From eb0812a9530f77712bf77aad0956f932a3a8f23d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Fri, 31 Mar 2023 10:11:41 +0200 Subject: [PATCH] eframe web: ensure modifiers keys won't stick in a down state on alt-tab (#2857) * eframe web: ensure modifiers keys won't stick in a down state on alt-tab * Update changelog * Properly set the has_focus input flag on web --- crates/eframe/CHANGELOG.md | 5 ++- crates/eframe/src/web/backend.rs | 8 +++++ crates/eframe/src/web/events.rs | 61 ++++++++++++++++++++++---------- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/crates/eframe/CHANGELOG.md b/crates/eframe/CHANGELOG.md index da8fa17c..a8c8d980 100644 --- a/crates/eframe/CHANGELOG.md +++ b/crates/eframe/CHANGELOG.md @@ -5,9 +5,12 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C ## Unreleased -* Add `Frame::request_screenshot` and `Frame::screenshot` to communicate to the backend that a screenshot of the current frame should be exposed by `Frame` during `App::post_rendering` ([#2676](https://github.com/emilk/egui/pull/2676)) +#### Desktop/Native: +* Add `Frame::request_screenshot` and `Frame::screenshot` to communicate to the backend that a screenshot of the current frame should be exposed by `Frame` during `App::post_rendering` ([#2676](https://github.com/emilk/egui/pull/2676)). * Add `eframe::run_simple_native` - a simple API for simple apps ([#2453](https://github.com/emilk/egui/pull/2453)). +#### Web: +* Bug fix: modifiers keys getting stuck on alt-tab ([#2857](https://github.com/emilk/egui/pull/2857)). ## 0.21.3 - 2023-02-15 * Fix typing the letter 'P' on web ([#2740](https://github.com/emilk/egui/pull/2740)). diff --git a/crates/eframe/src/web/backend.rs b/crates/eframe/src/web/backend.rs index 0d2301fc..03284723 100644 --- a/crates/eframe/src/web/backend.rs +++ b/crates/eframe/src/web/backend.rs @@ -30,6 +30,13 @@ impl WebInput { ..self.raw.take() } } + + pub fn on_web_page_focus_change(&mut self, has_focus: bool) { + self.raw.modifiers = egui::Modifiers::default(); + self.raw.has_focus = has_focus; + self.latest_touch_pos = None; + self.latest_touch_pos_id = None; + } } // ---------------------------------------------------------------------------- @@ -548,6 +555,7 @@ fn start_runner(app_runner: AppRunner, follow_system_theme: bool) -> Result Result<(), JsValue> { - let window = web_sys::window().unwrap(); - let document = window.document().unwrap(); + let document = web_sys::window().unwrap().document().unwrap(); + + { + // Avoid sticky modifier keys on alt-tab: + let clear_modifiers = ["blur", "focus"]; + + for event_name in clear_modifiers { + let closure = + move |_event: web_sys::MouseEvent, + mut runner_lock: egui::mutex::MutexGuard<'_, AppRunner>| { + let has_focus = event_name == "focus"; + runner_lock.input.on_web_page_focus_change(has_focus); + runner_lock.egui_ctx().request_repaint(); + // tracing::debug!("{event_name:?}"); + }; + + runner_container.add_event_listener(&document, event_name, closure)?; + } + } runner_container.add_event_listener( &document, @@ -185,6 +202,12 @@ pub fn install_document_events(runner_container: &mut AppRunnerContainer) -> Res }, )?; + Ok(()) +} + +pub fn install_window_events(runner_container: &mut AppRunnerContainer) -> Result<(), JsValue> { + let window = web_sys::window().unwrap(); + for event_name in &["load", "pagehide", "pageshow", "resize"] { runner_container.add_event_listener( &window, @@ -231,24 +254,26 @@ pub fn install_color_scheme_change_event( pub fn install_canvas_events(runner_container: &mut AppRunnerContainer) -> Result<(), JsValue> { let canvas = canvas_element(runner_container.runner.lock().canvas_id()).unwrap(); - let prevent_default_events = [ - // By default, right-clicks open a context menu. - // We don't want to do that (right clicks is handled by egui): - "contextmenu", - // Allow users to use ctrl-p for e.g. a command palette - "afterprint", - ]; + { + let prevent_default_events = [ + // By default, right-clicks open a context menu. + // We don't want to do that (right clicks is handled by egui): + "contextmenu", + // Allow users to use ctrl-p for e.g. a command palette: + "afterprint", + ]; - for event_name in prevent_default_events { - let closure = - move |event: web_sys::MouseEvent, - mut _runner_lock: egui::mutex::MutexGuard<'_, AppRunner>| { - event.prevent_default(); - // event.stop_propagation(); - // tracing::debug!("Preventing event {:?}", event_name); - }; + for event_name in prevent_default_events { + let closure = + move |event: web_sys::MouseEvent, + mut _runner_lock: egui::mutex::MutexGuard<'_, AppRunner>| { + event.prevent_default(); + // event.stop_propagation(); + // tracing::debug!("Preventing event {event_name:?}"); + }; - runner_container.add_event_listener(&canvas, event_name, closure)?; + runner_container.add_event_listener(&canvas, event_name, closure)?; + } } runner_container.add_event_listener(