Commit c6aa5ac9 authored by Felix Paul Kühne's avatar Felix Paul Kühne

macosx: update SPMediaKeyTap to latest code from upstream (refs #6613)

parent 9b56e18b
...@@ -18,24 +18,15 @@ ...@@ -18,24 +18,15 @@
#define SPSystemDefinedEventMediaKeys 8 #define SPSystemDefinedEventMediaKeys 8
@interface SPMediaKeyTap : NSObject { @interface SPMediaKeyTap : NSObject {
EventHandlerRef _app_switching_ref;
EventHandlerRef _app_switching_ref; EventHandlerRef _app_terminating_ref;
CFMachPortRef _eventPort;
EventHandlerRef _app_terminating_ref; CFRunLoopSourceRef _eventPortSource;
CFRunLoopRef _tapThreadRL;
CFMachPortRef _eventPort; BOOL _shouldInterceptMediaKeyEvents;
id _delegate;
CFRunLoopSourceRef _eventPortSource; // The app that is frontmost in this list owns media keys
NSMutableArray *_mediaKeyAppList;
CFRunLoopRef _tapThreadRL;
BOOL _shouldInterceptMediaKeyEvents;
id _delegate;
// The app that is frontmost in this list owns media keys
NSMutableArray *_mediaKeyAppList;
} }
+ (NSArray*)defaultMediaKeyUserBundleIdentifiers; + (NSArray*)defaultMediaKeyUserBundleIdentifiers;
...@@ -45,11 +36,19 @@ NSMutableArray *_mediaKeyAppList; ...@@ -45,11 +36,19 @@ NSMutableArray *_mediaKeyAppList;
-(void)startWatchingMediaKeys; -(void)startWatchingMediaKeys;
-(void)stopWatchingMediaKeys; -(void)stopWatchingMediaKeys;
-(void)handleAndReleaseMediaKeyEvent:(NSEvent *)event; -(void)handleAndReleaseMediaKeyEvent:(NSEvent *)event;
-(void)setShouldInterceptMediaKeyEvents:(BOOL)newSetting;
@end @end
@interface NSObject (SPMediaKeyTapDelegate) @interface NSObject (SPMediaKeyTapDelegate)
-(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event; -(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event;
@end @end
#ifdef __cplusplus
extern "C" {
#endif
extern NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey; extern NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey;
extern NSString *kIgnoreMediaKeysDefaultsKey;
#ifdef __cplusplus
}
#endif
...@@ -11,10 +11,11 @@ ...@@ -11,10 +11,11 @@
// Copyright (c) 2010 Spotify AB // Copyright (c) 2010 Spotify AB
#import "SPMediaKeyTap.h" #import "SPMediaKeyTap.h"
#import "SPInvocationGrabbing.h" // https://gist.github.com/511181 #import "SPInvocationGrabbing.h"
@interface SPMediaKeyTap () @interface SPMediaKeyTap ()
-(BOOL)shouldInterceptMediaKeyEvents; -(BOOL)shouldInterceptMediaKeyEvents;
-(void)setShouldInterceptMediaKeyEvents:(BOOL)newSetting;
-(void)startWatchingAppSwitching; -(void)startWatchingAppSwitching;
-(void)stopWatchingAppSwitching; -(void)stopWatchingAppSwitching;
-(void)eventTapThread; -(void)eventTapThread;
...@@ -38,6 +39,9 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv ...@@ -38,6 +39,9 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
[self startWatchingAppSwitching]; [self startWatchingAppSwitching];
singleton = self; singleton = self;
_mediaKeyAppList = [NSMutableArray new]; _mediaKeyAppList = [NSMutableArray new];
_tapThreadRL=nil;
_eventPort=nil;
_eventPortSource=nil;
return self; return self;
} }
-(void)dealloc; -(void)dealloc;
...@@ -68,6 +72,9 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv ...@@ -68,6 +72,9 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
} }
-(void)startWatchingMediaKeys;{ -(void)startWatchingMediaKeys;{
// Prevent having multiple mediaKeys threads
[self stopWatchingMediaKeys];
[self setShouldInterceptMediaKeyEvents:YES]; [self setShouldInterceptMediaKeyEvents:YES];
// Add an event tap to intercept the system defined media key events // Add an event tap to intercept the system defined media key events
...@@ -88,6 +95,22 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv ...@@ -88,6 +95,22 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
-(void)stopWatchingMediaKeys; -(void)stopWatchingMediaKeys;
{ {
// TODO<nevyn>: Shut down thread, remove event tap port and source // TODO<nevyn>: Shut down thread, remove event tap port and source
if(_tapThreadRL){
CFRunLoopStop(_tapThreadRL);
_tapThreadRL=nil;
}
if(_eventPort){
CFMachPortInvalidate(_eventPort);
CFRelease(_eventPort);
_eventPort=nil;
}
if(_eventPortSource){
CFRelease(_eventPortSource);
_eventPortSource=nil;
}
} }
#pragma mark - #pragma mark -
...@@ -95,18 +118,21 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv ...@@ -95,18 +118,21 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
+(BOOL)usesGlobalMediaKeyTap +(BOOL)usesGlobalMediaKeyTap
{ {
return YES;
#ifdef _DEBUG #ifdef _DEBUG
// breaking in gdb with a key tap inserted sometimes locks up all mouse and keyboard input forever, forcing reboot
return NO; return NO;
#else #else
// XXX(nevyn): MediaKey event tap doesn't work on 10.4, feel free to figure out why if you have the energy. // XXX(nevyn): MediaKey event tap doesn't work on 10.4, feel free to figure out why if you have the energy.
return floor(NSAppKitVersionNumber) >= 949/*NSAppKitVersionNumber10_5*/; return
![[NSUserDefaults standardUserDefaults] boolForKey:kIgnoreMediaKeysDefaultsKey]
&& floor(NSAppKitVersionNumber) >= 949/*NSAppKitVersionNumber10_5*/;
#endif #endif
} }
+ (NSArray*)defaultMediaKeyUserBundleIdentifiers; + (NSArray*)defaultMediaKeyUserBundleIdentifiers;
{ {
return [NSArray arrayWithObjects: return [NSArray arrayWithObjects:
[[NSBundle mainBundle] bundleIdentifier], // your app
@"com.spotify.client", @"com.spotify.client",
@"com.apple.iTunes", @"com.apple.iTunes",
@"com.apple.QuickTimePlayerX", @"com.apple.QuickTimePlayerX",
...@@ -117,6 +143,14 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv ...@@ -117,6 +143,14 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
@"com.apple.Aperture", @"com.apple.Aperture",
@"com.plexsquared.Plex", @"com.plexsquared.Plex",
@"com.soundcloud.desktop", @"com.soundcloud.desktop",
@"org.niltsh.MPlayerX",
@"com.ilabs.PandorasHelper",
@"com.mahasoftware.pandabar",
@"com.bitcartel.pandorajam",
@"org.clementine-player.clementine",
@"fm.last.Last.fm",
@"com.beatport.BeatportPro",
@"com.Timenut.SongKey",
@"com.macromedia.fireworks", // the tap messes up their mouse input @"com.macromedia.fireworks", // the tap messes up their mouse input
nil nil
]; ];
...@@ -222,6 +256,8 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv ...@@ -222,6 +256,8 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
#pragma mark Task switching callbacks #pragma mark Task switching callbacks
NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey = @"SPApplicationsNeedingMediaKeys"; NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey = @"SPApplicationsNeedingMediaKeys";
NSString *kIgnoreMediaKeysDefaultsKey = @"SPIgnoreMediaKeys";
-(void)mediaKeyAppListChanged; -(void)mediaKeyAppListChanged;
...@@ -247,7 +283,6 @@ NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey = @"SPApplicationsNeedingMe ...@@ -247,7 +283,6 @@ NSString *kMediaKeyUsingBundleIdentifiersDefaultsKey = @"SPApplicationsNeedingMe
Boolean same; Boolean same;
OSErr err = SameProcess(&mySerial, &topSerial, &same); OSErr err = SameProcess(&mySerial, &topSerial, &same);
[self setShouldInterceptMediaKeyEvents:(err == noErr && same)]; [self setShouldInterceptMediaKeyEvents:(err == noErr && same)];
} }
-(void)appIsNowFrontmost:(ProcessSerialNumber)psn; -(void)appIsNowFrontmost:(ProcessSerialNumber)psn;
{ {
...@@ -301,7 +336,6 @@ static pascal OSStatus appTerminated (EventHandlerCallRef nextHandler, EventRef ...@@ -301,7 +336,6 @@ static pascal OSStatus appTerminated (EventHandlerCallRef nextHandler, EventRef
&deadPSN &deadPSN
); );
[self appTerminated:deadPSN]; [self appTerminated:deadPSN];
return CallNextEventHandler(nextHandler, evt); return CallNextEventHandler(nextHandler, evt);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment