[vlc-devel] [VLC 3.x v2 11/11] macosx: SPMediaKeyTap: Move event parsing to library

Marvin Scholz epirat07 at gmail.com
Fri Apr 23 01:19:38 UTC 2021


Instead of doing the event parsing in VLCCoreInteraction, do it
in the library. That way the VLC code does not get cluttered with
details how to parse the event and everything is properly dealt with
by the SPMediaKeyTap class.
---
 modules/gui/macosx/SPMediaKeyTap.h      | 31 ++++++++++----
 modules/gui/macosx/SPMediaKeyTap.m      | 21 ++++++++--
 modules/gui/macosx/VLCCoreInteraction.m | 56 +++++++++++--------------
 3 files changed, 64 insertions(+), 44 deletions(-)

diff --git a/modules/gui/macosx/SPMediaKeyTap.h b/modules/gui/macosx/SPMediaKeyTap.h
index fc28bf0d57..49076c75b7 100644
--- a/modules/gui/macosx/SPMediaKeyTap.h
+++ b/modules/gui/macosx/SPMediaKeyTap.h
@@ -25,18 +25,31 @@
 #import <IOKit/hidsystem/ev_keymap.h>
 #import <IOKit/hidsystem/IOLLEvent.h>
 
-// http://overooped.com/post/2593597587/mediakeys
-
-#define SPSystemDefinedEventMediaKeys NX_SUBTYPE_AUX_CONTROL_BUTTONS
+typedef NS_ENUM(uint8_t, SPKeyCode) {
+    SPKeyCodePlay           = NX_KEYTYPE_PLAY,
+    SPKeyCodeNext           = NX_KEYTYPE_NEXT,
+    SPKeyCodePrevious       = NX_KEYTYPE_PREVIOUS,
+    SPKeyCodeFastForward    = NX_KEYTYPE_FAST,
+    SPKeyCodeRewind         = NX_KEYTYPE_REWIND
+};
+
+typedef NS_ENUM(uint8_t, SPKeyState) {
+    SPKeyStateDown  = NX_KEYDOWN,
+    SPKeyStateUp    = NX_KEYUP
+};
+
+ at class SPMediaKeyTap;
+
+ at protocol SPMediaKeyTapDelegate <NSObject>
+- (void)mediaKeyTap:(SPMediaKeyTap *)keyTap
+   receivedMediaKey:(SPKeyCode)keyCode
+              state:(SPKeyState)keyState
+             repeat:(BOOL)isRepeat;
+ at end
 
 @interface SPMediaKeyTap : NSObject
-
-- (id)initWithDelegate:(id)delegate;
+- (id)initWithDelegate:(id<SPMediaKeyTapDelegate>)delegate;
 
 - (BOOL)startWatchingMediaKeys;
 - (void)stopWatchingMediaKeys;
 @end
-
- at interface NSObject (SPMediaKeyTapDelegate)
-- (void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event;
- at end
diff --git a/modules/gui/macosx/SPMediaKeyTap.m b/modules/gui/macosx/SPMediaKeyTap.m
index 67686de132..bf18e5bb68 100644
--- a/modules/gui/macosx/SPMediaKeyTap.m
+++ b/modules/gui/macosx/SPMediaKeyTap.m
@@ -30,7 +30,7 @@
 @interface SPMediaKeyTap () {
     CFMachPortRef _eventPort;
     CFRunLoopSourceRef _eventPortSource;
-    id _delegate;
+    __weak id<SPMediaKeyTapDelegate> _delegate;
     // The app that is frontmost in this list owns media keys
     NSMutableArray<NSRunningApplication *> *_mediaKeyAppList;
 }
@@ -51,10 +51,12 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
 #pragma mark -
 #pragma mark Setup and teardown
 
-- (id)initWithDelegate:(id)delegate
+- (id)initWithDelegate:(id<SPMediaKeyTapDelegate>)delegate
 {
     self = [super init];
     if (self) {
+        NSAssert([delegate conformsToProtocol:@protocol(SPMediaKeyTapDelegate)],
+            @"SPMediaKeyTap delegate must conform to the SPMediaKeyTapDelegate protocol!");
         _delegate = delegate;
         [self startWatchingAppSwitching];
         _mediaKeyAppList = [NSMutableArray new];
@@ -233,7 +235,7 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
             return event;
         }
 
-        if ([nsEvent subtype] != SPSystemDefinedEventMediaKeys)
+        if ([nsEvent subtype] != NX_SUBTYPE_AUX_CONTROL_BUTTONS)
             return event;
 
         int keyCode = (([nsEvent data1] & 0xFFFF0000) >> 16);
@@ -252,7 +254,18 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
 
 - (void)handleAndReleaseMediaKeyEvent:(NSEvent *)event
 {
-    [_delegate mediaKeyTap:self receivedMediaKeyEvent:event];
+    uint32_t eventData  = [event data1];
+
+    SPKeyCode keyCode   = ((eventData & 0xFFFF0000) >> 16);
+    uint16_t eventFlags = ((eventData & 0x0000FFFF));
+
+    SPKeyState keyState = ((eventFlags & 0xFF00) >> 8);
+    BOOL keyRepeat      =  (eventFlags & 0x1);
+
+    [_delegate mediaKeyTap:self
+          receivedMediaKey:keyCode
+                     state:keyState
+                    repeat:keyRepeat];
 }
 
 
diff --git a/modules/gui/macosx/VLCCoreInteraction.m b/modules/gui/macosx/VLCCoreInteraction.m
index 62a88159aa..5afd889739 100644
--- a/modules/gui/macosx/VLCCoreInteraction.m
+++ b/modules/gui/macosx/VLCCoreInteraction.m
@@ -56,7 +56,7 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
     }
 }
 
