From 74425d5cb1ddc12637c4f11adbdc258d693b3dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Mon, 8 Sep 2025 10:12:04 +0200 Subject: [PATCH] Set window theme to match color scheme of active theme --- core/src/theme.rs | 13 ++++++++++++- winit/src/conversion.rs | 2 +- winit/src/lib.rs | 4 ++++ winit/src/window/state.rs | 27 +++++++++++++++++++++++---- 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/core/src/theme.rs b/core/src/theme.rs index 5f2fb127..1260bca8 100644 --- a/core/src/theme.rs +++ b/core/src/theme.rs @@ -258,7 +258,10 @@ pub trait Base { /// Returns the default theme for the preferred [`Mode`]. fn default(preference: Mode) -> Self; - /// Returns the default base [`Style`] of a theme. + /// Returns the [`Mode`] of the theme. + fn mode(&self) -> Mode; + + /// Returns the default base [`Style`] of the theme. fn base(&self) -> Style; /// Returns the color [`Palette`] of the theme. @@ -295,6 +298,14 @@ impl Base for Theme { } } + fn mode(&self) -> Mode { + if self.extended_palette().is_dark { + Mode::Dark + } else { + Mode::Light + } + } + fn base(&self) -> Style { default(self) } diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs index feef78bd..654cfb54 100644 --- a/winit/src/conversion.rs +++ b/winit/src/conversion.rs @@ -1207,7 +1207,7 @@ pub fn icon(icon: window::Icon) -> Option { winit::window::Icon::from_rgba(pixels, size.width, size.height).ok() } -/// Convertions some [`input_method::Purpose`] into its `winit` counterpart. +/// Converts some [`input_method::Purpose`] into its `winit` counterpart. pub fn ime_purpose( purpose: input_method::Purpose, ) -> winit::window::ImePurpose { diff --git a/winit/src/lib.rs b/winit/src/lib.rs index a2d58820..970366c7 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -634,6 +634,10 @@ async fn run_instance

( system_theme, ); + window.raw.set_theme(conversion::window_theme( + window.state.theme_mode(), + )); + debug::theme_changed(|| { if is_first { theme::Base::palette(window.state.theme()) diff --git a/winit/src/window/state.rs b/winit/src/window/state.rs index b3f9af3c..683b5352 100644 --- a/winit/src/window/state.rs +++ b/winit/src/window/state.rs @@ -9,7 +9,7 @@ use winit::window::Window; use std::fmt::{Debug, Formatter}; -/// The state of a multi-windowed [`Program`]. +/// The state of the window of a [`Program`]. pub struct State where P::Theme: theme::Base, @@ -21,6 +21,7 @@ where cursor_position: Option>, modifiers: winit::keyboard::ModifiersState, theme: Option, + theme_mode: theme::Mode, default_theme: P::Theme, style: theme::Style, } @@ -52,7 +53,7 @@ where window: &Window, system_theme: theme::Mode, ) -> Self { - let theme_mode = window + let system_theme = window .theme() .map(conversion::theme_mode) .unwrap_or(system_theme); @@ -60,7 +61,9 @@ where let title = program.title(window_id); let scale_factor = program.scale_factor(window_id); let theme = program.theme(window_id); - let default_theme = ::default(theme_mode); + let theme_mode = + theme.as_ref().map(theme::Base::mode).unwrap_or_default(); + let default_theme = ::default(system_theme); let style = program.style(theme.as_ref().unwrap_or(&default_theme)); let viewport = { @@ -80,6 +83,7 @@ where cursor_position: None, modifiers: winit::keyboard::ModifiersState::default(), theme, + theme_mode, default_theme, style, } @@ -135,6 +139,11 @@ where self.theme.as_ref().unwrap_or(&self.default_theme) } + /// Returns the current [`theme::Mode`] of the [`State`]. + pub fn theme_mode(&self) -> theme::Mode { + self.theme_mode + } + /// Returns the current background [`Color`] of the [`State`]. pub fn background_color(&self) -> Color { self.style.background_color @@ -192,9 +201,9 @@ where self.default_theme = ::default( conversion::theme_mode(*theme), ); - self.style = program.style(self.theme()); if self.theme.is_none() { + self.style = program.style(&self.default_theme); window.request_redraw(); } } @@ -242,5 +251,15 @@ where // Update theme and appearance self.theme = program.theme(window_id); self.style = program.style(self.theme()); + + if let Some(theme) = &self.theme { + let new_mode = theme::Base::mode(theme); + + if self.theme_mode != new_mode { + window.set_theme(conversion::window_theme(new_mode)); + + self.theme_mode = new_mode; + } + } } }