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.
This commit is contained in:
Kamil Jarosz 2024-07-20 01:32:28 +02:00
parent 52192fa9ca
commit 496a966c64
4 changed files with 124 additions and 17 deletions

54
Cargo.lock generated
View File

@ -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",

View File

@ -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"

82
desktop/src/dbus.rs Normal file
View File

@ -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<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[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<OwnedValue>;
#[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<Self> {
Ok(Self {
proxy: FreedesktopSettingsInterfaceProxy::new(connection).await?,
})
}
pub async fn color_scheme(&self) -> Result<ColorScheme> {
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<impl Stream<Item = Result<ColorScheme>>> {
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<ColorScheme> {
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(),
))?,
}
}
}

View File

@ -10,6 +10,7 @@ mod app;
mod backends;
mod cli;
mod custom_event;
mod dbus;
mod gui;
mod log;
mod player;