- at interface VLCCoreInteraction ()
+ at interface VLCCoreInteraction () <SPMediaKeyTapDelegate>
 {
     int i_currentPlaybackRate;
     mtime_t timeA, timeB;
@@ -896,41 +896,35 @@ static int BossCallback(vlc_object_t *p_this, const char *psz_var,
     }
 }
 
--(void)mediaKeyTap:(SPMediaKeyTap*)keyTap receivedMediaKeyEvent:(NSEvent*)event
+- (void)mediaKeyTap:(SPMediaKeyTap *)keyTap
+   receivedMediaKey:(SPKeyCode)keyCode
+              state:(SPKeyState)keyState
+             repeat:(BOOL)isRepeat
 {
-    if (b_mediaKeySupport) {
-        assert([event type] == NSSystemDefined && [event subtype] == SPSystemDefinedEventMediaKeys);
-
-        int keyCode = (([event data1] & 0xFFFF0000) >> 16);
-        int keyFlags = ([event data1] & 0x0000FFFF);
-        int keyState = (((keyFlags & 0xFF00) >> 8)) == 0xA;
-        int keyRepeat = (keyFlags & 0x1);
-
-        if (keyCode == NX_KEYTYPE_PLAY && keyState == 0)
+    if (keyCode == SPKeyCodePlay && keyState == SPKeyStateUp)
             [self playOrPause];
 
-        if ((keyCode == NX_KEYTYPE_FAST || keyCode == NX_KEYTYPE_NEXT) && !b_mediakeyJustJumped) {
-            if (keyState == 0 && keyRepeat == 0)
-                [self next];
-            else if (keyRepeat == 1) {
-                [self forwardShort];
-                b_mediakeyJustJumped = YES;
-                [self performSelector:@selector(resetMediaKeyJump)
-                           withObject: NULL
-                           afterDelay:0.25];
-            }
+    if ((keyCode == SPKeyCodeFastForward || keyCode == SPKeyCodeNext) && !b_mediakeyJustJumped) {
+        if (keyState == SPKeyStateUp && !isRepeat)
+            [self next];
+        else if (isRepeat) {
+            [self forwardShort];
+            b_mediakeyJustJumped = YES;
+            [self performSelector:@selector(resetMediaKeyJump)
+                       withObject: NULL
+                       afterDelay:0.25];
         }
+    }
 
-        if ((keyCode == NX_KEYTYPE_REWIND || keyCode == NX_KEYTYPE_PREVIOUS) && !b_mediakeyJustJumped) {
-            if (keyState == 0 && keyRepeat == 0)
-                [self previous];
-            else if (keyRepeat == 1) {
-                [self backwardShort];
-                b_mediakeyJustJumped = YES;
-                [self performSelector:@selector(resetMediaKeyJump)
-                           withObject: NULL
-                           afterDelay:0.25];
-            }
+    if ((keyCode == SPKeyCodeRewind || keyCode == SPKeyCodePrevious) && !b_mediakeyJustJumped) {
+        if (keyState == SPKeyStateUp && !isRepeat)
+            [self previous];
+        else if (isRepeat) {
+            [self backwardShort];
+            b_mediakeyJustJumped = YES;
+            [self performSelector:@selector(resetMediaKeyJump)
+                       withObject: NULL
+                       afterDelay:0.25];
         }
     }
 }
-- 
2.30.1



More information about the vlc-devel mailing list