Some mac apps, like iTunes and Spotify, react to the play/pause/next/previous buttons on some Apple keyboards.
Presumably they're tapping into some sort of NSNotification, how can I do the same?
I do this by subclassing NSApplication (and setting that class as the application class in my target's info) 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];
}
The "state" in -mediaKeyEvent:state: is for up/down. In my app it makes sense to only react to the play/pause key when it's back up (done pressing), but I continuously react to RW/FF events while the key is down for seeking.
I'd love to know of a better way to do this if it exists, though. Currently, unless the user disables these keys in the global keyboard shortcuts, it controls my app and iTunes. :-)
This code has been used quite awhile in my transcription app and works well (aside from the global keyboard shortcut issue above).
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