From 91aac75638c2274fe5aa35d931b0b7ebcd50fcb2 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 29 Jun 2024 00:02:16 +0200 Subject: [PATCH] Web: Remove some unnecessary compatibility code --- src/changelog/unreleased.md | 1 + src/platform_impl/web/event_loop/runner.rs | 100 +++++++++++---------- src/platform_impl/web/web_sys/event.rs | 68 +++----------- 3 files changed, 69 insertions(+), 100 deletions(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index f5cd2a6b18..9e9a479cb4 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -52,6 +52,7 @@ changelog entry. to send specific data to be processed on the main thread. - Changed `EventLoopProxy::send_event` to `EventLoopProxy::wake_up`, it now only wakes up the loop. +- On Web, slightly improve accuracy of `DeviceEvent::MouseMotion`. ### Removed diff --git a/src/platform_impl/web/event_loop/runner.rs b/src/platform_impl/web/event_loop/runner.rs index 92a7d624b8..6dd1b39a37 100644 --- a/src/platform_impl/web/event_loop/runner.rs +++ b/src/platform_impl/web/event_loop/runner.rs @@ -234,64 +234,74 @@ impl Shared { )); let runner = self.clone(); - let window = self.window().clone(); *self.0.on_mouse_move.borrow_mut() = Some(EventListenerHandle::new( self.window().clone(), "pointermove", - Closure::new(move |event: PointerEvent| { - if !runner.device_events() { - return; - } + Closure::new({ + let mut delta = backend::event::MouseDelta::new(); + move |event: PointerEvent| { + if !runner.device_events() { + return; + } - let pointer_type = event.pointer_type(); + let pointer_type = event.pointer_type(); - if pointer_type != "mouse" { - return; - } - - // chorded button event - let device_id = RootDeviceId(DeviceId(event.pointer_id())); + if pointer_type != "mouse" { + return; + } - if let Some(button) = backend::event::mouse_button(&event) { - debug_assert_eq!( - pointer_type, "mouse", - "expect pointer type of a chorded button event to be a mouse" - ); + // chorded button event + let device_id = RootDeviceId(DeviceId(event.pointer_id())); - let state = if backend::event::mouse_buttons(&event).contains(button.into()) { - ElementState::Pressed - } else { - ElementState::Released - }; + if let Some(button) = backend::event::mouse_button(&event) { + debug_assert_eq!( + pointer_type, "mouse", + "expect pointer type of a chorded button event to be a mouse" + ); - runner.send_event(Event::DeviceEvent { - device_id, - event: DeviceEvent::Button { button: button.to_id(), state }, - }); + let state = if backend::event::mouse_buttons(&event).contains(button.into()) + { + ElementState::Pressed + } else { + ElementState::Released + }; - return; - } + runner.send_event(Event::DeviceEvent { + device_id, + event: DeviceEvent::Button { button: button.to_id(), state }, + }); - // pointer move event - let mut delta = backend::event::MouseDelta::init(&window, &event); - runner.send_events(backend::event::pointer_move_event(event).flat_map(|event| { - let delta = delta.delta(&event).to_physical(backend::scale_factor(&window)); + return; + } - let x_motion = (delta.x != 0.0).then_some(Event::DeviceEvent { - device_id, - event: DeviceEvent::Motion { axis: 0, value: delta.x }, - }); + // pointer move event + runner.send_events(backend::event::pointer_move_event(event).flat_map( + |event| { + let delta = delta.delta(&event); - let y_motion = (delta.y != 0.0).then_some(Event::DeviceEvent { - device_id, - event: DeviceEvent::Motion { axis: 1, value: delta.y }, - }); + if delta.x == 0 && delta.y == 0 { + return None.into_iter().chain(None).chain(None); + } - x_motion.into_iter().chain(y_motion).chain(iter::once(Event::DeviceEvent { - device_id, - event: DeviceEvent::MouseMotion { delta: (delta.x, delta.y) }, - })) - })); + let x_motion = (delta.x != 0).then_some(Event::DeviceEvent { + device_id, + event: DeviceEvent::Motion { axis: 0, value: delta.x.into() }, + }); + + let y_motion = (delta.y != 0).then_some(Event::DeviceEvent { + device_id, + event: DeviceEvent::Motion { axis: 1, value: delta.y.into() }, + }); + + x_motion.into_iter().chain(y_motion).chain(Some(Event::DeviceEvent { + device_id, + event: DeviceEvent::MouseMotion { + delta: (delta.x.into(), delta.y.into()), + }, + })) + }, + )); + } }), )); let runner = self.clone(); diff --git a/src/platform_impl/web/web_sys/event.rs b/src/platform_impl/web/web_sys/event.rs index 51df63714b..b76cce9b5a 100644 --- a/src/platform_impl/web/web_sys/event.rs +++ b/src/platform_impl/web/web_sys/event.rs @@ -1,7 +1,7 @@ -use crate::dpi::LogicalPosition; use crate::event::{MouseButton, MouseScrollDelta}; use crate::keyboard::{Key, KeyLocation, ModifiersState, NamedKey, PhysicalKey}; +use dpi::{LogicalPosition, PhysicalPosition}; use smol_str::SmolStr; use std::cell::OnceCell; use wasm_bindgen::prelude::wasm_bindgen; @@ -95,42 +95,23 @@ pub fn mouse_position(event: &MouseEvent) -> LogicalPosition { LogicalPosition { x: event.offset_x(), y: event.offset_y() } } -// TODO: Remove this when Firefox supports correct movement values in coalesced events. -// See . -pub struct MouseDelta(Option); - -pub struct MouseDeltaInner { - old_position: LogicalPosition, - old_delta: LogicalPosition, -} +pub struct MouseDelta(Option>); impl MouseDelta { - pub fn init(window: &web_sys::Window, event: &PointerEvent) -> Self { - // Firefox has wrong movement values in coalesced events, we will detect that by checking - // for `pointerrawupdate` support. Presumably an implementation of `pointerrawupdate` - // should require correct movement values, otherwise uncoalesced events might be broken as - // well. - Self((!has_pointer_raw_support(window) && has_coalesced_events_support(event)).then(|| { - MouseDeltaInner { - old_position: mouse_position(event), - old_delta: LogicalPosition { - x: event.movement_x() as f64, - y: event.movement_y() as f64, - }, - } - })) + pub fn new() -> Self { + Self(None) } - pub fn delta(&mut self, event: &MouseEvent) -> LogicalPosition { - if let Some(inner) = &mut self.0 { - let new_position = mouse_position(event); - let x = new_position.x - inner.old_position.x + inner.old_delta.x; - let y = new_position.y - inner.old_position.y + inner.old_delta.y; - inner.old_position = new_position; - inner.old_delta = LogicalPosition::new(0., 0.); - LogicalPosition::new(x, y) + pub fn delta(&mut self, event: &MouseEvent) -> PhysicalPosition { + let new = PhysicalPosition::new(event.screen_x(), event.screen_y()); + + if let Some(old) = self.0 { + let delta = PhysicalPosition::new(new.x - old.x, new.y - old.y); + self.0 = Some(new); + delta } else { - LogicalPosition { x: event.movement_x() as f64, y: event.movement_y() as f64 } + self.0 = Some(new); + PhysicalPosition::default() } } } @@ -238,29 +219,6 @@ pub fn pointer_move_event(event: PointerEvent) -> impl Iterator. -pub fn has_pointer_raw_support(window: &web_sys::Window) -> bool { - thread_local! { - static POINTER_RAW_SUPPORT: OnceCell = const { OnceCell::new() }; - } - - POINTER_RAW_SUPPORT.with(|support| { - *support.get_or_init(|| { - #[wasm_bindgen] - extern "C" { - type PointerRawSupport; - - #[wasm_bindgen(method, getter, js_name = onpointerrawupdate)] - fn has_on_pointerrawupdate(this: &PointerRawSupport) -> JsValue; - } - - let support: &PointerRawSupport = window.unchecked_ref(); - !support.has_on_pointerrawupdate().is_undefined() - }) - }) -} - // TODO: Remove when Safari supports `getCoalescedEvents`. // See . pub fn has_coalesced_events_support(event: &PointerEvent) -> bool {