Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listening to mac keyboard play/pause events

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?

like image 786
Alex MacCaw Avatar asked Mar 19 '10 12:03

Alex MacCaw


1 Answers

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).

like image 62
Joshua Nozzi Avatar answered Oct 24 '22 01:10

Joshua Nozzi