Domanda

Quindi, ho sprecato un sacco di tempo a creare questa tastiera davvero cool applicazione macro. E le grandi opere, l'unico problema è che dopo un paio di minuti, appena smette di funzionare. Cessa di ottenere chiamato quando si preme un tasto.

non sono stato in grado di bloccare il basso, ma ci vuole sempre almeno 30 secondi per accadere. Di solito non accadrà per diversi minuti. Io ho intercettato e inviato numerosi eventi per allora. L'applicazione è ancora in funzione quando succede.

Ecco un esempio di quello che sto facendo per ascoltare

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

E il gestore -

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

Si noti inoltre che quando intercetta un evento (e restituire che CGEventCreate(NULL)), io di solito emettere una o più tasti premuti di mio, utilizzando il seguente codice. Si noti che KeyCmd, ecc, sono solo scorciatoie per le costanti normali.

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

Grazie!

È stato utile?

Soluzione

C'è un bug in Snow Leopard, credo, che ferma il vostro ascoltatore se qualcosa timeout.

Nel vostro gestore keyDown, assegno per il tipo seguente, e solo riattivare l'ascoltatore.

if (type == kCGEventTapDisabledByTimeout) {
    NSLog(@"Event Taps Disabled! Re-enabling");
            CGEventTapEnable(eventTap, true);
    return event;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top