From 496a966c64e35786db301fcb3055e187e5b192a9 Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Sat, 20 Jul 2024 01:32:28 +0200 Subject: [PATCH] desktop: Add D-Bus support This patch adds D-Bus support, implements the interface `org.freedesktop.portal.Settings`, and provides `FreedesktopSettings`, which facilitates access to freedesktop settings and its color-scheme. --- Cargo.lock | 54 +++++++++++++++++++---------- desktop/Cargo.toml | 4 +++ desktop/src/dbus.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++ desktop/src/main.rs | 1 + 4 files changed, 124 insertions(+), 17 deletions(-) create mode 100644 desktop/src/dbus.rs diff --git a/Cargo.lock b/Cargo.lock index facc1696b..d3ca5d08f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -759,6 +759,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chardetng" version = "0.1.17" @@ -2165,7 +2171,7 @@ dependencies = [ "libc", "libudev-sys", "log", - "nix", + "nix 0.28.0", "uuid", "vec_map", "wasm-bindgen", @@ -3305,7 +3311,19 @@ checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" dependencies = [ "bitflags 2.6.0", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.1.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases 0.2.1", "libc", "memoffset", ] @@ -4370,6 +4388,7 @@ dependencies = [ "ruffle_video_external", "ruffle_video_software", "sys-locale", + "thiserror", "tokio", "toml_edit 0.22.16", "tracing", @@ -4383,6 +4402,7 @@ dependencies = [ "wgpu", "winapi", "winit", + "zbus", ] [[package]] @@ -6245,7 +6265,7 @@ checksum = "90e37c7b9921b75dfd26dd973fdcbce36f13dfa6e2dc82aece584e0ed48c355c" dependencies = [ "arrayvec", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.1.1", "document-features", "js-sys", "log", @@ -6273,7 +6293,7 @@ dependencies = [ "arrayvec", "bit-vec", "bitflags 2.6.0", - "cfg_aliases", + "cfg_aliases 0.1.1", "codespan-reporting", "document-features", "indexmap", @@ -6305,7 +6325,7 @@ dependencies = [ "bit-set", "bitflags 2.6.0", "block", - "cfg_aliases", + "cfg_aliases 0.1.1", "core-graphics-types", "d3d12", "glow", @@ -6674,7 +6694,7 @@ dependencies = [ "bitflags 2.6.0", "bytemuck", "calloop", - "cfg_aliases", + "cfg_aliases 0.1.1", "core-foundation", "core-graphics", "cursor-icon", @@ -6828,9 +6848,9 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zbus" -version = "4.2.2" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c3977a7aafa97b12b9a35d21cdcff9b0d2289762b14683f45d66b1ba6c48f" +checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725" dependencies = [ "async-broadcast", "async-executor", @@ -6848,7 +6868,7 @@ dependencies = [ "futures-sink", "futures-util", "hex", - "nix", + "nix 0.29.0", "ordered-stream", "rand", "serde", @@ -6866,9 +6886,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "4.2.2" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe9de53245dcf426b7be226a4217dd5e339080e5d46e64a02d6e5dcbf90fca1" +checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6947,9 +6967,9 @@ dependencies = [ [[package]] name = "zvariant" -version = "4.1.1" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa6d31a02fbfb602bfde791de7fedeb9c2c18115b3d00f3a36e489f46ffbbc7" +checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe" dependencies = [ "endi", "enumflags2", @@ -6961,9 +6981,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "4.1.1" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642bf1b6b6d527988b3e8193d20969d53700a36eac734d21ae6639db168701c8" +checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -6974,9 +6994,9 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc242db087efc22bd9ade7aa7809e4ba828132edc312871584a6b4391bdf8786" +checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 29b3b70b0..8e7d01eca 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -49,6 +49,10 @@ tokio = { workspace = true, features = ["rt-multi-thread", "macros"]} # Deliberately held back to match tracy client used by profiling crate tracing-tracy = { version = "=0.10.4", optional = true } rand = "0.8.5" +thiserror.workspace = true + +[target.'cfg(target_os = "linux")'.dependencies] +zbus = "4.4.0" [target.'cfg(windows)'.dependencies] winapi = "0.3.9" diff --git a/desktop/src/dbus.rs b/desktop/src/dbus.rs new file mode 100644 index 000000000..7280d3be3 --- /dev/null +++ b/desktop/src/dbus.rs @@ -0,0 +1,82 @@ +#![cfg(target_os = "linux")] +//! Types and methods utilized for communicating with D-Bus + +use futures::StreamExt; +use zbus::export::futures_core::Stream; +use zbus::zvariant::{OwnedValue, Value}; +use zbus::{proxy, Connection}; + +type Result = std::result::Result>; + +#[proxy( + interface = "org.freedesktop.portal.Settings", + default_service = "org.freedesktop.portal.Desktop", + default_path = "/org/freedesktop/portal/desktop", + gen_blocking = false +)] +trait FreedesktopSettingsInterface { + fn read(&self, namespace: &str, key: &str) -> Result; + + #[zbus(signal)] + fn setting_changed(&self, namespace: &str, key: &str, value: Value<'_>); +} + +pub enum ColorScheme { + Default, + PreferLight, + PreferDark, +} + +#[derive(thiserror::Error, Debug)] +pub enum FreedesktopSettingsError { + #[error("Unexpected value for color scheme: {0}")] + UnexpectedColorScheme(Value<'static>), +} + +pub struct FreedesktopSettings<'p> { + proxy: FreedesktopSettingsInterfaceProxy<'p>, +} + +impl<'p> FreedesktopSettings<'p> { + const COLOR_SCHEME: (&'static str, &'static str) = + ("org.freedesktop.appearance", "color-scheme"); + + pub async fn new(connection: &Connection) -> Result { + Ok(Self { + proxy: FreedesktopSettingsInterfaceProxy::new(connection).await?, + }) + } + + pub async fn color_scheme(&self) -> Result { + let (namespace, key) = Self::COLOR_SCHEME; + let value = self.proxy.read(namespace, key).await?; + Self::parse_color_scheme(value.into()) + } + + pub async fn watch_color_scheme(&self) -> Result>> { + let stream: SettingChangedStream = self.proxy.receive_setting_changed().await?; + Ok(stream.filter_map(|value| async move { + let args = value.args().ok()?; + if (args.namespace, args.key) == Self::COLOR_SCHEME { + Some(Self::parse_color_scheme(args.value)) + } else { + None + } + })) + } + + fn parse_color_scheme(mut value: Value<'_>) -> Result { + while let Value::Value(inner_value) = value { + value = *inner_value; + } + + match value { + Value::U32(0) => Ok(ColorScheme::Default), + Value::U32(1) => Ok(ColorScheme::PreferDark), + Value::U32(2) => Ok(ColorScheme::PreferLight), + value => Err(FreedesktopSettingsError::UnexpectedColorScheme( + value.try_to_owned()?.into(), + ))?, + } + } +} diff --git a/desktop/src/main.rs b/desktop/src/main.rs index 448600857..9939a755b 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -10,6 +10,7 @@ mod app; mod backends; mod cli; mod custom_event; +mod dbus; mod gui; mod log; mod player;