views:

59

answers:

2

Is there a way to make my app respond to the play/pause button on Mac?

EDIT:

Using the suggested code,I get this console message:

Could not connect the action buttonPressed: to target of class NSApplication

Why would that be?

+1  A: 

Here's a great article on the subject: http://www.rogueamoeba.com/utm/2007/09/29/

cobbal
+2  A: 

I accomplished this in my own application by subclassing NSApplication (and setting the app's principal class to this subclass). It catches seek and play/pause keys and translates them to specific actions in my app delegate.

Relevant lines:

#import <IOKit/hidsystem/ev_keymap.h>

- (void)sendEvent:(NSEvent *)event
{
    // Catch media key events
    if ([event type] == NSSystemDefined && [event subtype] == 8)
    {
        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];
}

- (void)mediaKeyEvent:(int)key state:(BOOL)state
{
    switch (key)
    {
        // Play pressed
        case NX_KEYTYPE_PLAY:
            if (state == NO)
                [(TSAppController *)[self delegate] togglePlayPause:self];
            break;

        // Rewind
        case NX_KEYTYPE_FAST:
            if (state == YES)
                [(TSAppController *)[self delegate] seekForward:self];
            break;

        // Previous
        case NX_KEYTYPE_REWIND:
            if (state == YES)
                [(TSAppController *)[self delegate] seekBack:self];
            break;
    }
}
Joshua Nozzi
I'm getting this weird console message. Any clue why? Also, I'm streaming music and I just want it to catch the play/pause button. Volume can be done on the regular OS X GUI.
Moshe
What weird console message? Also, if you want to catch only play/pause, then only respond to NX_KEYTYPE_PLAY (remove the other cases).
Joshua Nozzi
@Joshua Nozzi - see my edit.
Moshe
@Joshua Nozzi - Actually, it has to do with something else. Thanks for the code. +1
Moshe
Actually, neither worked yet...
Moshe
What's the specific issue you're having? I've implemented this in a shipping app that's been out a few years now.
Joshua Nozzi
@Joshua - I'me having problems "overriding" parts of my app. I'll look into it a bit more. This code seems to work, my placement of it doesn't.
Moshe
Subclass NSApplication, put this code in it. In your target's info, set the principal class to the name of your NSApplication subclass. Done. See the screenshot I posted here: http://jnozzi.me/mediakeys
Joshua Nozzi