From 52553ca482d52b97cb3ae884c38df4c06a1e6a69 Mon Sep 17 00:00:00 2001 From: Nick Ludwig <79381743+nick1udwig@users.noreply.github.com> Date: Tue, 17 Feb 2026 11:25:25 -0800 Subject: [PATCH] fix(appearance): switch light and dark despite suspend/time change --- .../src/pages/desktop/appearance/mod.rs | 29 ++++++++++++++++++- .../pages/desktop/appearance/theme_manager.rs | 7 +++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/cosmic-settings/src/pages/desktop/appearance/mod.rs b/cosmic-settings/src/pages/desktop/appearance/mod.rs index 1e8cf07..cac3087 100644 --- a/cosmic-settings/src/pages/desktop/appearance/mod.rs +++ b/cosmic-settings/src/pages/desktop/appearance/mod.rs @@ -16,9 +16,10 @@ use cosmic::app::ContextDrawer; use cosmic::config::CosmicTk; use cosmic::cosmic_config::{Config, ConfigSet, CosmicConfigEntry}; use cosmic::cosmic_theme::palette::{FromColor, Hsv, Srgb}; -use cosmic::cosmic_theme::{CornerRadii, Density, ThemeBuilder}; +use cosmic::cosmic_theme::{CornerRadii, Density, ThemeBuilder, ThemeMode}; #[cfg(feature = "xdg-portal")] use cosmic::dialog::file_chooser::{self, FileFilter}; +use cosmic::iced::Subscription; use cosmic::iced_core::{Alignment, Length}; use cosmic::widget::{ button, color_picker::ColorPickerUpdate, container, horizontal_space, radio, row, settings, @@ -124,6 +125,7 @@ pub enum Message { Autoswitch(bool), DarkMode(bool), Density(Density), + ThemeModeUpdate(ThemeMode), DrawerOpen(ContextView), DrawerColor(ColorPickerUpdate), @@ -534,6 +536,20 @@ impl Page { Message::Daytime(day_time) => { self.day_time = day_time; return Task::none(); + }, + + Message::ThemeModeUpdate(mode) => { + let was_dark = self.theme_manager.mode().is_dark; + let was_auto = self.theme_manager.mode().auto_switch; + + self.theme_manager.sync_mode(mode); + + // If auto-switch flipped while the page is open, keep the UI in sync. + if was_dark != self.theme_manager.mode().is_dark + || was_auto != self.theme_manager.mode().auto_switch + { + self.drawer.reset(&self.theme_manager); + } } } @@ -737,6 +753,17 @@ impl page::Page for Page { cosmic::task::batch(tasks) } + fn subscription(&self, core: &cosmic::Core) -> Subscription { + // Keep the Appearance page in sync when the daemon auto-switches light/dark. + core.watch_config::("com.system76.CosmicTheme.Mode") + .map(|update| { + for why in update.errors { + tracing::error!(?why, "theme mode config load error"); + } + crate::pages::Message::Appearance(Message::ThemeModeUpdate(update.config)) + }) + } + fn context_drawer(&self) -> Option> { self.drawer.context_drawer(self.context_view) } diff --git a/cosmic-settings/src/pages/desktop/appearance/theme_manager.rs b/cosmic-settings/src/pages/desktop/appearance/theme_manager.rs index 88f01e7..02ae5cd 100644 --- a/cosmic-settings/src/pages/desktop/appearance/theme_manager.rs +++ b/cosmic-settings/src/pages/desktop/appearance/theme_manager.rs @@ -260,6 +260,13 @@ impl Manager { &self.mode.0 } + /// Update the locally cached `ThemeMode` from an external source (daemon / config watcher). + /// + /// This must not write back to config, since the daemon is the source of truth. + pub fn sync_mode(&mut self, mode: ThemeMode) { + self.mode.0 = mode; + } + #[inline] pub fn builder(&self) -> &ThemeBuilder { &self.selected_customizer().builder.0