I have a Mac app with a background-only helper app that needs to have Accessibility permission in order to use an event tap that can modify events. This has worked OK through Sonoma, but in the Sequoia beta it is failing to create the tap. C code to test the ability to create the event tap:
static CGEventRef _Nullable DummyTap(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *userInfo)
{
return NULL;
}
static bool CanFilterEvents( void )
{
CFMachPortRef thePort = CGEventTapCreate(
kCGSessionEventTap,
kCGTailAppendEventTap,
kCGEventTapOptionDefault, // active filter, not passive listener
CGEventMaskBit(kCGEventKeyDown),
DummyTap,
NULL );
bool madeTap = (thePort != NULL);
if (madeTap)
{
CFMachPortInvalidate( thePort );
CFRelease( thePort );
}
return madeTap;
}
So, on Sequoia, CanFilterEvents
returns false in spite of Accessibility permission being granted in System Settings. CGPreflightPostEventAccess
also returns false, but AXIsProcessTrusted
returns true.
I tried making a non-background-only test app, and when that has Accessibility permission, CanFilterEvents
, CGPreflightPostEventAccess
, and AXIsProcessTrusted
all return true. Suggestions on what to try next?
I tried making a non-background-only test app, and when that has Accessibility permission, CanFilterEvents, CGPreflightPostEventAccess, and AXIsProcessTrusted all return true. Suggestions on what to try next?
First off, please file a bug report on this and post the feedback number here. If something that used to work stops working then a bug is always warranted.
As for what you do "now", there are few things:
-
How exactly is your "background-only helper app" setup? Is it an app bundle that marked as "faceless" with LSUIElement set? Or is it a standalone executable? My general recommendation is that the "default" should be to bundle ALL executables, even if you won't actually be calling/using that executable as an "app". For example, I even think it's a good idea to bundle "command line" executables that simply perform specific tasks and then exit. As far as the system is concerned, any executable will work fine inside an app bundle and, in my experience, the bundle structure is far less likely to have issues.
-
How are you launching your helper app? In particular, "direct execution" (Process, NSTask, fork/exec, posix_spawn...) is NOT equivalent to having "the system" launch the app (NSWorkspace). There's a long history of "nonsensical" API failures like this occurring because an internal framework change ended up breaking a complicated chain of "details" that were allowing the direct execution case to work.
-
What have you actually granted permission to? If you haven't authorized your main app, that would be worth trying as well.
-
What happens if you transition your test app into "accessory"? Or transition your real app into "regular", then back to "accessory"? Our API history obscures this, but apps can freely transition in/out of app types using setActivationPolicy(_:)->.accessory/.regular. What LSUIElement basically does is tell LaunchServices not to create a dock icon during early launch the "set" your app into NSApplication.ActivationPolicy.accessory once it's actual up and running.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware