Intercepting keystrokes on macOS is a recurrent nightmare.
I wrote this code 4 years ago and it worked.
A couple of years on, macOS updated and it broke. This fixed it: CGEventTapCreate returns null in macOS Mojave
Now it's broken again.
NSLog(@" Creating event tap");
eventTap = CGEventTapCreate( kCGHIDEventTap, // Event tap is placed at point where HID system events enter window server.
kCGHeadInsertEventTap, // Insert tap BEFORE any pre-existing event taps at the same location.
kCGEventTapOptionDefault, // Active filter, not passive listener.
CGEventMaskBit( NSEventTypeKeyDown )
| CGEventMaskBit( NSEventTypeKeyUp )
| CGEventMaskBit( NSEventTypeMouseMoved )
| CGEventMaskBit( NSEventTypeFlagsChanged )
| CGEventMaskBit( NSEventTypeSystemDefined ),
(CGEventTapCallBack)tap_callback,
(__bridge void *)(self));
if ( eventTap == NULL ) {
NSLog( @"Unable to create event tap. Run as root or `SysPrefs->Security&Privacy->Privacy->{check mapper app}" );
NSLog( @"");
[NSApp terminate:nil]; // or: exit( 1 );
}
NSLog(@" Enabling tap");
// :
https://github.com/0x8BADFOOD/osx-cmd-launcher is a minimal hello-world / testcase that demonstrates the problem.
It should switch the a
and z
keys on your keyboard.
I've filed an issue: https://github.com/0x8BADFOOD/osx-cmd-launcher/issues/1
Can anyone get it to run?
I'm really stuck here.
EDIT: I've resolved the issue with the CLI hello-world program. But I still can't get my solution working in XCode
EDIT: An Apple support engineer has shared code that DOES achieve the EventTap in XCode (using Swift), so I'm utterly confounded as to how my app still cannot achieve. I've tried so many combinations of refreshing my provisioning profile, resetting my keychain, using Development not Local for profile, info.plist, entitlements, sysPrefs Accessibility & InputMonitoring, running as sudo, etc etc.
Research:
https://developer.apple.com/documentation/coregraphics/1454426-cgeventtapcreate
tap
The location of the new event tap. Pass one of the constants listed in CGEventTapLocation. Only processes running as the root user may locate an event tap at the point where HID events enter the window server; for other users, this function returns NULL.
Googling for "CGEventTap Ventura" yields e.g. https://github.com/artginzburg/MiddleClick-Ventura/blob/main/MiddleClick/Controller.m which suggests that someone has managed to get some kind of event-tap working on Ventura.