MacOS App: handling global keyboard shortcuts

In some applications, it makes sense for the application to directly handle keyboard shortcuts that are otherwise associated with system combinations. For example, ⌘-Space (usually Spotlight) or ⌘-Tab (usually an app switcher). This works in various Mac applications, such as VMWare Fusion, native Screen Sharing and Remote Desktop users (sending events to a virtual machine or server, instead of managing them locally, respectively), as well as some similar third-party applications in the store application.

We would like to implement such a regime in the application we are working on, but we are having difficulty developing how to do it. I must point out that this application is a regular front-end application, it is isolated, and any solution must comply with the rules of the App Store. The fact that other apps in the store can do this implies that this should be possible.

To be clear, we want:

  • Detect and process all keystrokes, including those associated with global shortcuts.
  • Disable global shortcuts to trigger their globally related effect.

Apple's Event Architecture Document assumes that the foreground application should already receive these events. (He talks only about earlier levels that control things like power and eject buttons, which is good.) The following is suggested, but

+7
source share
2 answers

I decided this a long time ago, but only noticed that I had never posted it here. Answer ended with CGSSetGlobalHotKeyOperatingMode() . This is not a public API, but there are a number of Mac App Store applications that use it, confusing the function name and looking through it dynamically. Apple doesn't seem to mind. The API is fairly easy to use, and there are many open source code examples.

0
source

Well, that’s why Cocoa event methods and Quartz event indents are missing because they either require root access or accessibility, or they don’t capture events in front of the dock.

PushSymbolicHotKeyMode no Carbon PushSymbolicHotKeyMode because documents require access to accessibility.

Carbon RegisterEventHotKey probably came out because Apple doesn't seem to allow it (see my link in the comment for the question). However, despite this, I tested, and you cannot use it to catch Command + Tab.

I made a brief proof of how this might work, but YMMV:

  • we implement the KeyboardWatcher class from this. You will need to bind IOKit.
  • add the rights to use the hardware - USB (com.apple.security.device.usb). This is necessary because KeyboardWatcher uses HID to capture keystrokes.
  • Handle_DeviceEventCallback will provide you the keys pressed. You can obviously change this to your needs.
  • Use SetSystemUIMode to lock task switcher and Spotlight. You will need to bind Carbon.

SetSystemUIMode(kUIModeContentSuppressed, kUIOptionDisableProcessSwitch);

Please note that this will only work when your application is in the foreground (maybe what you want). I set this on my view using the tracking rectangle, so it takes effect when the mouse is over my view (e.g. in Remotix):

 - (void)viewDidLoad { [super viewDidLoad]; NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:[self.view bounds] options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil]; [self.view addTrackingArea:trackingArea]; } - (void) mouseEntered:(NSEvent*)theEvent { SetSystemUIMode(kUIModeContentSuppressed, kUIOptionDisableProcessSwitch); } - (void) mouseExited:(NSEvent*)theEvent { SetSystemUIMode(kUIModeNormal, 0); } 

Remotix seems to connect Carbon and IOKit, but I don’t see if they have USB rights (I tried the demo, not the version of the App Store). Perhaps they are doing something like this.


A common way to achieve this is to install a crane. However, to receive events intended for other applications, you must (as you say) be either root or have access to accessibility for your application.

It seems impossible to use an event tap with current sandbox rules. This is confirmed in the developer forum. A link is only a login, but for a quote from a stream:

Is it possible to handle media key events, preventing iTunes from starting. Before the sandbox, this was possible by creating a CGEventTap, but now the sandbox denies the use of hid-controll.

No, this is currently not possible in the Sandbox app.

I am not sure of another way to do this; and I’d be interested to know which apps on the App Store can?

VMWare Fusion is clearly not isolated, and Apple’s own applications are exempt from the rules. Remember that the sandbox is only used in new applications added after its introduction in 2012. Applications added before this date do not have a forced sandbox. See this answer .

+2
source

Source: https://habr.com/ru/post/1268723/


All Articles