I do this by subclassing NSApplication (and setting this class as the application class in my target information) with the following:
#import <IOKit/hidsystem/ev_keymap.h>
...
- (void)mediaKeyEvent:(int)key state:(BOOL)state { switch (key) { // Play pressed case NX_KEYTYPE_PLAY: if (state == NO) [(TSAppController *)[self delegate] togglePlayPause:self]; break; // FF pressed case NX_KEYTYPE_FAST: if (state == YES) [(TSAppController *)[self delegate] seekForward:self]; break; // RW pressed case NX_KEYTYPE_REWIND: if (state == YES) [(TSAppController *)[self delegate] seekBack:self]; break; } } - (void)sendEvent:(NSEvent *)event { // Catch media key events if ([event type] == NSSystemDefined && [event subtype] == NX_SUBTYPE_AUX_CONTROL_BUTTONS) { int keyCode = (([event data1] & 0xFFFF0000) >> 16); int keyFlags = ([event data1] & 0x0000FFFF); int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA; // Process the media key event and return [self mediaKeyEvent:keyCode state:keyState]; return; } // Continue on to super [super sendEvent:event]; }
"State" in -mediaKeyEvent: state: for up / down. In my application, it makes sense to respond only to the play / pause button when it is backed up (pressing it), but I constantly respond to RW / FF events until the key works for searching.
I would like to know how best to do this if it exists. Currently, if the user does not disable these keys in global keyboard shortcuts, he controls my application and iTunes .:-)
This code has been used for quite some time in my transcription application and works well (besides the global keyboard problem above).
Joshua nozzi
source share