diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index f6cb909a40db..27d978239c52 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -222,6 +222,9 @@ impl GlowWinitApp { for viewport in glutin.viewports.values_mut() { if let Some(egui_winit) = viewport.egui_winit.as_mut() { egui_winit.set_max_texture_side(max_texture_side); + if let Some(window) = viewport.window.as_deref() { + egui_winit.init_system_theme(window); + } } } diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index 285320d5d4a7..685b444322a0 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -254,6 +254,8 @@ impl WgpuWinitApp { let event_loop_proxy = self.repaint_proxy.lock().clone(); integration.init_accesskit(&mut egui_winit, &window, event_loop_proxy); } + egui_winit.init_system_theme(&window); + let theme = system_theme.unwrap_or(self.native_options.default_theme); egui_ctx.set_visuals(Visuals::theme(theme)); diff --git a/crates/eframe/src/web/app_runner.rs b/crates/eframe/src/web/app_runner.rs index b253abc271a1..6a9722d60f50 100644 --- a/crates/eframe/src/web/app_runner.rs +++ b/crates/eframe/src/web/app_runner.rs @@ -132,6 +132,7 @@ impl AppRunner { .entry(egui::ViewportId::ROOT) .or_default() .native_pixels_per_point = Some(super::native_pixels_per_point()); + runner.input.raw.system_theme = super::system_theme(); Ok(runner) } diff --git a/crates/eframe/src/web/events.rs b/crates/eframe/src/web/events.rs index 48c2249b22e5..7395482c521d 100644 --- a/crates/eframe/src/web/events.rs +++ b/crates/eframe/src/web/events.rs @@ -370,6 +370,7 @@ pub(crate) fn install_color_scheme_change_event(runner_ref: &WebRunner) -> Resul let theme = theme_from_dark_mode(event.matches()); runner.frame.info.system_theme = Some(theme); runner.egui_ctx().set_visuals(Visuals::theme(theme)); + runner.input.raw.system_theme = Some(theme); runner.needs_repaint.repaint_asap(); }, )?; diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 4854cd2fd68c..2c36b7463bc1 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -14,7 +14,7 @@ pub use accesskit_winit; pub use egui; #[cfg(feature = "accesskit")] use egui::accesskit; -use egui::{Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo}; +use egui::{Pos2, Rect, Theme, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo}; pub use winit; pub mod clipboard; @@ -172,6 +172,10 @@ impl State { )); } + pub fn init_system_theme(&mut self, window: &Window) { + self.egui_input.system_theme = window.theme().map(to_egui_theme); + } + /// Call this once a graphics context has been created to update the maximum texture dimensions /// that egui will use. pub fn set_max_texture_side(&mut self, max_texture_side: usize) { @@ -405,6 +409,13 @@ impl State { consumed: false, } } + WindowEvent::ThemeChanged(winit_theme) => { + self.egui_input.system_theme = Some(to_egui_theme(*winit_theme)); + EventResponse { + repaint: true, + consumed: false, + } + } WindowEvent::HoveredFile(path) => { self.egui_input.hovered_files.push(egui::HoveredFile { path: Some(path.clone()), @@ -464,7 +475,6 @@ impl State { | WindowEvent::Occluded(_) | WindowEvent::Resized(_) | WindowEvent::Moved(_) - | WindowEvent::ThemeChanged(_) | WindowEvent::TouchpadPressure { .. } | WindowEvent::CloseRequested => EventResponse { repaint: true, @@ -891,6 +901,13 @@ impl State { } } +fn to_egui_theme(theme: winit::window::Theme) -> Theme { + match theme { + winit::window::Theme::Dark => Theme::Dark, + winit::window::Theme::Light => Theme::Light, + } +} + pub fn inner_rect_in_points(window: &Window, pixels_per_point: f32) -> Option { let inner_pos_px = window.inner_position().ok()?; let inner_pos_px = egui::pos2(inner_pos_px.x as f32, inner_pos_px.y as f32);