diff --git a/CHANGELOG.md b/CHANGELOG.md index 54f5a13bc86..763690b1201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ And please only add new entries to the top of this list, right below the `# Unre - Added `Window::is_resizable`. - Added `Window::is_decorated`. - On X11, fix for repeated event loop iteration when `ControlFlow` was `Wait` +- On web, by default, when the canvas is focused, scrolling of the webpage is disabled. It can however be enabled via the `WindowBuilderExtWebSys::enable_web_scroll` method. - On Wayland, report unaccelerated mouse deltas in `DeviceEvent::MouseMotion`. - **Breaking:** Bump `ndk` version to 0.6, ndk-sys to `v0.3`, `ndk-glue` to `0.6`. - Remove no longer needed `WINIT_LINK_COLORSYNC` environment variable. diff --git a/src/platform/web.rs b/src/platform/web.rs index 210f87b9d2c..9ea4c74ca01 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -17,10 +17,25 @@ pub trait WindowExtWebSys { } pub trait WindowBuilderExtWebSys { + /// Enable scrolling of the web page the canvas is in when the canvas is focused. + /// + /// Scrolling is disabled by default because the scroll input on many mobile devices + /// is the same as click and dragging which is a very common input method for many applications. + /// + /// So only call this method if you know that you will never need to handle mouse wheel inputs + /// or click and dragging. + fn enable_web_scroll(self) -> Self; + fn with_canvas(self, canvas: Option) -> Self; } impl WindowBuilderExtWebSys for WindowBuilder { + fn enable_web_scroll(mut self) -> Self { + self.platform_specific.enable_web_scroll = true; + + self + } + fn with_canvas(mut self, canvas: Option) -> Self { self.platform_specific.canvas = canvas; diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 8d68e5aaab2..529b7b4a8ca 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -30,6 +30,7 @@ pub struct Canvas { on_fullscreen_change: Option>, on_dark_mode: Option, mouse_state: MouseState, + disable_web_scroll: Option<[EventListenerHandle; 5]>, } struct Common { @@ -72,11 +73,34 @@ impl Canvas { MouseState::NoPointerEvent(mouse_handler::MouseHandler::new()) }; + let common = Common { + raw: canvas, + wants_fullscreen: Rc::new(RefCell::new(false)), + }; + + let disable_web_scroll = if !attr.enable_web_scroll { + Some([ + common.add_event("pointermove", move |event: Event| { + event.prevent_default(); + }), + common.add_event("pointermove", move |event: Event| { + event.prevent_default(); + }), + common.add_event("touchstart", move |event: Event| { + event.prevent_default(); + }), + common.add_event("touchend", move |event: Event| { + event.prevent_default(); + }), + common.add_event("wheel", move |event: Event| { + event.prevent_default(); + }), + ]) + } else { + None + }; + Ok(Canvas { - common: Common { - raw: canvas, - wants_fullscreen: Rc::new(RefCell::new(false)), - }, on_blur: None, on_focus: None, on_keyboard_release: None, @@ -86,6 +110,8 @@ impl Canvas { on_fullscreen_change: None, on_dark_mode: None, mouse_state, + disable_web_scroll, + common, }) } @@ -266,7 +292,6 @@ impl Canvas { F: 'static + FnMut(i32, MouseScrollDelta, ModifiersState), { self.on_mouse_wheel = Some(self.common.add_event("wheel", move |event: WheelEvent| { - event.prevent_default(); if let Some(delta) = event::mouse_scroll_delta(&event) { handler(0, delta, event::mouse_modifiers(&event)); } diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index 2850439ad3b..2f74026de3d 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -365,4 +365,5 @@ impl Id { #[derive(Default, Clone)] pub struct PlatformSpecificBuilderAttributes { pub(crate) canvas: Option, + pub(crate) enable_web_scroll: bool, }