The Mac driver has historically used session-wide CGEventTaps to
implement ClipCursor. In macOS Mojave, such event taps started
requiring Accessibility permission from the user. That's problematic
on two levels:
First, it's a hassle. Unlike, say, microphone permissions, the user
can't just click "Approve" on a dialog box. Instead they have to go to
the System Preferences app, enter their password, and click a checkbox
(which will have the name of the preloader). This is especially bad
because ClipCursor is frequently called by fullscreen games, which
means the permission prompt will be hidden.
Second, many apps misbehave if ClipCursor fails. For instance, some
Unity games (e.g. Raft, The Forest) exhibit erratic mouse movement in
that case. But apps are likely to end up in that state since
Accessibility permission is deny-by-default and there is no blocking
call to check for the permission. The attempt to install an event tap
immediately fails until the permission is granted.
As of 10.13, there is an undocumented NSWindow method
-setMouseConfinementRect: that is in many ways a better option. It
does not support certain uncommon scenarios (clipping to regions
outside of a window), but it is far simpler and requires fewer
workarounds than the event tap. It also does not require permission
from the user.
This series of patches factors the existing clipping code out of
cocoa_app.m into its own class. It then adds a second implementation
of that interface that uses -setMouseConfinementRect:. Finally it
enables that approach by default in 10.13+, adding a registry key to
enable the old behavior if needed.
I'd welcome any feedback or suggestions. If you know of any apps that
clip the cursor to a region outside of a single frontmost window, I'd
also love to hear about those.
Tim Clem (5):
winemac.drv: Factor out cursor clipping code to its own class.
winemac.drv: Create a protocol to represent a cursor clipping handler.
winemac.drv: Factor common cursor clipping methods into functions.
winemac.drv: Add a cursor clipping implementation using
-setMouseConfinementRect:.
winemac.drv: Use -setMouseConfinementRect: for cursor clipping by
default.
dlls/winemac.drv/Makefile.in | 1 +
dlls/winemac.drv/cocoa_app.h | 11 +-
dlls/winemac.drv/cocoa_app.m | 333 ++--------------
dlls/winemac.drv/cocoa_cursorclipping.h | 73 ++++
dlls/winemac.drv/cocoa_cursorclipping.m | 510 ++++++++++++++++++++++++
dlls/winemac.drv/macdrv_cocoa.h | 1 +
dlls/winemac.drv/macdrv_main.c | 4 +
7 files changed, 626 insertions(+), 307 deletions(-)
create mode 100644 dlls/winemac.drv/cocoa_cursorclipping.h
create mode 100644 dlls/winemac.drv/cocoa_cursorclipping.m
--
2.34.1