January 2010
Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            

October 20, 2002
Doing Carbon things in Cocoa

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.

 Posted by rosyna at 01:23 AM | Comments (6)
Related:
Comments

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 AM

This code works on both 10.1 and 10.2

Posted by: Rosyna on October 21, 2002 2:43 AM

I 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 PM

Email fixed, sorry.

Posted by: Eric Bailey on May 29, 2004 7:54 AM

Hi,

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 AM

Frontmost 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 PM
Post a comment
Keep comments on topic. If a comment is unrelated to this post, it may be removed or moderated.





Remember Me?

(you may use HTML tags for style)