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:`.
This commit is contained in:
Stefano Pigozzi 2013-06-06 21:31:20 +02:00
parent 6619905902
commit e8a6e1a201
2 changed files with 56 additions and 27 deletions

View File

@ -28,7 +28,7 @@ struct cocoa_input_queue;
@end
@interface EventsResponder : NSObject <HIDRemoteDelegate>
- (BOOL)handleMediaKey:(int)key;
- (BOOL)handleMediaKey:(NSEvent *)event;
- (NSEvent *)handleKeyDown:(NSEvent *)event;
- (void)startAppleRemote;
- (void)stopAppleRemote;

View File

@ -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;