vlc | branch: master | Marvin Scholz <[email protected]> | Thu Aug 2 00:48:38 2018 +0200| [f70a3de4f035e5e1027786d6247040cc069c5201] | committer: Marvin Scholz
macosx: SPMediaKeyTap: Replace long deprecated Carbon APIs > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f70a3de4f035e5e1027786d6247040cc069c5201 --- modules/gui/macosx/Makefile.am | 2 +- modules/gui/macosx/SPMediaKeyTap.h | 1 - modules/gui/macosx/SPMediaKeyTap.m | 127 ++++++++++++++----------------------- 3 files changed, 50 insertions(+), 80 deletions(-) diff --git a/modules/gui/macosx/Makefile.am b/modules/gui/macosx/Makefile.am index 2ce031924a..5f9e53b03a 100644 --- a/modules/gui/macosx/Makefile.am +++ b/modules/gui/macosx/Makefile.am @@ -2,7 +2,7 @@ SUFFIXES += .xib libmacosx_plugin_la_OBJCFLAGS = $(AM_OBJCFLAGS) -fobjc-exceptions -fobjc-arc libmacosx_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(guidir)' \ - -Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,CoreServices \ + -Wl,-framework,Cocoa -Wl,-framework,CoreServices \ -Wl,-framework,AVFoundation -Wl,-framework,CoreMedia -Wl,-framework,IOKit \ -Wl,-framework,AddressBook -Wl,-framework,WebKit -Wl,-framework,CoreAudio \ -Wl,-framework,SystemConfiguration -Wl,-framework,ScriptingBridge \ diff --git a/modules/gui/macosx/SPMediaKeyTap.h b/modules/gui/macosx/SPMediaKeyTap.h index 4e0287c528..fd437a8335 100644 --- a/modules/gui/macosx/SPMediaKeyTap.h +++ b/modules/gui/macosx/SPMediaKeyTap.h @@ -23,7 +23,6 @@ #import <Cocoa/Cocoa.h> #import <IOKit/hidsystem/ev_keymap.h> -#import <Carbon/Carbon.h> // http://overooped.com/post/2593597587/mediakeys diff --git a/modules/gui/macosx/SPMediaKeyTap.m b/modules/gui/macosx/SPMediaKeyTap.m index 0950978c64..fa95fb9e66 100644 --- a/modules/gui/macosx/SPMediaKeyTap.m +++ b/modules/gui/macosx/SPMediaKeyTap.m @@ -25,18 +25,19 @@ #import "SPMediaKeyTap.h" #import "SPInvocationGrabbing.h" +// Define to enable app list debug output +// #define DEBUG_SPMEDIAKEY_APPLIST 1 + NSString *kIgnoreMediaKeysDefaultsKey = @"SPIgnoreMediaKeys"; @interface SPMediaKeyTap () { - EventHandlerRef _app_switching_ref; - EventHandlerRef _app_terminating_ref; CFMachPortRef _eventPort; CFRunLoopSourceRef _eventPortSource; CFRunLoopRef _tapThreadRL; BOOL _shouldInterceptMediaKeyEvents; id _delegate; // The app that is frontmost in this list owns media keys - NSMutableArray *_mediaKeyAppList; + NSMutableArray<NSRunningApplication *> *_mediaKeyAppList; } - (BOOL)shouldInterceptMediaKeyEvents; @@ -46,8 +47,6 @@ NSString *kIgnoreMediaKeysDefaultsKey = @"SPIgnoreMediaKeys"; - (void)eventTapThread; @end -static pascal OSStatus appSwitched (EventHandlerCallRef nextHandler, EventRef evt, void* userData); -static pascal OSStatus appTerminated (EventHandlerCallRef nextHandler, EventRef evt, void* userData); static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon); @@ -79,20 +78,22 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv { // Listen to "app switched" event, so that we don't intercept media keys if we // weren't the last "media key listening" app to be active - EventTypeSpec eventType = { kEventClassApplication, kEventAppFrontSwitched }; - OSStatus err = InstallApplicationEventHandler(NewEventHandlerUPP(appSwitched), 1, &eventType, (__bridge void*)(self), &_app_switching_ref); - assert(err == noErr); - eventType.eventKind = kEventAppTerminated; - err = InstallApplicationEventHandler(NewEventHandlerUPP(appTerminated), 1, &eventType, (__bridge void *)(self), &_app_terminating_ref); - assert(err == noErr); + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self + selector:@selector(frontmostAppChanged:) + name:NSWorkspaceDidActivateApplicationNotification + object:nil]; + + + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self + selector:@selector(appTerminated:) + name:NSWorkspaceDidTerminateApplicationNotification + object:nil]; } - (void)stopWatchingAppSwitching { - if(!_app_switching_ref) return; - RemoveEventHandler(_app_switching_ref); - _app_switching_ref = NULL; + [[[NSWorkspace sharedWorkspace] notificationCenter] removeObserver:self]; } - (BOOL)startWatchingMediaKeys @@ -237,7 +238,7 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv } } -#pragma mark + #pragma mark - #pragma mark Event tap callbacks @@ -300,88 +301,58 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv CFRunLoopRun(); } + +#pragma mark - #pragma mark Task switching callbacks - (void)mediaKeyAppListChanged { - if([_mediaKeyAppList count] == 0) return; - - /*NSLog(@"--"); - int i = 0; - for (NSValue *psnv in _mediaKeyAppList) { - ProcessSerialNumber psn; [psnv getValue:&psn]; - NSDictionary *processInfo = (id)ProcessInformationCopyDictionary( - &psn, - kProcessDictionaryIncludeAllInformationMask - ); - NSString *bundleIdentifier = [processInfo objectForKey:(id)kCFBundleIdentifierKey]; - NSLog(@"%d: %@", i++, bundleIdentifier); - }*/ - - ProcessSerialNumber mySerial, topSerial; - GetCurrentProcess(&mySerial); - [[_mediaKeyAppList firstObject] getValue:&topSerial]; - - Boolean same; - OSErr err = SameProcess(&mySerial, &topSerial, &same); - [self setShouldInterceptMediaKeyEvents:(err == noErr && same)]; -} + #ifdef DEBUG_SPMEDIAKEY_APPLIST + [self debugPrintAppList]; + #endif -- (void)appIsNowFrontmost:(ProcessSerialNumber)psn -{ - NSValue *psnv = [NSValue valueWithBytes:&psn objCType:@encode(ProcessSerialNumber)]; + if([_mediaKeyAppList count] == 0) + return; - NSDictionary *processInfo = (__bridge_transfer NSDictionary *)ProcessInformationCopyDictionary( - &psn, - kProcessDictionaryIncludeAllInformationMask - ); - NSString *bundleIdentifier = [processInfo objectForKey:(id)kCFBundleIdentifierKey]; + NSRunningApplication *thisApp = [NSRunningApplication currentApplication]; + NSRunningApplication *otherApp = [_mediaKeyAppList firstObject]; - if (![[SPMediaKeyTap mediaKeyUserBundleIdentifiers] containsObject:bundleIdentifier]) - return; + BOOL isCurrent = [thisApp isEqual:otherApp]; - [_mediaKeyAppList removeObject:psnv]; - [_mediaKeyAppList insertObject:psnv atIndex:0]; - [self mediaKeyAppListChanged]; + [self setShouldInterceptMediaKeyEvents:isCurrent]; } -- (void)appTerminated:(ProcessSerialNumber)psn +- (void)frontmostAppChanged:(NSNotification *)notification { - NSValue *psnv = [NSValue valueWithBytes:&psn objCType:@encode(ProcessSerialNumber)]; - [_mediaKeyAppList removeObject:psnv]; + NSRunningApplication *app = [notification.userInfo objectForKey:NSWorkspaceApplicationKey]; + if (app.bundleIdentifier == nil) + return; + + if (![[SPMediaKeyTap mediaKeyUserBundleIdentifiers] containsObject:app.bundleIdentifier]) + return; + + [_mediaKeyAppList removeObject:app]; + [_mediaKeyAppList insertObject:app atIndex:0]; [self mediaKeyAppListChanged]; } -static pascal OSStatus appSwitched (EventHandlerCallRef nextHandler, EventRef evt, void* userData) +- (void)appTerminated:(NSNotification *)notification { - SPMediaKeyTap *self = (__bridge id)userData; + NSRunningApplication *app = [notification.userInfo objectForKey:NSWorkspaceApplicationKey]; + [_mediaKeyAppList removeObject:app]; - ProcessSerialNumber newSerial; - GetFrontProcess(&newSerial); - - [self appIsNowFrontmost:newSerial]; - - return CallNextEventHandler(nextHandler, evt); + [self mediaKeyAppListChanged]; } -static pascal OSStatus appTerminated (EventHandlerCallRef nextHandler, EventRef evt, void* userData) +#ifdef DEBUG_SPMEDIAKEY_APPLIST +- (void)debugPrintAppList { - SPMediaKeyTap *self = (__bridge id)userData; - - ProcessSerialNumber deadPSN; - - GetEventParameter( - evt, - kEventParamProcessID, - typeProcessSerialNumber, - NULL, - sizeof(deadPSN), - NULL, - &deadPSN - ); - - [self appTerminated:deadPSN]; - return CallNextEventHandler(nextHandler, evt); + NSMutableString *list = [NSMutableString stringWithCapacity:255]; + for (NSRunningApplication *app in _mediaKeyAppList) { + [list appendFormat:@" - %@\n", app.bundleIdentifier]; + } + NSLog(@"List: \n%@", list); } +#endif @end _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
