Add support for global media keys on mac (Cocoa only).

Updates issue #6
This commit is contained in:
John Maguire 2010-04-13 13:55:54 +00:00
parent c59c7ee0ec
commit a4405e7877
6 changed files with 125 additions and 1 deletions

View File

@ -181,7 +181,7 @@ set(CLEMENTINE-LANGUAGES
# OSD and DBus.
if(APPLE)
set(CLEMENTINE-SOURCES ${CLEMENTINE-SOURCES} osd_mac.mm)
set(CLEMENTINE-SOURCES ${CLEMENTINE-SOURCES} osd_mac.mm mac_startup.mm)
else(APPLE)
if(WIN32)
set(CLEMENTINE-SOURCES ${CLEMENTINE-SOURCES} osd_win.cpp)
@ -318,6 +318,7 @@ if (APPLE)
${GROWL}
/System/Library/Frameworks/Carbon.framework
/System/Library/Frameworks/Foundation.framework
/System/Library/Frameworks/AppKit.framework
)
include_directories(${GROWL}/Headers)
endif (APPLE)

View File

@ -17,6 +17,8 @@
#include "globalshortcuts.h"
#include "qxtglobalshortcut.h"
#include "mac_startup.h"
#include <QtDebug>
#ifdef QT_DBUS_LIB
@ -34,6 +36,10 @@ GlobalShortcuts::GlobalShortcuts(QObject *parent)
}
void GlobalShortcuts::Init() {
#ifdef Q_OS_DARWIN
mac::SetShortcutHandler(this);
return;
#endif
if (RegisterGnome()) return;
if (RegisterQxt()) return;
}
@ -78,3 +84,10 @@ void GlobalShortcuts::GnomeMediaKeyPressed(const QString&, const QString& key) {
if (key == "Next") emit Next();
if (key == "Previous") emit Previous();
}
void GlobalShortcuts::MacMediaKeyPressed(const QString& key) {
if (key == "Play") emit PlayPause();
// Stop doesn't exist on a mac keyboard.
if (key == "Next") emit Next();
if (key == "Previous") emit Previous();
}

View File

@ -29,6 +29,8 @@ public:
static const char* kGsdPath;
static const char* kGsdInterface;
void MacMediaKeyPressed(const QString& key);
signals:
void PlayPause();
void Stop();

13
src/mac_startup.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef MAC_STARTUP_H
#define MAC_STARTUP_H
class GlobalShortcuts;
namespace mac {
void MacMain();
void SetShortcutHandler(GlobalShortcuts* handler);
} // namespace mac
#endif

87
src/mac_startup.mm Normal file
View File

@ -0,0 +1,87 @@
#import <IOKit/hidsystem/ev_keymap.h>
#import <AppKit/NSApplication.h>
#import <AppKit/NSEvent.h>
#include "globalshortcuts/globalshortcuts.h"
#include "mac_startup.h"
// Capture global media keys on Mac (Cocoa only!)
// See: http://www.rogueamoeba.com/utm/2007/09/29/apple-keyboard-media-key-event-handling/
@interface MacApplication :NSApplication {
GlobalShortcuts* handler_;
}
- (GlobalShortcuts*) handler;
- (void) SetHandler: (GlobalShortcuts*)handler;
-(void) mediaKeyEvent: (int)key state: (BOOL)state repeat: (BOOL)repeat;
@end
@implementation MacApplication
- (id) init {
if ((self = [super init])) {
[self SetHandler:nil];
}
return self;
}
- (GlobalShortcuts*) handler {
return handler_;
}
- (void) SetHandler: (GlobalShortcuts*)handler {
handler_ = handler;
}
-(void) sendEvent: (NSEvent*)event {
if ([event type] == NSSystemDefined && [event subtype] == 8) {
int keycode = (([event data1] & 0xFFFF0000) >> 16);
int keyflags = ([event data1] & 0x0000FFFF);
int keystate = (((keyflags & 0xFF00) >> 8)) == 0xA;
int keyrepeat = (keyflags & 0x1);
[self mediaKeyEvent: keycode state: keystate repeat: keyrepeat];
}
[super sendEvent: event];
}
-(void) mediaKeyEvent: (int)key state: (BOOL)state repeat: (BOOL)repeat {
if (!handler_) {
return;
}
if (state == 0) {
switch (key) {
case NX_KEYTYPE_PLAY:
// Play pressed.
handler_->MacMediaKeyPressed("Play");
break;
case NX_KEYTYPE_FAST:
// Next pressed.
handler_->MacMediaKeyPressed("Next");
break;
case NX_KEYTYPE_REWIND:
handler_->MacMediaKeyPressed("Previous");
break;
default:
break;
}
}
}
@end
namespace mac {
void MacMain() {
// Creates and sets the magic global variable so QApplication will find it.
[MacApplication sharedApplication];
}
void SetShortcutHandler(GlobalShortcuts* handler) {
[NSApp SetHandler: handler];
}
} // namespace mac

View File

@ -43,6 +43,8 @@
# include "osd.h"
#endif
#include "mac_startup.h"
// Load sqlite plugin on windows
#ifdef WIN32
# include <QtPlugin>
@ -67,6 +69,12 @@ void LoadTranslation(const QString& prefix, const QString& path) {
}
int main(int argc, char *argv[]) {
#ifdef Q_OS_DARWIN
// Do Mac specific startup to get media keys working.
// This must go before QApplication initialisation.
mac::MacMain();
#endif
QCoreApplication::setApplicationName("Clementine");
QCoreApplication::setApplicationVersion("0.2");
QCoreApplication::setOrganizationName("Clementine");