2011-01-18 6 views
2

これで、本当にクールなキーボードマクロアプリケーションを作成するのに無駄な時間を費やしました。素晴らしいことですが、唯一の問題は数分後には動作を停止することです。私はキーを押すと呼び出されなくなります。アプリケーションはランダムにキープレス(CGEventTaps)の受信を停止します。

私はそれをロックすることができませんでしたが、少なくとも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) 
} 

ハンドラ聞くためにやっているものの例だ - 通常I、

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

ありがとうございます!

答えて

6

Snow Leopardには何かタイムアウトした場合にリスナーが停止するバグがあります。

keyDownハンドラで、次のタイプを確認して、リスナを再度有効にしてください。

if (type == kCGEventTapDisabledByTimeout) { 
    NSLog(@"Event Taps Disabled! Re-enabling"); 
      CGEventTapEnable(eventTap, true); 
    return event; 
} 
関連する問題