Respect and detect `prefers-color-scheme: no-preference` (#7293)
I don't think this will make a difference in practice, but technically there are three preference states: * `dark` * `light` * `no-preference` Previously we would only check for `dark`, and if not set would assume `light`. Not we also check `light` and if we're neither `dark` or `light` we assume nothing.
This commit is contained in:
parent
1878874f7d
commit
40c69cd1ba
|
|
@ -3,8 +3,8 @@ use crate::web::string_from_js_value;
|
||||||
use super::{
|
use super::{
|
||||||
AppRunner, Closure, DEBUG_RESIZE, JsCast as _, JsValue, WebRunner, button_from_mouse_event,
|
AppRunner, Closure, DEBUG_RESIZE, JsCast as _, JsValue, WebRunner, button_from_mouse_event,
|
||||||
location_hash, modifiers_from_kb_event, modifiers_from_mouse_event, modifiers_from_wheel_event,
|
location_hash, modifiers_from_kb_event, modifiers_from_mouse_event, modifiers_from_wheel_event,
|
||||||
native_pixels_per_point, pos_from_mouse_event, prefers_color_scheme_dark, primary_touch_pos,
|
native_pixels_per_point, pos_from_mouse_event, prefers_color_scheme, primary_touch_pos,
|
||||||
push_touches, text_from_keyboard_event, theme_from_dark_mode, translate_key,
|
push_touches, text_from_keyboard_event, translate_key,
|
||||||
};
|
};
|
||||||
|
|
||||||
use web_sys::{Document, EventTarget, ShadowRoot};
|
use web_sys::{Document, EventTarget, ShadowRoot};
|
||||||
|
|
@ -469,16 +469,19 @@ fn install_color_scheme_change_event(
|
||||||
runner_ref: &WebRunner,
|
runner_ref: &WebRunner,
|
||||||
window: &web_sys::Window,
|
window: &web_sys::Window,
|
||||||
) -> Result<(), JsValue> {
|
) -> Result<(), JsValue> {
|
||||||
if let Some(media_query_list) = prefers_color_scheme_dark(window)? {
|
for theme in [egui::Theme::Dark, egui::Theme::Light] {
|
||||||
runner_ref.add_event_listener::<web_sys::MediaQueryListEvent>(
|
if let Some(media_query_list) = prefers_color_scheme(window, theme)? {
|
||||||
&media_query_list,
|
runner_ref.add_event_listener::<web_sys::MediaQueryListEvent>(
|
||||||
"change",
|
&media_query_list,
|
||||||
|event, runner| {
|
"change",
|
||||||
let theme = theme_from_dark_mode(event.matches());
|
|_event, runner| {
|
||||||
runner.input.raw.system_theme = Some(theme);
|
if let Some(theme) = super::system_theme() {
|
||||||
runner.needs_repaint.repaint_asap();
|
runner.input.raw.system_theme = Some(theme);
|
||||||
},
|
runner.needs_repaint.repaint_asap();
|
||||||
)?;
|
}
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ pub(crate) type ActiveWebPainter = web_painter_wgpu::WebPainterWgpu;
|
||||||
|
|
||||||
pub use backend::*;
|
pub use backend::*;
|
||||||
|
|
||||||
|
use egui::Theme;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use web_sys::{Document, MediaQueryList, Node};
|
use web_sys::{Document, MediaQueryList, Node};
|
||||||
|
|
||||||
|
|
@ -113,24 +114,31 @@ pub fn native_pixels_per_point() -> f32 {
|
||||||
///
|
///
|
||||||
/// `None` means unknown.
|
/// `None` means unknown.
|
||||||
pub fn system_theme() -> Option<egui::Theme> {
|
pub fn system_theme() -> Option<egui::Theme> {
|
||||||
let dark_mode = prefers_color_scheme_dark(&web_sys::window()?)
|
let window = web_sys::window()?;
|
||||||
.ok()??
|
if does_prefer_color_scheme(&window, Theme::Dark) == Some(true) {
|
||||||
.matches();
|
Some(Theme::Dark)
|
||||||
Some(theme_from_dark_mode(dark_mode))
|
} else if does_prefer_color_scheme(&window, Theme::Light) == Some(true) {
|
||||||
}
|
Some(Theme::Light)
|
||||||
|
|
||||||
fn prefers_color_scheme_dark(window: &web_sys::Window) -> Result<Option<MediaQueryList>, JsValue> {
|
|
||||||
window.match_media("(prefers-color-scheme: dark)")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn theme_from_dark_mode(dark_mode: bool) -> egui::Theme {
|
|
||||||
if dark_mode {
|
|
||||||
egui::Theme::Dark
|
|
||||||
} else {
|
} else {
|
||||||
egui::Theme::Light
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn does_prefer_color_scheme(window: &web_sys::Window, theme: Theme) -> Option<bool> {
|
||||||
|
Some(prefers_color_scheme(window, theme).ok()??.matches())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prefers_color_scheme(
|
||||||
|
window: &web_sys::Window,
|
||||||
|
theme: Theme,
|
||||||
|
) -> Result<Option<MediaQueryList>, JsValue> {
|
||||||
|
let theme = match theme {
|
||||||
|
Theme::Dark => "dark",
|
||||||
|
Theme::Light => "light",
|
||||||
|
};
|
||||||
|
window.match_media(format!("(prefers-color-scheme: {theme})").as_str())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the canvas in client coordinates.
|
/// Returns the canvas in client coordinates.
|
||||||
fn canvas_content_rect(canvas: &web_sys::HtmlCanvasElement) -> egui::Rect {
|
fn canvas_content_rect(canvas: &web_sys::HtmlCanvasElement) -> egui::Rect {
|
||||||
let bounding_rect = canvas.get_bounding_client_rect();
|
let bounding_rect = canvas.get_bounding_client_rect();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue