Pregunta

Por lo tanto, he perdido un montón de tiempo en la creación de este teclado muy fresco macro de aplicación. Funciona muy bien, el único problema es que después de un par de minutos, simplemente deja de funcionar. Deja de ser llamado cuando se presiona una tecla.

No han sido capaces de bloqueo hacia abajo, pero siempre toma por lo menos 30 segundos para pasar. Por lo general no va a suceder durante varios minutos. Voy he interceptado y enviado a cabo muchos eventos para entonces. La aplicación sigue funcionando cuando sucede.

Este es un ejemplo de lo que estoy haciendo para escuchar

 -(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)
}

Y el manejador -

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

También tenga en cuenta que cuando un evento de intercepción (y devolver ese CGEventCreate(NULL)), por lo general emitir una o más claves prensas de mi propia, usando el siguiente código. Tenga en cuenta que KeyCmd, etc, son sólo los accesos directos a las constantes normales.

 - (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);
}

Gracias!

¿Fue útil?

Solución

Hay un error en Snow Leopard, creo, que para su oyente si algo el tiempo de espera.

En el controlador de keyDown, cheque por el siguiente tipo, y simplemente volver a habilitar el oyente.

if (type == kCGEventTapDisabledByTimeout) {
    NSLog(@"Event Taps Disabled! Re-enabling");
            CGEventTapEnable(eventTap, true);
    return event;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top