2011-01-18 2 views
2

그래서이 멋진 키보드 매크로 응용 프로그램을 만드는 데 많은 시간을 낭비했습니다. 그것은 훌륭한 작품, 유일한 문제는 몇 분 후, 그냥 작동을 멈 춥니 다. 키를 누르면 호출이 중지됩니다.응용 프로그램이 임의로 키 누르기 (CGEventTaps) 수신을 중지합니다.

나는 그것을 잠글 수 없었지만, 적어도 30 초가 걸렸습니다. 대개 몇 분 동안은 발생하지 않습니다. 나는 그때까지 많은 이벤트를 가로 채고 보낼 것이다. 응용 프로그램이 발생하면 여전히 실행 중입니다.

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) 것을 반환) 할 때, 나는 일반적주의 - 여기

내가

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

그리고 핸들러를 듣고 뭘하는지의 예 다음 코드를 사용하여 하나 이상의 키 누름을 발행하십시오. 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; 
}