Приложение случайным образом прекращает нажатие клавиш (CGEVENTTAPS)
-
12-10-2019 - |
Вопрос
Итак, я потратил впустую кучу времени, создав это действительно классное приложение для клавиатуры. Это отлично работает, единственная проблема в том, что через пару минут он просто перестает работать. Это перестает меня вызвать, когда я нажимаю клавишу.
Я не смог заблокировать это, но всегда требуется как минимум 30 секунд. Обычно это не произойдет в течение нескольких минут. К тому времени я перехватил и разослал много событий. Приложение все еще работает, когда это происходит.
Вот пример того, что я делаю, чтобы послушать
-(void)listen {
CFMachPortRef downEventTap = CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionDefault,CGEventMaskBit(kCGEventKeyDown),&onKeyDown,self);
downSourceRef = CFMachPortCreateRunLoopSource(NULL, downEventTap, 0);
CFRelease(downEventTap);
CFRunLoopAddSource(CFRunLoopGetCurrent(), downSourceRef, kCFRunLoopDefaultMode);
CFRelease(downSourceRef)
}
И обработчик -
CGEventRef onKeyDown(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
NSLog(@"DOWN (%i)", CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode));
// When it matches, I return CGEventCreate(NULL) to stop the event
return event;
}
Также обратите внимание, что когда я перехватываю событие (и возвращаю это CGEventCreate(NULL)
), Я обычно выпускаю один или несколько собственных нажатий клавиш, используя следующий код. Обратите внимание, что KeyCmd и т. Д. - просто ярлыки для нормальных констант.
- (void)sendKey:(KeyCode)code cmd:(BOOL)cmd alt:(BOOL)alt ctl:(BOOL)ctl shift:(BOOL)shift {
CGEventFlags flags = 0;
if (cmd) flags = flags | KeyCmd;
if (alt) flags = flags | KeyAlt;
if (ctl) flags = flags | KeyCtl;
if (shift) flags = flags | KeyShift;
CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
CGEventRef keyDownPress = CGEventCreateKeyboardEvent(source, (CGKeyCode)code, YES);
CGEventSetFlags(keyDownPress, flags);
CGEventPost(kCGAnnotatedSessionEventTap, keyDownPress);
CFRelease(keyDownPress);
CFRelease(source);
}
Спасибо!
Решение
Я думаю, что в Snow Leopard есть ошибка, которая останавливает вашего слушателя, если что -то раз.
В вашем обработчике Keydown проверьте следующий тип и просто повторно включите слушателя.
if (type == kCGEventTapDisabledByTimeout) {
NSLog(@"Event Taps Disabled! Re-enabling");
CGEventTapEnable(eventTap, true);
return event;
}