1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-30 13:20:05 -04:00

Follow the System Theme in egui (#4860)

* Some initial progress towards #4490

This PR just moves `Theme` and the "follow system theme" settings to
egui and adds `RawInput.system_theme`.
A follow-up PR can then introduce the two separate `dark_mode_style` and
`light_mode_style` fields on `Options`.


<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md)
before opening a Pull Request!

* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->


* [x] I have followed the instructions in the PR template


### Breaking changes

The options `follow_system_theme` and `default_theme` has been moved
from `eframe` into `egui::Options`, settable with `ctx.options_mut`

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
Tau Gärtli
2024-08-06 20:17:51 +02:00
committed by GitHub
parent ed0254288a
commit 2dac4a4fc6
16 changed files with 129 additions and 137 deletions

View File

@@ -38,18 +38,11 @@ impl AppRunner {
) -> Result<Self, String> {
let painter = super::ActiveWebPainter::new(canvas, &web_options).await?;
let system_theme = if web_options.follow_system_theme {
super::system_theme()
} else {
None
};
let info = epi::IntegrationInfo {
web_info: epi::WebInfo {
user_agent: super::user_agent().unwrap_or_default(),
location: super::web_location(),
},
system_theme,
cpu_usage: None,
};
let storage = LocalStorage::default();
@@ -68,9 +61,6 @@ impl AppRunner {
o.zoom_factor = 1.0;
});
let theme = system_theme.unwrap_or(web_options.default_theme);
egui_ctx.set_visuals(theme.egui_visuals());
let cc = epi::CreationContext {
egui_ctx: egui_ctx.clone(),
integration_info: info.clone(),
@@ -132,6 +122,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)
}

View File

@@ -94,6 +94,7 @@ pub(crate) fn install_event_handlers(runner_ref: &WebRunner) -> Result<(), JsVal
install_wheel(runner_ref, &canvas)?;
install_drag_and_drop(runner_ref, &canvas)?;
install_window_events(runner_ref, &window)?;
install_color_scheme_change_event(runner_ref, &window)?;
Ok(())
}
@@ -353,17 +354,17 @@ fn install_window_events(runner_ref: &WebRunner, window: &EventTarget) -> Result
Ok(())
}
pub(crate) fn install_color_scheme_change_event(runner_ref: &WebRunner) -> Result<(), JsValue> {
let window = web_sys::window().unwrap();
if let Some(media_query_list) = prefers_color_scheme_dark(&window)? {
fn install_color_scheme_change_event(
runner_ref: &WebRunner,
window: &web_sys::Window,
) -> Result<(), JsValue> {
if let Some(media_query_list) = prefers_color_scheme_dark(window)? {
runner_ref.add_event_listener::<web_sys::MediaQueryListEvent>(
&media_query_list,
"change",
|event, runner| {
let theme = theme_from_dark_mode(event.matches());
runner.frame.info.system_theme = Some(theme);
runner.egui_ctx().set_visuals(theme.egui_visuals());
runner.input.raw.system_theme = Some(theme);
runner.needs_repaint.repaint_asap();
},
)?;

View File

@@ -45,8 +45,6 @@ use web_sys::MediaQueryList;
use input::*;
use crate::Theme;
// ----------------------------------------------------------------------------
pub(crate) fn string_from_js_value(value: &JsValue) -> String {
@@ -103,7 +101,7 @@ pub fn native_pixels_per_point() -> f32 {
/// Ask the browser about the preferred system theme.
///
/// `None` means unknown.
pub fn system_theme() -> Option<Theme> {
pub fn system_theme() -> Option<egui::Theme> {
let dark_mode = prefers_color_scheme_dark(&web_sys::window()?)
.ok()??
.matches();
@@ -114,11 +112,11 @@ fn prefers_color_scheme_dark(window: &web_sys::Window) -> Result<Option<MediaQue
window.match_media("(prefers-color-scheme: dark)")
}
fn theme_from_dark_mode(dark_mode: bool) -> Theme {
fn theme_from_dark_mode(dark_mode: bool) -> egui::Theme {
if dark_mode {
Theme::Dark
egui::Theme::Dark
} else {
Theme::Light
egui::Theme::Light
}
}

View File

@@ -63,8 +63,6 @@ impl WebRunner {
) -> Result<(), JsValue> {
self.destroy();
let follow_system_theme = web_options.follow_system_theme;
let text_agent = TextAgent::attach(self)?;
let runner = AppRunner::new(canvas, web_options, app_creator, text_agent).await?;
@@ -83,10 +81,6 @@ impl WebRunner {
{
events::install_event_handlers(self)?;
if follow_system_theme {
events::install_color_scheme_change_event(self)?;
}
// The resize observer handles calling `request_animation_frame` to start the render loop.
events::install_resize_observer(self)?;
}