From 95fc2c6744803d2fbea3944f150abbcc23e61b5e Mon Sep 17 00:00:00 2001 From: Jonathan Johnson Date: Sat, 21 Sep 2024 13:40:40 -0700 Subject: [PATCH] Added darkmode detection on Linux --- CHANGELOG.md | 5 +++++ Cargo.lock | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 6 +++++- src/lib.rs | 19 ++++++++++++++++++ src/private.rs | 2 ++ src/xdg.rs | 16 ++++++++++++++++ 6 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 src/xdg.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index f0c8806..2369295 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 underlying window is resized immediately. Notably, this happens on Wayland but may happen on some other platforms as well. +### Added + +- A new feature `xdg` has been added, enabled by default, that enables detecting + dark mode changes on Linux. + ## v0.4.0 (2024-09-14) ### Breaking Changes diff --git a/Cargo.lock b/Cargo.lock index 1cbbad5..618c2c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,6 +62,7 @@ checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" name = "appit" version = "0.4.0" dependencies = [ + "darkmode", "winit", ] @@ -260,6 +261,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" +[[package]] +name = "darkmode" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "075a9464059e42ad7f7c487897c1ceb65327daf056c2acf58b27ca62a51db2ab" +dependencies = [ + "dbus", +] + +[[package]] +name = "dbus" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b" +dependencies = [ + "libc", + "libdbus-sys", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -419,6 +440,15 @@ version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +[[package]] +name = "libdbus-sys" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72" +dependencies = [ + "pkg-config", +] + [[package]] name = "libloading" version = "0.8.5" @@ -1303,6 +1333,22 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -1312,6 +1358,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.45.0" diff --git a/Cargo.toml b/Cargo.toml index 7745e8d..dd53d23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,14 +11,18 @@ categories = ["gui"] readme = "./README.md" [features] -default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita"] +default = ["x11", "wayland", "wayland-dlopen", "wayland-csd-adwaita", "xdg"] wayland-csd-adwaita = ["winit/wayland-csd-adwaita"] x11 = ["winit/x11"] wayland = ["winit/wayland"] wayland-dlopen = ["winit/wayland-dlopen"] rwh_06 = ["winit/rwh_06"] rwh_05 = ["winit/rwh_05"] +xdg = ["dep:darkmode"] [dependencies] winit = { version = "0.30.5", default-features = false } + +[target.'cfg(target_os = "linux")'.dependencies] +darkmode = { version = "0.1.0", optional = true } diff --git a/src/lib.rs b/src/lib.rs index 1f8b082..8904f3b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,9 @@ mod private; mod window; +#[cfg(all(target_os = "linux", feature = "xdg"))] +mod xdg; + use std::collections::HashMap; use std::ops::Deref; use std::process::exit; @@ -253,6 +256,8 @@ where let StartCause::Init = cause else { return; }; + #[cfg(all(target_os = "linux", feature = "xdg"))] + self.observe_darkmode_changes(event_loop.proxy()); self.running.started.store(true, Ordering::Relaxed); for PendingWindow { window, @@ -333,6 +338,10 @@ where exit(0) } } + #[cfg(all(target_os = "linux", feature = "xdg"))] + EventLoopMessage::ThemeChanged(theme) => { + self.running.windows.theme_changed(theme); + } } } } @@ -706,6 +715,16 @@ impl Windows { data.guards -= 1; data.should_shutdown() } + + #[cfg(all(target_os = "linux", feature = "xdg"))] + fn theme_changed(&self, theme: winit::window::Theme) { + let data = self.data.lock().unwrap_or_else(PoisonError::into_inner); + for window in data.open.values() { + let _ = window + .sender + .send(WindowMessage::Event(WindowEvent::ThemeChanged(theme))); + } + } } struct OpenWindow { diff --git a/src/private.rs b/src/private.rs index 8c34f06..68cd161 100644 --- a/src/private.rs +++ b/src/private.rs @@ -62,6 +62,8 @@ where }, PreventShutdown, AllowShutdown, + #[cfg(all(target_os = "linux", feature = "xdg"))] + ThemeChanged(Theme), } #[derive(Debug)] diff --git a/src/xdg.rs b/src/xdg.rs new file mode 100644 index 0000000..86c6835 --- /dev/null +++ b/src/xdg.rs @@ -0,0 +1,16 @@ +use winit::{event_loop::EventLoopProxy, window::Theme}; + +use crate::{private::EventLoopMessage, Message}; + +fn observe_darkmode_changes(proxy: EventLoopProxy>) +where + AppMessage: Message, +{ + let _ignored_error = darkmode::subscribe(move |mode| { + let _ = proxy.send_event(EventLoopMessage::ThemeChanged(match mode { + darkmode::Mode::Dark => Theme::Dark, + darkmode::Mode::Light => Theme::Light, + darkmode::Mode::Default => return, + })); + }); +}