From 7ebc68bb846a690199d005df31d552c9abb68284 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Sun, 22 Jan 2023 23:35:32 +0000 Subject: [PATCH] Allow not preventing default event behaviors on wasm (#7304) # Objective On wasm, bevy applications currently prevent any of the normal browser hotkeys from working normally (Ctrl+R, F12, F5, Ctrl+F5, tab, etc.). Some of those events you may want to override, perhaps you can hold the tab key for showing in-game stats? However, if you want to make a well-behaved game, you probably don't want to needlessly prevent that behavior unless you have a good reason. Secondary motivation: Also, consider the workaround presented here to get audio working: https://developer.chrome.com/blog/web-audio-autoplay/#moving-forward ; It won't work (for keydown events) if we stop event propagation. ## Solution - Winit has a field that allows it to not stop event propagation, expose it on the window settings to allow the user to choose the desired behavior. Default to `true` for backwards compatibility. --- ## Changelog - Added `Window::prevent_default_event_handling` . This allows bevy apps to not override default browser behavior on hotkeys like F5, F12, Ctrl+R etc. --- crates/bevy_window/src/window.rs | 8 ++++++++ crates/bevy_winit/src/winit_windows.rs | 3 +++ examples/window/window_settings.rs | 2 ++ 3 files changed, 13 insertions(+) diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index ec29a7e9692aa..2c0aad00b756c 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -158,6 +158,13 @@ pub struct Window { /// /// This value has no effect on non-web platforms. pub fit_canvas_to_parent: bool, + /// Whether or not to stop events from propagating out of the canvas element + /// + /// When `true`, this will prevent common browser hotkeys like F5, F12, Ctrl+R, tab, etc. + /// from performing their default behavior while the bevy app has focus. + /// + /// This value has no effect on non-web platforms. + pub prevent_default_event_handling: bool, /// Stores internal state that isn't directly accessible. pub internal: InternalWindowState, } @@ -180,6 +187,7 @@ impl Default for Window { focused: true, always_on_top: false, fit_canvas_to_parent: false, + prevent_default_event_handling: true, canvas: None, } } diff --git a/crates/bevy_winit/src/winit_windows.rs b/crates/bevy_winit/src/winit_windows.rs index 2f7dda6702f7b..25ac5e40b780a 100644 --- a/crates/bevy_winit/src/winit_windows.rs +++ b/crates/bevy_winit/src/winit_windows.rs @@ -110,6 +110,9 @@ impl WinitWindows { panic!("Cannot find element: {}.", selector); } } + + winit_window_builder = + winit_window_builder.with_prevent_default(window.prevent_default_event_handling) } let winit_window = winit_window_builder.build(event_loop).unwrap(); diff --git a/examples/window/window_settings.rs b/examples/window/window_settings.rs index 53ceccb1eb50b..7d914081cfec1 100644 --- a/examples/window/window_settings.rs +++ b/examples/window/window_settings.rs @@ -16,6 +16,8 @@ fn main() { present_mode: PresentMode::AutoVsync, // Tells wasm to resize the window according to the available canvas fit_canvas_to_parent: true, + // Tells wasm not to override default event handling, like F5, Ctrl+R etc. + prevent_default_event_handling: false, ..default() }), ..default()