diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm index 1e6b6c14..16cc9ea1 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKey.mm +++ b/Sources/OpenKey/macOS/ModernKey/OpenKey.mm @@ -68,6 +68,9 @@ CGKeyCode _keycode; CGEventFlags _flag, _lastFlag = 0, _privateFlag; CGEventTapProxy _proxy; + + //defined in OpenKeyManager.m + extern void OpenKeyReEnableEventTap(void); Uint16 _newCharString[MAX_UNICODE_STRING]; Uint16 _newCharSize; @@ -599,6 +602,14 @@ CGKeyCode ConvertEventToKeyboadLayoutCompatKeyCode(CGEventRef keyEvent, CGKeyCod * MAIN Callback. */ CGEventRef OpenKeyCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) { + //macOS turns the tap off if this callback misses its deadline (heavy system load) + //or after certain user input, and tells us through these two pseudo event types. + //Without re-enabling here, OpenKey silently stops converting until it is relaunched. + if (type == kCGEventTapDisabledByTimeout || type == kCGEventTapDisabledByUserInput) { + OpenKeyReEnableEventTap(); + return event; + } + //dont handle my event if (CGEventGetIntegerValueField(event, kCGEventSourceStateID) == CGEventSourceGetSourceStateID(myEventSource)) { return event; diff --git a/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m b/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m index 97883f1a..4ac82862 100644 --- a/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m +++ b/Sources/OpenKey/macOS/ModernKey/OpenKeyManager.m @@ -77,6 +77,14 @@ +(BOOL)initEventTap { return YES; } +// Called from OpenKeyCallback when macOS reports that it turned our tap off. +// Only this file owns `eventTap`, so re-enabling has to happen here. +void OpenKeyReEnableEventTap(void) { + if (eventTap) { + CGEventTapEnable(eventTap, true); + } +} + +(BOOL)stopEventTap { if (_isInited) { //release all object CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);