Skip to content
Draft
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
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ jobs:
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
python3-pip ninja-build libnfc-dev libpcsclite-dev \
libwayland-dev libx11-dev
- 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
Loading