Search code examples
swiftmacosmacos-venturamacos-sequoia

How to check the status of the 'Input Monitoring' permission in my swift-based macOS app?


How would I be able to see if my app has 'Input Monitoring' permissions in my Swift-based macOS app? This applies to macOS Ventura+.

enter image description here

In earlier versions of macOS, I think this permission was bundled in with the Accessibility permissions, which I could query with AXIsProcessTrusted() or AXIsProcessTrustedWithOptions(options as CFDictionary?). This still returns true if my app is enabled in the Accessibility menu (see below), but I'm not able to see the Input Monitoring status specifically.

enter image description here

Is anyone aware of an API that will expose Input Monitoring status, or any other technique for determining if access has been granted?


Solution

  • As by @Willeke's comment, use IOHIDCheckAccess to test for "Input Monitoring" status:

     IOHIDCheckAccess(kIOHIDRequestTypeListenEvent)
    

    This will return one of the following IOHIDAccessType:

    IOHIDAccessType(rawValue: 2) kIOHIDAccessTypeUnknown

    IOHIDAccessType(rawValue: 1) kIOHIDAccessTypeDenied

    IOHIDAccessType(rawValue: 0) kIOHIDAccessTypeGranted

    Note that there is also ...

    IOHIDCheckAccess(kIOHIDRequestTypePostEvent)
    

    which relates to posting events and is showing up in "Accessibility" permissions. It is including the Listen type, the check for ...ListenEvent will return ...Granted, but your app will NOT be listed in "Input Monitoring" when granted. So you would have to check for PostEvent first, then for ListenEvent to know if you have ONLY listen access right.


    To request the access, either just use an API that needs this or explicitly request it with these:

    Requesting Event Listen Access ("Input Monitoring" section):

    IOHIDRequestAccess(kIOHIDRequestTypeListenEvent)
    

    Requesting Event Post Access ("Accessibility" section):

    IOHIDRequestAccess(kIOHIDRequestTypePostEvent)
    

    Both methods trigger the user permission request dialogue window on the first call and return false if denied, true if granted.
    Afaik, there‘s no way to „re-trigger“ that dialogue once it is denied and the user has to go manually to security settings.