Приложение случайным образом прекращает получать нажатия клавиш (CGEventTaps) - PullRequest
2 голосов
/ 18 января 2011

Итак, я потратил кучу времени на создание этого действительно классного клавиатурного макроса. Он отлично работает, единственная проблема в том, что через пару минут он просто перестает работать. Он перестает звонить, когда я нажимаю клавишу.

Я не смог его заблокировать, но это всегда занимает не менее 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);
}

Спасибо!

1 Ответ

7 голосов
/ 30 марта 2011

В Snow Leopard, я думаю, есть ошибка, которая останавливает вашего слушателя, если что-то заканчивается.

В вашем обработчике keyDown проверьте следующий тип и просто повторно включите прослушиватель.

if (type == kCGEventTapDisabledByTimeout) {
    NSLog(@"Event Taps Disabled! Re-enabling");
            CGEventTapEnable(eventTap, true);
    return event;
}
...