¿Cómo monitorear el estado global de la clave modificadora (en cualquier aplicación)?

Estoy usando un código de carbono en mi proyecto Cocoa para manejar eventos clave globales (accesos directos) desde otras aplicaciones. Actualmente tengo configurada unakEventHotKeyReleased el controlador de eventos y yo podemos obtener teclas de acceso rápido cuando mi aplicación no está activa. Eso desencadena alguna operación en mi aplicación.

El problema que tengo con el comportamiento dekEventHotKeyReleased es:

Digamos, por ejemplo, presiono la combinación de teclas Cmd-Shift-P. Tan pronto como suelte la tecla "P", se activa el evento de la tecla de acceso rápido.Necesito poder activar el evento (o activarlo manualmente) cuandotodos de las teclas están sin pulsar (es decir, las teclas Cmd y Shift también se liberan).

Es fácil monitorear las teclas de acceso rápido, pero no he visto nada para monitorear pulsaciones individuales. Si pudiera monitorear los estados clave del modificador estaría en el negocio.

¿Alguna pista sobre cómo hacer esto?

¡Gracias por adelantado!

ACTUALIZAR:

He intentado usarkEventRawKeyUp ykEventRawKeyModifiersChanged pero mientraskEventHotKeyReleased funciona esos dos no lo hacen a pesar de que los configuro de la misma manera quekEventHotKeyReleased.

EventTypeSpec eventTypes[] = {{kEventClassKeyboard, kEventHotKeyReleased}, {kEventClassKeyboard, kEventRawKeyUp}};
// Changing the order in the list does not help, nor does removing kEventHotKeyReleased
OSStatus err = InstallApplicationEventHandler(&globalHotkeyHandler, GetEventTypeCount(eventTypes), eventTypes, NULL, NULL);
// err == noErr after this line

losglobalHotKeyHandler se llama metodo parakEventHotKeyReleased, pero no parakEventRawKeyUp Por alguna razón, parece que no puedo entender. Esto es lo que miglobalHotKeyHandler método se ve como

OSStatus globalHotkeyHandler(EventHandlerCallRef nextHandler, EventRef anEvent, void *userData) {
    NSLog(@"Something happened!");
}

¿Hay alguna llamada adicional que deba hacerse o alguna otra cosa que haya olvidado?

N.B: A primera vista, parece que podría estar deshabilitado el acceso para dispositivos de asistencia peroNo lo es. Así que estoy bastante despistado.

ACTUALIZACIÓN 2:

Investigué un poco en elCGEventTap Leibowitzn sugirió y se me ocurrió esta configuración:

CFMachPortRef keyUpEventTap = CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,kCGEventKeyUp,&keyUpCallback,NULL);
CFRunLoopSourceRef keyUpRunLoopSourceRef = CFMachPortCreateRunLoopSource(NULL, keyUpEventTap, 0);
CFRelease(keyUpEventTap);
CFRunLoopAddSource(CFRunLoopGetCurrent(), keyUpRunLoopSourceRef, kCFRunLoopDefaultMode);
CFRelease(keyUpRunLoopSourceRef);

... y la devolución de llamada:

CGEventRef keyUpCallback (CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) {
    NSLog(@"KeyUp event tapped!");
    return event;
}

Como puedes ver estoy usandokCGEventKeyUp como la máscara para el grifo del evento, pero de alguna manera estoy recibiendoeventos del mouse hacia abajo ??! ??

ACTUALIZACIÓN 3:

Ok, olvídalo, pasé por alto la línea en el documento que decía usar CGEventMaskBit (kCGEventKeyUp) para este parámetro, por lo que la llamada correcta es:

CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventKeyUp),&keyUpCallback,NULL);

Sin embargo, sigo teniendo un problema: las teclas modificadoras no activan kCGEventKeyUp ...

ACTUALIZACIÓN 4:

Ok, olvídalo otra vez ... Estoy obligado a responder a mis propias preguntas 5 minutos después de hacerlas hoy, ¡eh!

Para interceptar teclas modificadoras, usekCGEventFlagsChanged:

CGEventTapCreate(kCGHIDEventTap,kCGHeadInsertEventTap,kCGEventTapOptionListenOnly,CGEventMaskBit(kCGEventFlagsChanged),&callbackFunction,NULL);

Así que, en esencia, tengo la clave y la detección de estado de clave modificadora funcionando, peroTodavía estoy interesado en saberpor qué kEventRawKeyUp no funciona...

N.B: También tenga en cuenta que estoy desarrollando Tiger con el objetivo de tener soporte para versiones nuevas y antiguas del sistema operativo tanto como sea posible. CGEventTap es 10.4+ solo, así que usaré esto por ahora, pero una solución compatible con versiones anteriores sería bienvenida.

Respuestas a la pregunta(2)

Su respuesta a la pregunta