[vlc-commits] macosx: SPMediaKeyTap: Replace long deprecated Carbon APIs

Marvin Scholz git at videolan.org
Fri Aug 3 01:45:57 CEST 2018


vlc/vlc-3.0 | branch: master | Marvin Scholz <epirat07 at gmail.com> | Thu Aug  2 00:48:38 2018 +0200| [dd10c2999f1f1b0ceed238960d3413a4665f1e6a] | committer: Felix Paul Kühne

macosx: SPMediaKeyTap: Replace long deprecated Carbon APIs

(cherry picked from commit f70a3de4f035e5e1027786d6247040cc069c5201)
Signed-off-by: Felix Paul Kühne <felix at feepk.net>

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=dd10c2999f1f1b0ceed238960d3413a4665f1e6a
---

 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 865f67590c..59726e8d26 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



More information about the vlc-commits mailing list