From e8a6e1a201f86c9b0946206526cb9ecd85595ea1 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Thu, 6 Jun 2013 21:31:20 +0200 Subject: macosx_events: handle key modifiers with media keys This was overlooked in the previous inplementation. Adding it required some refactoring of the `handleKeyDown:` method in order to extract common parts with `handleMediaKey:`. --- osdep/macosx_application_objc.h | 2 +- osdep/macosx_events.m | 81 ++++++++++++++++++++++++++++------------- 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/osdep/macosx_application_objc.h b/osdep/macosx_application_objc.h index 0a6b70a95d..27c1871dc4 100644 --- a/osdep/macosx_application_objc.h +++ b/osdep/macosx_application_objc.h @@ -28,7 +28,7 @@ struct cocoa_input_queue; @end @interface EventsResponder : NSObject -- (BOOL)handleMediaKey:(int)key; +- (BOOL)handleMediaKey:(NSEvent *)event; - (NSEvent *)handleKeyDown:(NSEvent *)event; - (void)startAppleRemote; - (void)stopAppleRemote; diff --git a/osdep/macosx_events.m b/osdep/macosx_events.m index aff83a866f..ebeb260221 100644 --- a/osdep/macosx_events.m +++ b/osdep/macosx_events.m @@ -104,6 +104,20 @@ void cocoa_uninit_apple_remote(void) [app.eventsResponder stopAppleRemote]; } +static int mk_code(NSEvent *event) +{ + return (([event data1] & 0xFFFF0000) >> 16); +} + +static int mk_flags(NSEvent *event) +{ + return ([event data1] & 0x0000FFFF); +} + +static int mk_down(NSEvent *event) { + return (((mk_flags(event) & 0xFF00) >> 8)) == 0xA; +} + static CGEventRef tap_event_callback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *ctx) { @@ -125,14 +139,7 @@ static CGEventRef tap_event_callback(CGEventTapProxy proxy, CGEventType type, // This is not a media key return event; - // It's a media key! Handle it specially. The magic numbers are reverse - // engineered and found on several blog posts. Unfortunately there is - // no public API for this. F-bomb. - int code = (([nse data1] & 0xFFFF0000) >> 16); - int flags = ([nse data1] & 0x0000FFFF); - int down = (((flags & 0xFF00) >> 8)) == 0xA; - - if (down && [responder handleMediaKey:code]) { + if (mk_down(nse) && [responder handleMediaKey:nse]) { // Handled this event, return nil so that it is removed from the // global queue. return nil; @@ -220,11 +227,23 @@ void cocoa_put_key(int keycode) self->_mk_tap_port = nil; }); } + - (NSArray *) keyEquivalents { return @[@"h", @"q", @"Q", @"0", @"1", @"2"]; } -- (BOOL)handleMediaKey:(int)key + +- (BOOL)isAppKeyEquivalent:(NSString *)eq withEvent:(NSEvent *)event +{ + if ([event modifierFlags] & NSCommandKeyMask) + for(NSString *c in [self keyEquivalents]) + if ([eq isEqualToString:c]) + return YES; + + return NO; +} + +- (BOOL)handleMediaKey:(NSEvent *)event { NSDictionary *keymap = @{ @(NX_KEYTYPE_PLAY): @(MP_MK_PLAY), @@ -232,8 +251,11 @@ void cocoa_put_key(int keycode) @(NX_KEYTYPE_FAST): @(MP_MK_NEXT), }; - return [self handleKey:key withMapping:keymap]; + return [self handleKey:mk_code(event) + withMask:[self keyModifierMask:event] + andMapping:keymap]; } + - (NSEvent*)handleKeyDown:(NSEvent *)event { NSString *chars; @@ -246,26 +268,17 @@ void cocoa_put_key(int keycode) int key = convert_key([event keyCode], *[chars UTF8String]); if (key > -1) { - if ([event modifierFlags] & NSShiftKeyMask) - key |= MP_KEY_MODIFIER_SHIFT; - if ([event modifierFlags] & NSControlKeyMask) - key |= MP_KEY_MODIFIER_CTRL; - if (LeftAltPressed(event)) - key |= MP_KEY_MODIFIER_ALT; - if ([event modifierFlags] & NSCommandKeyMask) { + if ([self isAppKeyEquivalent:chars withEvent:event]) // propagate the event in case this is a menu key equivalent - for(NSString *c in [self keyEquivalents]) - if ([chars isEqualToString:c]) - return event; - - key |= MP_KEY_MODIFIER_META; - } + return event; + key |= [self keyModifierMask:event]; cocoa_put_key(key); } return nil; } + - (void)hidRemote:(HIDRemote *)remote eventWithButton:(HIDRemoteButtonCode)buttonCode isPressed:(BOOL)isPressed @@ -290,13 +303,29 @@ void cocoa_put_key(int keycode) @(kHIDRemoteButtonCodeDownHold): @(MP_AR_VDOWN_HOLD), }; - [self handleKey:buttonCode withMapping:keymap]; + [self handleKey:buttonCode withMask:0 andMapping:keymap]; } --(BOOL)handleKey:(int)key withMapping:(NSDictionary *)mapping + +- (int)keyModifierMask:(NSEvent *)event +{ + int mask = 0; + if ([event modifierFlags] & NSShiftKeyMask) + mask |= MP_KEY_MODIFIER_SHIFT; + if ([event modifierFlags] & NSControlKeyMask) + mask |= MP_KEY_MODIFIER_CTRL; + if (LeftAltPressed(event)) + mask |= MP_KEY_MODIFIER_ALT; + if ([event modifierFlags] & NSCommandKeyMask) + mask |= MP_KEY_MODIFIER_META; + + return mask; +} + +-(BOOL)handleKey:(int)key withMask:(int)mask andMapping:(NSDictionary *)mapping { int mpkey = [mapping[@(key)] intValue]; if (mpkey > 0) { - cocoa_put_key(mpkey); + cocoa_put_key(mpkey | mask); return YES; } else { return NO; -- cgit v1.2.3