From e6064b2be378fcd5e1f4fc879c0b0e85fa2d75ac Mon Sep 17 00:00:00 2001 From: Jonas Holzman Date: Tue, 14 Oct 2025 14:31:02 +0200 Subject: [PATCH] Fix #134818: macOS: Hidden mouse grab not keeping mouse in window This commit fixes an issue where WM cursor grabbing, when used in "hidden" mode (`GHOST_kGrabHide`) would unexpectedly not prevent the cursor from escaping the Blender window and revealing itself when hovering over macOS desktop elements like the application Dock. Looking at the original issue in past Blender versions, testing with the Walk Navigation operator, this used to work in Blender 3.2, and broke in Blender 3.3. Bisecting leads to commit 4c4e8cc926 (Fix T99021: Walk-mode doesn't work in Wayland), which switched the Walk Navigation mouse warping method from custom `WM_cursor_warp` logic to using `WM_cursor_grab_{enable/disable}`. Then, looking at the WM_cursor_grab Cocoa implementation, more especially at the `GHOST_kGrabHide` case in `handleMouseEvent`, a comment ("Cursor hidden grab operation : no cursor move") suggests that hiding the cursor would previously prevent it from moving (possibly in earlier macOS versions?). This fix, the simplest I could come up with other than implementing simple window warping for the `GHOST_kGrabHide` case (similar to what's done on Windows, see #113066) is to use `CGAssociateMouseAndMouseCursorPosition` to disable cursor movements for the duration of the hidden grab, effectively restoring the original behavior indicated in the comment. Pull Request: https://projects.blender.org/blender/blender/pulls/148007 --- intern/ghost/intern/GHOST_WindowCocoa.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 31b6d010c44..f0a1196804e 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -1187,6 +1187,10 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode setCursorGrabAccum(0, 0); if (mode == GHOST_kGrabHide) { + /* Dissociate cursor movements from the mouse while hidden to prevent the cursor from + * being accidentally revealed whe hovering over desktop elements like the Dock. */ + CGAssociateMouseAndMouseCursorPosition(false); + setWindowCursorVisibility(false); } @@ -1198,6 +1202,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode else { if (cursor_grab_ == GHOST_kGrabHide) { system_cocoa_->setCursorPosition(cursor_grab_init_pos_[0], cursor_grab_init_pos_[1]); + CGAssociateMouseAndMouseCursorPosition(true); setWindowCursorVisibility(true); }