質問

それで、私はこの本当にクールなキーボードマクロアプリケーションを作成する時間を無駄にしました。それはうまく機能します。唯一の問題は、数分後に動作を停止することです。キーを押すと、呼び出されなくなります。

私はそれをロックダウンすることができませんでしたが、それは常に少なくとも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))、私は通常、次のコードを使用して、独自の1つ以上のキープレスを発行します。 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にはバグがあります、それは何かが時になったらあなたのリスナーを止めることです。

キーダウンハンドラーで、次のタイプをチェックして、リスナーを再度に再度可能にします。

if (type == kCGEventTapDisabledByTimeout) {
    NSLog(@"Event Taps Disabled! Re-enabling");
            CGEventTapEnable(eventTap, true);
    return event;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top