0

My app implements a hotkey so I'm using AXIsProcessTrustedWithOptions to check and prompt for accessibility permissions so I can set up the hotkey with CGEventTapCreate/CFMachPortCreateRunLoopSource/CFRunLoopAddSource.

It all works fine unless the app is sandboxed, in which case the prompt doesn't appear and the app isn't added to the list in the accessibility section of the Privacy and Security dialog in system preferences.

I've tried all combinations that I can think of in terms of signing (Mac App Distribution, Apple Distribution, Developer etc.)

This is the code which enables/disables the hotkey - it works if sandbox is disabled. If sandbox is enabled, the call to AXIsProcessTrustedWithOptions returns false and doesn't show the prompt (or add the app to the list in system preferences).

- (void)setup_hotkey
{
    LOG(@"setup_hotkey: enabled = %d", settings.hotkey_enabled);
    if (settings.hotkey_enabled) {
        if (!hotkey_installed) {
            NSDictionary *options_prompt = @{(__bridge id)kAXTrustedCheckOptionPrompt : @YES};
            if (AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)options_prompt)) {
                LOG(@"permissions OK");
                hotkey_tap = CGEventTapCreate(kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
                                              CGEventMaskBit(kCGEventKeyDown), on_hotkey, (__bridge void *)self);
                hotkey_runloop_source_ref = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, hotkey_tap, 0);
                CFRunLoopAddSource(CFRunLoopGetMain(), hotkey_runloop_source_ref, kCFRunLoopCommonModes);
                hotkey_installed = true;
            } else {
                LOG(@"still need permissions");
                settings.hotkey_enabled = false;
                [self show_options_window];
            }
        }
    } else if (hotkey_installed) {
        LOG(@"remove hotkey");
        CFRunLoopRemoveSource(CFRunLoopGetMain(), hotkey_runloop_source_ref, kCFRunLoopCommonModes);
        hotkey_tap = nil;
        hotkey_runloop_source_ref = nil;
        hotkey_installed = false;
    }
}

The project settings look like this (as mentioned, I've tried all the certificate types, the behaviour is the same regardless of which one I use). I've tried adding User Selected File/Read-Only but that made no difference. I've also tried Automatic Signing and basically every other combination of settings on this page that I can find. The only way that I've found so far to make the prompt appear is to remove the Sandbox setting.

project settings

The entitlements file looks like this:

entitlements

and it is being correctly referenced in the project settings.

I've tried Debug/Release (the settings are the same for both) and running the app in the debugger or from Finder. Same results regardless.

I'm building with XCode 12.4, running on Catalina 10.15.7 (Build 19H2026). These are the most recent versions I can use on the Mac that I have.

So the question is: Am I doing something wrong in the setup_hotkey function? Is there some flag or parameter which needs to be changed? And if not, is there some official signing/entitlement setting which is wrong or missing?

I've looked at accessibility-api-stops-working-after-sandboxing which references some ancient Apple documentation but I can't find any more recent docs on this. My understanding is that Sandboxed app can be granted the accessibility privilege in Catalina but am I mistaken there?

I've tried notarizing it and then running the notarized app from the Applications folder - still no prompt...

Charlie Skilbeck
  • 1,081
  • 2
  • 15
  • 38
  • Did you see the question and answer [here](https://developer.apple.com/forums/thread/707680)? Note that if you're just listening for events and not modifying them, use `kCGEventTapOptionListenOnly ` instead of `kCGEventTapOptionDefault`. I'm not sure sandboxed apps can get Accessibility permission. The linked thread isn't really double-speak; making an application _accessible_ is not the same as allowing it to control the system. – TheNextman Dec 02 '22 at 16:36
  • Yes, I saw that - I'm already using CGEventTap. To implement the hotkey function I need to return nil from the hotkey callback (to stop the hotkey from propagating up to whatever app has keyboard focus) which, as far as I understand it, requires the accessibility permission rather than input monitoring which is for passive observers (although I'm not sure what that would be used for...?) – Charlie Skilbeck Dec 02 '22 at 18:59
  • Is it just the AX prompt that's broken under the sandbox? Can you manually add Accessibility via System Preferences and things work? – TheNextman Dec 02 '22 at 21:38
  • Yes, if I add manually it works, it just won't pop the prompt dialog if the permission isn't there already – Charlie Skilbeck Dec 03 '22 at 01:46
  • Looks like it's [specifically prohibited](https://stackoverflow.com/questions/39089615/temporary-entitlements-to-call-axisprocesstrustedwithoptions) by Apple – TheNextman Dec 03 '22 at 01:51

0 Answers0