CGEventTapCreate наблюдает за вводом с клавиатуры в Какао

Приветствую. Я пытаюсь сделать приложение для контроля детей. Регистратор клавиатуры является частью этого приложения. Я использую CGEventTapCreate для наблюдения за клавиатурой. Это работает хорошо, но иногда я получаю дублирование событий нажатия клавиш. У них нет набора [NSEvent isARepeat], только дубликаты. Например, я могу набрать «qwerty», но приложение получает события нажатия клавиш для этих символов: «qqwweerrttyy». Может быть, кто-нибудь испытал что-то подобное? У меня эта проблема возникает на версиях 10.5 и 10.6 (обе - Intel).

Я публикую здесь методы установки и обработки регистратора клавиатуры:

- (BOOL)installKeyboardLogger
{
  CGEventMask keyboardMask = CGEventMaskBit(kCGEventKeyDown);
  CGEventMask mouseMask = CGEventMaskBit(kCGEventMouseMoved) |   CGEventMaskBit(kCGEventLeftMouseDown) |
      CGEventMaskBit(kCGEventRightMouseDown);

  CGEventMask mask = keyboardMask + mouseMask;// + mouseMask;//CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventMouseMoved);

  // Try to create keyboard-only hook. It will fail if Assistive Devices are not set.
  mMachPortRef =  CGEventTapCreate(
                                   kCGAnnotatedSessionEventTap,
                                   kCGTailAppendEventTap, // kCGHeadInsertEventTap
                                   kCGEventTapOptionListenOnly,
                                   keyboardMask,
                                   (CGEventTapCallBack)eventTapFunction,
                                   self );
  if (!mMachPortRef)
    [mLogFile logNeedAssistiveDevice: @"Can't install keyboard hook."];
  else
    CFRelease(mMachPortRef);

  mMachPortRef = CGEventTapCreate(
                                  kCGAnnotatedSessionEventTap,
                                  kCGTailAppendEventTap, // kCGHeadInsertEventTap
                                  kCGEventTapOptionListenOnly,
                                  mask,
                                  (CGEventTapCallBack)eventTapFunction,
                                  self );
  if (!mMachPortRef)
  {
    [mLogFile logNeedAssistiveDevice: @"Can't install keyboard&mouse hook."];
    return NO;
  }

  mKeyboardEventSrc = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, mMachPortRef, 0);
  if ( !mKeyboardEventSrc )
    return NO;

  CFRunLoopRef runLoop = CFRunLoopGetCurrent();
  if ( !runLoop )
    return NO;

  CFRunLoopAddSource(runLoop,  mKeyboardEventSrc, kCFRunLoopDefaultMode);
  return YES;
}


    CGEventRef eventTapFunction(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
{
  if (type != NX_KEYDOWN && type != NX_OMOUSEDOWN && type != NX_OMOUSEUP && type != NX_OMOUSEDRAGGED &&
      type != NX_LMOUSEUP && type != NX_LMOUSEDOWN && type != NX_RMOUSEUP && type != NX_RMOUSEDOWN &&
      type != NX_MOUSEMOVED && type != NX_LMOUSEDRAGGED && type != NX_RMOUSEDRAGGED) 
    return event;

  NSEvent* sysEvent = [NSEvent eventWithCGEvent:event];

  if (type == NX_KEYDOWN && [sysEvent type] == NSKeyDown)
  {
    if (![sysEvent isARepeat])
      [(ControlPanelController*)refcon handleCapturedCharacters: [sysEvent characters]];
  }
  else
    [(ControlPanelController*)refcon handleMouse];

  return event;
}
7
задан Dmytro 29 December 2010 в 17:28
поделиться