From 61bd8b8254fa665a6e9c0c19c4b80e504d26ad40 Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Sun, 4 Jun 2023 01:08:47 +0200 Subject: [PATCH] Send position on button release --- CHANGELOG.md | 1 + .../web/event_loop/window_target.rs | 80 +++++++++++-------- src/platform_impl/web/web_sys/canvas.rs | 2 +- .../web/web_sys/canvas/mouse_handler.rs | 3 +- .../web/web_sys/canvas/pointer_handler.rs | 3 +- 5 files changed, 54 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10961a72..b4e3b1f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ And please only add new entries to the top of this list, right below the `# Unre - **Breaking:** On Web, `instant` is now replaced by `web_time`. - On Windows, port to `windows-sys` version 0.48.0. - On Web, fix pen treated as mouse input. +- On Web, send mouse position on button release as well. # 0.28.6 diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 74b8984b..ff76d356 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -400,43 +400,59 @@ impl EventLoopWindowTarget { }, ); - let runner = self.runner.clone(); - let runner_touch = self.runner.clone(); - let modifiers = self.modifiers.clone(); - let has_focus_clone = has_focus.clone(); canvas.on_mouse_release( - move |pointer_id, button, active_modifiers| { - let modifiers_changed = - (has_focus_clone.get() && modifiers.get() != active_modifiers).then(|| { - modifiers.set(active_modifiers); + { + let runner = self.runner.clone(); + let modifiers = self.modifiers.clone(); + let has_focus = has_focus.clone(); + + move |pointer_id, position, button, active_modifiers| { + let modifiers_changed = + (has_focus.get() && modifiers.get() != active_modifiers).then(|| { + modifiers.set(active_modifiers); + Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::ModifiersChanged(active_modifiers.into()), + } + }); + + // A mouse up event may come in without any prior CursorMoved events, + // therefore we should send a CursorMoved event to make sure that the + // user code has the correct cursor position. + runner.send_events(modifiers_changed.into_iter().chain([ Event::WindowEvent { window_id: RootWindowId(id), - event: WindowEvent::ModifiersChanged(active_modifiers.into()), - } - }); - - runner.send_events(modifiers_changed.into_iter().chain(iter::once( - Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::MouseInput { - device_id: RootDeviceId(DeviceId(pointer_id)), - state: ElementState::Released, - button, + event: WindowEvent::CursorMoved { + device_id: RootDeviceId(DeviceId(pointer_id)), + position, + }, }, - }, - ))); + Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::MouseInput { + device_id: RootDeviceId(DeviceId(pointer_id)), + state: ElementState::Released, + button, + }, + }, + ])); + } }, - move |device_id, location, force| { - runner_touch.send_event(Event::WindowEvent { - window_id: RootWindowId(id), - event: WindowEvent::Touch(Touch { - id: device_id as u64, - device_id: RootDeviceId(DeviceId(device_id)), - phase: TouchPhase::Ended, - force: Some(force), - location, - }), - }); + { + let runner_touch = self.runner.clone(); + + move |device_id, location, force| { + runner_touch.send_event(Event::WindowEvent { + window_id: RootWindowId(id), + event: WindowEvent::Touch(Touch { + id: device_id as u64, + device_id: RootDeviceId(DeviceId(device_id)), + phase: TouchPhase::Ended, + force: Some(force), + location, + }), + }); + } }, ); diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 6c9a7f78..2b676434 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -243,7 +243,7 @@ impl Canvas { pub fn on_mouse_release(&mut self, mouse_handler: M, touch_handler: T) where - M: 'static + FnMut(i32, MouseButton, ModifiersState), + M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), T: 'static + FnMut(i32, PhysicalPosition, Force), { match &mut self.mouse_state { diff --git a/src/platform_impl/web/web_sys/canvas/mouse_handler.rs b/src/platform_impl/web/web_sys/canvas/mouse_handler.rs index 6827cac6..73213963 100644 --- a/src/platform_impl/web/web_sys/canvas/mouse_handler.rs +++ b/src/platform_impl/web/web_sys/canvas/mouse_handler.rs @@ -84,7 +84,7 @@ impl MouseHandler { pub fn on_mouse_release(&mut self, canvas_common: &super::Common, mut handler: F) where - F: 'static + FnMut(i32, MouseButton, ModifiersState), + F: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), { let on_mouse_leave_handler = self.on_mouse_leave_handler.clone(); let mouse_capture_state = self.mouse_capture_state.clone(); @@ -110,6 +110,7 @@ impl MouseHandler { event.stop_propagation(); handler( 0, + event::mouse_position(&event).to_physical(super::super::scale_factor()), event::mouse_button(&event).expect("no mouse button released"), event::mouse_modifiers(&event), ); diff --git a/src/platform_impl/web/web_sys/canvas/pointer_handler.rs b/src/platform_impl/web/web_sys/canvas/pointer_handler.rs index 476855f0..105f645b 100644 --- a/src/platform_impl/web/web_sys/canvas/pointer_handler.rs +++ b/src/platform_impl/web/web_sys/canvas/pointer_handler.rs @@ -75,7 +75,7 @@ impl PointerHandler { mut mouse_handler: M, mut touch_handler: T, ) where - M: 'static + FnMut(i32, MouseButton, ModifiersState), + M: 'static + FnMut(i32, PhysicalPosition, MouseButton, ModifiersState), T: 'static + FnMut(i32, PhysicalPosition, Force), { let canvas = canvas_common.raw.clone(); @@ -91,6 +91,7 @@ impl PointerHandler { ), "mouse" => mouse_handler( event.pointer_id(), + event::mouse_position(&event).to_physical(super::super::scale_factor()), event::mouse_button(&event).expect("no mouse button released"), event::mouse_modifiers(&event), ),