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

Merge remote-tracking branch 'origin/main' into lucas/fix-macos-fullscreen

This commit is contained in:
lucasmerlin
2025-07-09 11:50:25 +02:00
133 changed files with 1836 additions and 732 deletions

View File

@@ -72,7 +72,7 @@ fn roaming_appdata() -> Option<PathBuf> {
};
let path = if result == S_OK {
// SAFETY: SHGetKnownFolderPath indicated success and is supposed to allocate a nullterminated string for us.
// SAFETY: SHGetKnownFolderPath indicated success and is supposed to allocate a null-terminated string for us.
let path_slice = unsafe { slice::from_raw_parts(path_raw, wcslen(path_raw)) };
Some(PathBuf::from(OsString::from_wide(path_slice)))
} else {

View File

@@ -3,8 +3,8 @@ use crate::web::string_from_js_value;
use super::{
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,
native_pixels_per_point, pos_from_mouse_event, prefers_color_scheme_dark, primary_touch_pos,
push_touches, text_from_keyboard_event, theme_from_dark_mode, translate_key,
native_pixels_per_point, pos_from_mouse_event, prefers_color_scheme, primary_touch_pos,
push_touches, text_from_keyboard_event, translate_key,
};
use web_sys::{Document, EventTarget, ShadowRoot};
@@ -469,16 +469,19 @@ 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.input.raw.system_theme = Some(theme);
runner.needs_repaint.repaint_asap();
},
)?;
for theme in [egui::Theme::Dark, egui::Theme::Light] {
if let Some(media_query_list) = prefers_color_scheme(window, theme)? {
runner_ref.add_event_listener::<web_sys::MediaQueryListEvent>(
&media_query_list,
"change",
|_event, runner| {
if let Some(theme) = super::system_theme() {
runner.input.raw.system_theme = Some(theme);
runner.needs_repaint.repaint_asap();
}
},
)?;
}
}
Ok(())

View File

@@ -40,6 +40,7 @@ pub(crate) type ActiveWebPainter = web_painter_wgpu::WebPainterWgpu;
pub use backend::*;
use egui::Theme;
use wasm_bindgen::prelude::*;
use web_sys::{Document, MediaQueryList, Node};
@@ -113,24 +114,31 @@ pub fn native_pixels_per_point() -> f32 {
///
/// `None` means unknown.
pub fn system_theme() -> Option<egui::Theme> {
let dark_mode = prefers_color_scheme_dark(&web_sys::window()?)
.ok()??
.matches();
Some(theme_from_dark_mode(dark_mode))
}
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
let window = web_sys::window()?;
if does_prefer_color_scheme(&window, Theme::Dark) == Some(true) {
Some(Theme::Dark)
} else if does_prefer_color_scheme(&window, Theme::Light) == Some(true) {
Some(Theme::Light)
} 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.
fn canvas_content_rect(canvas: &web_sys::HtmlCanvasElement) -> egui::Rect {
let bounding_rect = canvas.get_bounding_client_rect();

View File

@@ -279,13 +279,6 @@ impl WebPainter for WebPainterWgpu {
Some((output_frame, capture_buffer))
};
{
let mut renderer = render_state.renderer.write();
for id in &textures_delta.free {
renderer.free_texture(id);
}
}
// Submit the commands: both the main buffer and user-defined ones.
render_state
.queue
@@ -307,6 +300,16 @@ impl WebPainter for WebPainterWgpu {
frame.present();
}
// Free textures marked for destruction **after** queue submit since they might still be used in the current frame.
// Calling `wgpu::Texture::destroy` on a texture that is still in use would invalidate the command buffer(s) it is used in.
// However, once we called `wgpu::Queue::submit`, it is up for wgpu to determine how long the underlying gpu resource has to live.
{
let mut renderer = render_state.renderer.write();
for id in &textures_delta.free {
renderer.free_texture(id);
}
}
Ok(())
}