From d51084a5c9348d49ee2c579d85dd504af2495795 Mon Sep 17 00:00:00 2001 From: ShootingStarDragons Date: Wed, 13 Sep 2023 14:50:48 +0800 Subject: [PATCH] feat: support settings interface --- Cargo.lock | 88 +++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 + src/main.rs | 3 ++ src/settings.rs | 74 +++++++++++++++++++++++++++++++++++ src/settings/config.rs | 67 ++++++++++++++++++++++++++++++++ 5 files changed, 229 insertions(+), 5 deletions(-) create mode 100644 src/settings.rs create mode 100644 src/settings/config.rs diff --git a/Cargo.lock b/Cargo.lock index eb837a2..23cccbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -980,6 +980,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "csscolorparser" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2a7d3066da2de787b7f032c736763eb7ae5d355f81a68bab2675a96008b0bf" +dependencies = [ + "phf", +] + [[package]] name = "ctor" version = "0.2.4" @@ -2814,6 +2823,48 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pico-args" version = "0.5.0" @@ -2953,7 +3004,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] @@ -3466,7 +3517,7 @@ dependencies = [ "regex", "serde_json", "tar", - "toml", + "toml 0.7.8", "ureq", ] @@ -3518,7 +3569,7 @@ dependencies = [ "i-slint-compiler", "spin_on", "thiserror", - "toml_edit", + "toml_edit 0.19.15", ] [[package]] @@ -3746,7 +3797,7 @@ dependencies = [ "cfg-expr", "heck", "pkg-config", - "toml", + "toml 0.7.8", "version-compare", ] @@ -3954,7 +4005,19 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc1433177506450fe920e46a4f9812d0c211f5dd556da10e731a0a3dfa151f0" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.1", ] [[package]] @@ -3979,6 +4042,19 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca676d9ba1a322c1b64eb8045a5ec5c0cfb0c9d08e15e9ff622589ad5221c8fe" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tracing" version = "0.1.37" @@ -4980,6 +5056,7 @@ version = "0.3.4" dependencies = [ "anyhow", "bitflags 2.4.0", + "csscolorparser", "enumflags2", "image", "libspa-sys", @@ -4994,6 +5071,7 @@ dependencies = [ "tempfile", "thiserror", "tokio", + "toml 0.8.1", "tracing", "tracing-subscriber", "url", diff --git a/Cargo.toml b/Cargo.toml index 4b549b9..171a5ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,8 @@ wayland-protocols-misc = { version = "0.2.0", features = ["client"] } xkbcommon = "0.6.0" tempfile = "3.8.0" thiserror = "1.0.48" +toml = "0.8.0" +csscolorparser = "0.6.2" [build-dependencies] diff --git a/src/main.rs b/src/main.rs index d970a01..0045319 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,10 +4,12 @@ mod screencast; mod screenshot; mod session; mod slintbackend; +mod settings; use remotedesktop::RemoteDesktopBackend; use screencast::ScreenCastBackend; use screenshot::ScreenShotBackend; +use settings::SettingsBackend; use std::collections::HashMap; use std::future::pending; @@ -56,6 +58,7 @@ async fn main() -> anyhow::Result<()> { .serve_at("/org/freedesktop/portal/desktop", ScreenShotBackend)? .serve_at("/org/freedesktop/portal/desktop", ScreenCastBackend)? .serve_at("/org/freedesktop/portal/desktop", RemoteDesktopBackend)? + .serve_at("/org/freedesktop/portal/desktop", SettingsBackend::init())? .build() .await?; diff --git a/src/settings.rs b/src/settings.rs new file mode 100644 index 0000000..fd44518 --- /dev/null +++ b/src/settings.rs @@ -0,0 +1,74 @@ +mod config; +use zbus::{dbus_interface, fdo, SignalContext}; + +use zbus::zvariant::{Array, DeserializeDict, OwnedValue, SerializeDict, Signature, Type}; + +const DEFAULT_COLOR: u32 = 0; +const DARK_COLOR: u32 = 1; +const LIGHT_COLOR: u32 = 2; + +const APPEARANCE: &str = "org.freedesktop.appearance"; +const COLOR_SCHEME: &str = "color-scheme"; +const ACCENT_COLOR: &str = "accent-color"; + +#[derive(DeserializeDict, SerializeDict, Clone, Copy, PartialEq, Type)] +#[zvariant(signature = "dict")] +struct Color { + color: [f64; 3], +} + +impl Into for Color { + fn into(self) -> OwnedValue { + let arraysignature = Signature::try_from("d").unwrap(); + let mut array = Array::new(arraysignature); + for col in self.color { + array.append(col.into()).unwrap(); + } + OwnedValue::from(array) + } +} + +#[derive(Debug)] +pub struct SettingsBackend { + config: config::SettingsConfig, +} + +impl SettingsBackend { + pub fn init() -> Self { + Self { + config: config::SettingsConfig::config_from_file(), + } + } +} +#[dbus_interface(name = "org.freedesktop.impl.portal.Settings")] +impl SettingsBackend { + #[dbus_interface(property, name = "version")] + fn version(&self) -> u32 { + 1 + } + + fn read(&self, namespace: String, key: String) -> fdo::Result { + if namespace != APPEARANCE { + return Err(zbus::fdo::Error::Failed("No such namespace".to_string())); + } + if key == COLOR_SCHEME { + return Ok(OwnedValue::from(self.config.get_color_scheme())); + } + if key == ACCENT_COLOR { + return Ok(Color { + color: self.config.get_accent_color(), + } + .into()); + } + Err(zbus::fdo::Error::Failed("No such namespace".to_string())) + } + + #[dbus_interface(signal)] + async fn setting_changed( + ctxt: &SignalContext<'_>, + namespace: String, + key: String, + value: u32, + ) -> zbus::Result<()>; + // add code here +} diff --git a/src/settings/config.rs b/src/settings/config.rs new file mode 100644 index 0000000..24fdfb4 --- /dev/null +++ b/src/settings/config.rs @@ -0,0 +1,67 @@ +use serde::Deserialize; +use std::io::Read; +const DEFAULT_COLOR_NAME: &str = "default"; +const DARK_COLOR_NAME: &str = "dark"; +const LIGHT_COLOR_NAME: &str = "light"; + +const DEFAULT_ACCENT_COLLOR: &str = "#ffffff"; + +#[derive(Deserialize, PartialEq, Eq, Debug)] +pub struct SettingsConfig { + pub color_scheme: String, + pub accent_color: String, +} + +impl SettingsConfig { + pub fn get_color_scheme(&self) -> u32 { + match self.color_scheme.as_str() { + DEFAULT_COLOR_NAME => super::DEFAULT_COLOR, + DARK_COLOR_NAME => super::DARK_COLOR, + LIGHT_COLOR_NAME => super::LIGHT_COLOR, + _ => unreachable!(), + } + } + pub fn get_accent_color(&self) -> [f64; 3] { + let color = csscolorparser::parse(&self.accent_color) + .map(|color| color.to_rgba8()) + .unwrap_or( + csscolorparser::parse(DEFAULT_ACCENT_COLLOR) + .unwrap() + .to_rgba8(), + ); + [ + color[0] as f64 / 256.0, + color[1] as f64 / 256.0, + color[2] as f64 / 256.0, + ] + } +} + +impl Default for SettingsConfig { + fn default() -> Self { + SettingsConfig { + color_scheme: DEFAULT_COLOR_NAME.to_string(), + accent_color: DEFAULT_ACCENT_COLLOR.to_string(), + } + } +} + +impl SettingsConfig { + pub fn config_from_file() -> Self { + let Ok(home) = std::env::var("HOME") else { + return Self::default(); + }; + let config_path = std::path::Path::new(home.as_str()) + .join(".config") + .join("xdg-desktop-portal-luminous") + .join("config.toml"); + let Ok(mut file) = std::fs::OpenOptions::new().read(true).open(config_path) else { + return Self::default(); + }; + let mut buf = String::new(); + if file.read_to_string(&mut buf).is_err() { + return Self::default(); + }; + toml::from_str(&buf).unwrap_or(Self::default()) + } +}