I've needed to make a global hot key input box in my Cocoa App.
I know about Shortcut Recorder, but it is a very old solution. It has parts implemented using Carbon, which has been deprecated, and I can't publish my app to the Mac App Store if I use it.
Is there any ready-to-use modern solution? Can anybody give me the way to make this by myself (I don't know where to start from)?
On your Mac, choose Apple menu > System Preferences, click Keyboard , then click Shortcuts. Select App Shortcuts on the left, click the Add button , click the Application pop-up menu, then choose a specific app or All Applications.
Open “System Preferences” > Keyboard > Shortcuts Tab > Services. You should see the service that you have just created. Click on the service and click on “Add Shortcut” and assign a shortcut. Now the service will be invoked every-time you hit the shortcut and the service would enter the keystrokes “[email protected]”.
There is a modern framework named MASShortcut for implementing Global Shortcuts in OS X 10.7+.
Not all of Carbon is deprecated. You can't make a pure-Carbon application anymore, but some APIs live on and some of them are still the easiest way to do certain things.
One of these is the Carbon Events hotkey API. You certainly can sift through all the events using NSEvent's event-monitor methods, but it's unnecessary work. The Carbon Events hotkey API is still supported and much simpler—you just tell it what key you want to match and what function to call when the key is pressed. And there are Cocoa wrappers such as DDHotKey that make it even simpler.
In Mac OS X 10.6 and higher, you can use the methods +addGlobalMonitorForEventsMatchingMask:handler: and +addLocalMonitorForEventsMatchingMask:handler: defined from the NSEvent
class. Monitoring Events reports the following information:
Local and global event monitors are mutually exclusive. For example, the global monitor does not observe the event stream of the application in which it is installed. The local event monitor only observes the event stream of its application. To monitor events from all applications, including the "current" application, you must install both event monitors.
The code shown in that page is for a local event monitor, but the code for a global event monitor is similar; what changes is the invoked NSEvent
's method.
_eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:
(NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask | NSKeyDownMask)
handler:^(NSEvent *incomingEvent) {
NSEvent *result = incomingEvent;
NSWindow *targetWindowForEvent = [incomingEvent window];
if (targetWindowForEvent != _window) {
[self _closeAndSendAction:NO];
} else if ([incomingEvent type] == NSKeyDown) {
if ([incomingEvent keyCode] == 53) {
// Escape
[self _closeAndSendAction:NO];
result = nil; // Don't process the event
} else if ([incomingEvent keyCode] == 36) {
// Enter
[self _closeAndSendAction:YES];
result = nil;
}
}
return result;
}];
Once the monitor is not anymore necessary, you remove it using the following code:
[NSEvent removeMonitor:_eventMonitor];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With