Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ jobs:
run: |
sudo apt install -y --no-install-recommends \
curl git build-essential \
libgtk-4-dev gettext libdbus-1-dev libssl-dev libudev-dev \
libxml2-utils blueprint-compiler desktop-file-utils \
python3-pip ninja-build libnfc-dev libpcsclite-dev
libgtk-4-dev libclang-dev libdbus-1-dev libssl-dev libudev-dev libnfc-dev \
libpcsclite-dev libxml2-utils \
blueprint-compiler desktop-file-utils gettext ninja-build python3-pip \
udev zip
- name: Install Meson
run: |
# Newer version needed for --interactive flag needed below
Expand Down
94 changes: 91 additions & 3 deletions credentialsd-common/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//! Types for serializing across D-Bus instances

use std::fmt::Display;

use serde::{
Deserialize, Serialize,
de::{DeserializeSeed, Error},
de::{DeserializeSeed, Error, Visitor},
};
use zvariant::{
self, Array, DeserializeDict, DynamicDeserialize, LE, Optional, OwnedValue, SerializeDict,
Signature, Structure, StructureBuilder, Type, Value, signature::Fields,
self, Array, DeserializeDict, DynamicDeserialize, LE, NoneValue, Optional, OwnedValue,
SerializeDict, Signature, Structure, StructureBuilder, Type, Value, signature::Fields,
};

use crate::model::{BackgroundEvent, Operation, RequestingApplication};
Expand Down Expand Up @@ -619,6 +621,92 @@ pub struct ViewRequest {
pub id: RequestId,
pub rp_id: String,
pub requesting_app: RequestingApplication,

/// Client window handle.
pub window_handle: Optional<WindowHandle>,
}

#[derive(Type, PartialEq, Debug)]
#[zvariant(signature = "s")]
pub enum WindowHandle {
Wayland(String),
X11(String),
}

impl NoneValue for WindowHandle {
type NoneType = String;

fn null_value() -> Self::NoneType {
String::new()
}
}

impl Serialize for WindowHandle {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

impl<'de> Deserialize<'de> for WindowHandle {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_str(WindowHandleVisitor {})
}
}

struct WindowHandleVisitor;

impl<'de> Visitor<'de> for WindowHandleVisitor {
type Value = WindowHandle;

fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"a window handle formatted as `<window system>:<handle value>`"
)
}

fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
v.try_into().map_err(E::custom)
}
}

impl TryFrom<String> for WindowHandle {
type Error = String;

fn try_from(value: String) -> Result<Self, Self::Error> {
WindowHandle::try_from(value.as_ref())
}
}

impl TryFrom<&str> for WindowHandle {
type Error = String;

fn try_from(value: &str) -> Result<Self, Self::Error> {
match value.split_once(':') {
Some(("x11", handle)) => Ok(Self::X11(handle.to_string())),
Some(("wayland", xid)) => Ok(Self::Wayland(xid.to_string())),
Some((window_system, _)) => Err(format!("Unknown windowing system: {window_system}")),
None => Err("Invalid window handle string format".to_string()),
}
}
}

impl Display for WindowHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Wayland(handle) => write!(f, "wayland:{handle}"),
Self::X11(xid) => write!(f, "x11:{xid}"),
}
}
}

fn value_to_owned(value: &Value<'_>) -> OwnedValue {
Expand Down
Loading