Skip to content

Commit adf1076

Browse files
committed
SRAXGlobalShortcutMonitor: Avoid using NSEvent from the CGEventTap handler
NSEvent seems to depend on being used from the main thread, which is unncessary limiting for the monitor. Refs #129
1 parent 168e409 commit adf1076

File tree

3 files changed

+65
-26
lines changed

3 files changed

+65
-26
lines changed

Library/SRCommon.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ NS_SWIFT_NAME(CarbonModifierFlagsMask)
2424
static const UInt32 SRCarbonModifierFlagsMask = cmdKey | optionKey | shiftKey | controlKey;
2525

2626

27+
NS_SWIFT_NAME(CoreGraphicsModifierFlagsMask)
28+
static const CGEventFlags SRCoreGraphicsModifierFlagsMask = kCGEventFlagMaskCommand | kCGEventFlagMaskAlternate | kCGEventFlagMaskShift | kCGEventFlagMaskControl;
29+
2730
/*!
2831
Dawable unicode characters for key codes that do not have appropriate constants in Carbon and Cocoa.
2932
@@ -301,6 +304,26 @@ NS_INLINE UInt32 SRCocoaToCarbonFlags(NSEventModifierFlags aCocoaFlags)
301304
return carbonFlags;
302305
}
303306

307+
NS_SWIFT_NAME(coreGraphicsToCocoaFlags(_:))
308+
NS_INLINE NSEventModifierFlags SRCoreGraphicsToCocoaFlags(CGEventFlags aCoreGraphicsFlags)
309+
{
310+
NSEventModifierFlags cocoaFlags = 0;
311+
312+
if (aCoreGraphicsFlags & kCGEventFlagMaskCommand)
313+
cocoaFlags |= NSEventModifierFlagCommand;
314+
315+
if (aCoreGraphicsFlags & kCGEventFlagMaskAlternate)
316+
cocoaFlags |= NSEventModifierFlagOption;
317+
318+
if (aCoreGraphicsFlags & kCGEventFlagMaskControl)
319+
cocoaFlags |= NSEventModifierFlagControl;
320+
321+
if (aCoreGraphicsFlags & kCGEventFlagMaskShift)
322+
cocoaFlags |= NSEventModifierFlagShift;
323+
324+
return cocoaFlags;
325+
}
326+
304327

305328
/*!
306329
Return Bundle where resources can be found.

Library/SRShortcutAction.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ typedef NS_CLOSED_ENUM(NSUInteger, SRKeyEventType)
198198

199199
@interface NSEvent (SRShortcutAction)
200200

201+
+ (SRKeyEventType)SR_keyEventTypeForEventType:(NSEventType)anEventType
202+
keyCode:(unsigned short)aKeyCode
203+
modifierFlags:(NSEventModifierFlags)aModifierFlags;
204+
201205
/*!
202206
Keyboard event type as recognized by the shortcut recorder.
203207

Library/SRShortcutAction.m

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -368,11 +368,13 @@ - (void)observeValueForKeyPath:(NSString *)aKeyPath
368368

369369
@implementation NSEvent (SRShortcutAction)
370370

371-
- (SRKeyEventType)SR_keyEventType
371+
+ (SRKeyEventType)SR_keyEventTypeForEventType:(NSEventType)anEventType
372+
keyCode:(unsigned short)aKeyCode
373+
modifierFlags:(NSEventModifierFlags)aModifierFlags
372374
{
373375
SRKeyEventType eventType = SRKeyEventTypeDown;
374376

375-
switch (self.type)
377+
switch (anEventType)
376378
{
377379
case NSEventTypeKeyDown:
378380
eventType = SRKeyEventTypeDown;
@@ -382,8 +384,8 @@ - (SRKeyEventType)SR_keyEventType
382384
break;
383385
case NSEventTypeFlagsChanged:
384386
{
385-
__auto_type keyCode = self.keyCode;
386-
__auto_type modifierFlags = self.modifierFlags;
387+
__auto_type keyCode = aKeyCode;
388+
__auto_type modifierFlags = aModifierFlags;
387389

388390
if (keyCode == kVK_Command || keyCode == kVK_RightCommand)
389391
eventType = modifierFlags & NSEventModifierFlagCommand ? SRKeyEventTypeDown : SRKeyEventTypeUp;
@@ -398,13 +400,18 @@ - (SRKeyEventType)SR_keyEventType
398400
break;
399401
}
400402
default:
401-
[NSException raise:NSInternalInconsistencyException format:@"Expected a key event, got %lu", self.type];
403+
[NSException raise:NSInternalInconsistencyException format:@"Expected a key event, got %lu", anEventType];
402404
break;
403405
}
404406

405407
return eventType;
406408
}
407409

410+
- (SRKeyEventType)SR_keyEventType
411+
{
412+
return [self.class SR_keyEventTypeForEventType:self.type keyCode:self.keyCode modifierFlags:self.modifierFlags];
413+
}
414+
408415
@end
409416

410417

@@ -1342,25 +1349,34 @@ - (CGEventRef)handleEvent:(CGEventRef)anEvent
13421349
__block __auto_type result = anEvent;
13431350

13441351
os_activity_initiate("-[SRAXGlobalShortcutMonitor handleEvent:]", OS_ACTIVITY_FLAG_DETACHED, ^{
1345-
__auto_type nsEvent = [NSEvent eventWithCGEvent:anEvent];
1346-
if (!nsEvent)
1347-
{
1348-
os_trace_error("#Error Unexpected event");
1349-
return;
1350-
}
1351-
1352-
__auto_type shortcut = [SRShortcut shortcutWithEvent:nsEvent ignoringCharacters:YES];
1353-
if (!shortcut)
1352+
__auto_type eventKeyCode = CGEventGetIntegerValueField(anEvent, kCGKeyboardEventKeycode);
1353+
__auto_type eventType = CGEventGetType(anEvent);
1354+
__auto_type cocoaModifierFlags = SRCoreGraphicsToCocoaFlags(CGEventGetFlags(anEvent));
1355+
NSEventType cocoaEventType;
1356+
switch (eventType)
13541357
{
1355-
os_trace_error("#Error Not a keyboard event");
1356-
return;
1358+
case kCGEventKeyDown:
1359+
cocoaEventType = NSEventTypeKeyDown;
1360+
break;
1361+
case kCGEventKeyUp:
1362+
cocoaEventType = NSEventTypeKeyUp;
1363+
break;
1364+
case kCGEventFlagsChanged:
1365+
cocoaEventType = NSEventTypeFlagsChanged;
1366+
break;
1367+
default:
1368+
cocoaEventType = 0;
1369+
break;
13571370
}
13581371

1359-
SRKeyEventType eventType = nsEvent.SR_keyEventType;
1360-
if (eventType == 0)
1361-
return;
1362-
1363-
__auto_type actions = [self enabledActionsForShortcut:shortcut keyEvent:eventType];
1372+
__auto_type shortcut = [SRShortcut shortcutWithCode:eventType != kCGEventFlagsChanged ? (SRKeyCode)eventKeyCode : SRKeyCodeNone
1373+
modifierFlags:cocoaModifierFlags
1374+
characters:nil
1375+
charactersIgnoringModifiers:nil];
1376+
__auto_type keyEventType = [NSEvent SR_keyEventTypeForEventType:cocoaEventType
1377+
keyCode:(unsigned short)eventKeyCode
1378+
modifierFlags:cocoaModifierFlags];
1379+
__auto_type actions = [self enabledActionsForShortcut:shortcut keyEvent:keyEventType];
13641380
__block BOOL isHandled = NO;
13651381
[actions enumerateObjectsWithOptions:NSEnumerationReverse
13661382
usingBlock:^(SRShortcutAction *obj, NSUInteger idx, BOOL *stop)
@@ -1577,11 +1593,7 @@ - (BOOL)handleEvent:(NSEvent *)anEvent withTarget:(nullable id)aTarget
15771593
return NO;
15781594
}
15791595

1580-
SRKeyEventType eventType = anEvent.SR_keyEventType;
1581-
if (eventType == 0)
1582-
return NO;
1583-
1584-
__auto_type actions = [self enabledActionsForShortcut:shortcut keyEvent:eventType];
1596+
__auto_type actions = [self enabledActionsForShortcut:shortcut keyEvent:anEvent.SR_keyEventType];
15851597
__block BOOL isHandled = NO;
15861598
[actions enumerateObjectsWithOptions:NSEnumerationReverse
15871599
usingBlock:^(SRShortcutAction *obj, NSUInteger idx, BOOL *stop)

0 commit comments

Comments
 (0)