I get asked or see people ask how to either get front application switched events in Cocoa or how to get global hot keys in Cocoa applications. It takes some extra work, but it is possible. I'll show you how.
Hot Keys in Cocoa
This is easy. Subclass NSApplication with your own version. Set the Principal class in the target settings window to your class then use the following code in your subclass.
enum {
// NSEvent subtypes for hotkey events (undocumented).
kEventHotKeyPressedSubtype = 6,
kEventHotKeyReleasedSubtype = 9,
};
- (void)sendEvent:(NSEvent *)theEvent
{
if ([theEvent type] == NSSystemDefined && [theEvent subtype] ==kEventHotKeyPressedSubtype)
{
// a hot key has been pressed.
// do something here.
}
[super sendEvent:theEvent]; // YOU MUST CALL THIS OR YOU WILL EAT EVENTS!
}
Yeah, that helps, right? [theEvent data1] is the registered hot key's identifier. You register hot keys using the normal Carbon code.
err=RegisterEventHotKey(keyCode,inMods,hotKeyID, GetApplicationEventTarget(), 0, hotKeyRef);
//hotKeyRef is the ID returned by [theEvent data1]
There's very little to it. You just need some way to find out what is supposed to happen when the hotkey is pressed. I use a dictionary to store the hotKeyRef in of each hot key I registered. I then add the key command pressed to the dictionary and execute that key command to my app's menu when the hotkey is pressed.
It really is that simple. Always check for errors.
Application switched events for Cocoa.
Painfully easy once you know what to do. In your application's delegate, register for the distributed notification com.apple.HIToolbox.menuBarShownNotification in -awakeFromNib. This is notification is sent whenever the front application changes. I also register for app launched and app died events "just in case" the menu bar notification fails. You also need to prepare your code in case it receives two notifications in succession. It will when launching or quitting applications.
// The below registrations are made to check if the front application has changed
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(checkFrontApp:) name:NSWorkspaceDidLaunchApplicationNotification object:nil];
[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self selector:@selector(checkFrontApp:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkFrontApp:) name:NSApplicationDidBecomeActiveNotification object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkFrontApp:) name:NSApplicationDidResignActiveNotification object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkFrontApp:) name:NSApplicationDidHideNotification object:NSApp];
[[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(checkFrontApp:) name:@"com.apple.HIToolbox.menuBarShownNotification" object:nil];
checkFrontApp: is the selector that gets called when the front application changes. That is, the method called when one of the notifications is received.
Make sense? Any questions? Special thanks to Evan Gross and NoisyApp.
Related:
- Hiya Kids, it's Theming Time! - Oct 06, 2009
- Mighty Mouse with Some Theme Sauce - Jun 02, 2009
- WindowShade X 4.3 - Apr 24, 2009
- Sound of the Underground - Apr 20, 2009
- Welcome back. - Apr 17, 2009
Does the hotkeys work for cocoa applications on 10.1? It was my understanding that it won't work because cocoa apps can't recieve carbon events...
At least that's my understanding- and if this is the case, do you know of any work arounds or hacks to make this work?
thanks,
-gus
Posted by: Gus Mueller on October 21, 2002 12:19 AMI relatively new to Cocoa and could use a little extra help. This is the best help I've found so far, but I'd like it a little dumbed down. Email me, please. Thanks.
Posted by: Eric Bailey on April 28, 2004 10:09 PMHi,
thx for the code, it helped me a lot to create hotkeys for CuteClips.
i refactored the code a bit and created a loadable plugin, so that every application can easily use hotkeys. one just has to load the plugin and register a hotkey with a name, the rest is done by the plugin. the plugin also provides a prefsview that can be assigned to some NSView in order to configure the key.
The plugin is available from www.codebeach.org and is under MIT license.
Karsten
Posted by: Karsten on April 26, 2007 7:26 AMFrontmost app changes are no longer accompanied by "com.apple.HIToolbox.menuBarShownNotification" distributed notifications since the first day Tiger came out.
Posted by: Dirk Buro on September 12, 2007 4:45 PMKeep comments on topic. If a comment is unrelated to this post, it may be removed or moderated.
