From 9306e01b10cd0cad50179f68fe8c8fed1c86e4a1 Mon Sep 17 00:00:00 2001 From: Yevgeny Makarov Date: Sun, 29 Nov 2020 17:35:33 +0100 Subject: Fix T82870: on macOS, continuous grab jumps when crossing editor border The event queue can contain events from before pointer warping, ignore those now. This is an old issue, but became more common now that we disabled event coalescing and started using the event mouse location rather than the current mouse location. Thanks to Yevgeny Makarov and Nicholas Rishel for helping solve this. Ref D9662 --- intern/ghost/intern/GHOST_SystemCocoa.h | 3 +++ intern/ghost/intern/GHOST_SystemCocoa.mm | 13 +++++++++++++ 2 files changed, 16 insertions(+) (limited to 'intern/ghost') diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 5637dfb0565..cee6398b5a6 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -311,4 +311,7 @@ class GHOST_SystemCocoa : public GHOST_System { bool m_ignoreMomentumScroll; /** Is the scroll wheel event generated by a multitouch trackpad or mouse? */ bool m_multiTouchScroll; + /** To prevent multiple warp, we store the time of the last warp event + * and ignore mouse moved events generated before that. */ + double m_last_warp_timestamp; }; diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 2a3f6e0b0b9..d5b8311349b 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -53,6 +53,8 @@ #include #include +#include + #pragma mark KeyMap, mouse converters static GHOST_TButtonMask convertButton(int button) @@ -537,6 +539,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() m_ignoreWindowSizedMessages = false; m_ignoreMomentumScroll = false; m_multiTouchScroll = false; + m_last_warp_timestamp = 0; } GHOST_SystemCocoa::~GHOST_SystemCocoa() @@ -1590,6 +1593,13 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } case GHOST_kGrabWrap: // Wrap cursor at area/window boundaries { + NSTimeInterval timestamp = [event timestamp]; + if (timestamp < m_last_warp_timestamp) { + /* After warping we can still receive older unwarped mouse events, + * ignore those. */ + break; + } + NSPoint mousePos = [event locationInWindow]; GHOST_TInt32 x_mouse = mousePos.x; GHOST_TInt32 y_mouse = mousePos.y; @@ -1625,6 +1635,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) setMouseCursorPosition(warped_x, warped_y); /* wrap */ window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse), y_accum + (y_mouse - warped_y_mouse)); + + /* This is the current time that matches NSEvent timestamp. */ + m_last_warp_timestamp = mach_absolute_time() * 1e-9; } // Generate event -- cgit v1.2.3