From 6c9cdfc9810a70965b957685142c997a82e93437 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 21 Mar 2024 20:26:36 +0100 Subject: [PATCH] Consistently emit extra mouse motion events In particular, we don't want to emit those events inside of `pressureChangeWithEvent:`, since the mouse motion value is sometimes outdated. Additionally, we want to ensure the events have been emitted during other gestures. Fixes https://github.com/rust-windowing/winit/issues/3516 --- src/changelog/unreleased.md | 1 + src/platform_impl/macos/view.rs | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 9ad14dffad..6ca46aabec 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -41,3 +41,4 @@ - Add `Window::default_attributes` to get default `WindowAttributes`. - `log` has been replaced with `tracing`. The old behavior can be emulated by setting the `log` feature on the `tracing` crate. - On Windows, confine cursor to center of window when grabbed and hidden. +- On macOS, fix sequence of mouse events being out of order when dragging on the trackpad. diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index 99ea42b309..382813bcec 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -552,6 +552,17 @@ declare_class!( }); } + // In the past (?), `mouseMoved:` events were not generated when the + // user hovered over a window from a separate window, and as such the + // application might not know the location of the mouse in the event. + // + // To fix this, we emit `mouse_motion` inside of mouse click, mouse + // scroll, magnify and other gesture event handlers, to ensure that + // the application's state of where the mouse click was located is up + // to date. + // + // See https://github.com/rust-windowing/winit/pull/1490 for history. + #[method(mouseDown:)] fn mouse_down(&self, event: &NSEvent) { trace_scope!("mouseDown:"); @@ -686,6 +697,8 @@ declare_class!( fn magnify_with_event(&self, event: &NSEvent) { trace_scope!("magnifyWithEvent:"); + self.mouse_motion(event); + #[allow(non_upper_case_globals)] let phase = match unsafe { event.phase() } { NSEventPhaseBegan => TouchPhase::Started, @@ -703,9 +716,11 @@ declare_class!( } #[method(smartMagnifyWithEvent:)] - fn smart_magnify_with_event(&self, _event: &NSEvent) { + fn smart_magnify_with_event(&self, event: &NSEvent) { trace_scope!("smartMagnifyWithEvent:"); + self.mouse_motion(event); + self.queue_event(WindowEvent::DoubleTapGesture { device_id: DEVICE_ID, }); @@ -715,6 +730,8 @@ declare_class!( fn rotate_with_event(&self, event: &NSEvent) { trace_scope!("rotateWithEvent:"); + self.mouse_motion(event); + #[allow(non_upper_case_globals)] let phase = match unsafe { event.phase() } { NSEventPhaseBegan => TouchPhase::Started, @@ -735,8 +752,6 @@ declare_class!( fn pressure_change_with_event(&self, event: &NSEvent) { trace_scope!("pressureChangeWithEvent:"); - self.mouse_motion(event); - self.queue_event(WindowEvent::TouchpadPressure { device_id: DEVICE_ID, pressure: unsafe { event.pressure() },