Pregunta

Estoy usando cuarzo CGEventTap en un intento de prensas globalmente capslock interceptar y bloquearlas (al que ellos hagan algo útil en su lugar). Yo detecto con éxito prensas capslock pero hasta ahora ha sido imposible para bloquearlos. Mi código (procedente de este respuesta stackoverflow) es algo como esto:

eventTap = CGEventTapCreate(kCGHIDEventTap,
                            kCGTailAppendEventTap, 
                            kCGEventTapOptionDefault, 
                            eventMask,
                            myCGEventCallback,
                            &oldFlags);

runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);

CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);

CGEventRef myCGEventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef theEvent, void *refcon)
{
    CGEventFlags *oldFlags = (CGEventFlags *)refcon; 

    switch (type)
    {
        case kCGEventFlagsChanged:
        {
            CGEventFlags newFlags = CGEventGetFlags(theEvent);
            CGEventFlags changedFlags = *oldFlags ^ newFlags; 
            *oldFlags = newFlags;

            if (changedFlags == 65536)
            {
                NSLog(@"Capslock pressed. Let's not return the event");
                return NULL;
            }
            break;
        }
        default:
            break;
    }

    NSLog(@"Different modifier than capslock. Returning the event");
    return theEvent;
}

Si he entendido bien devuelva NULL debería bloquear de manera efectiva la pulsación de tecla se propaguen. De hecho, también se hace por keyup "normal" y eventos -Por las. Sin embargo, independientemente capsLock alterna. Cualquier idea por qué? Estoy haciendo suposiciones incorrectas? Y / o ¿cómo puedo hacer las cosas de manera diferente para lograr mi objetivo?

Gracias,

Thor

¿Fue útil?

Solución

No se puede bloquear BloqMayus así. BloqMayus es una condición, que es manejado por el controlador del teclado, no por la ventana de servidores o las aplicaciones individuales. A propaga eventos de pulsación de tecla en OS X como que:

controlador de teclado -> Servidor de Ventanas -> Sesión de usuario -> aplicación activa

En cada nivel de propagación (indicado por "->") se puede colocar un grifo de evento y de bloque y / o modificar los eventos clave. Controlador de teclado y ventana de servidores son ambos componentes privilegiados, los otros dos son componentes normales de nivel de usuario.

La primera se puede coger un evento de teclado es cuando se propaga el evento desde el controlador (el espacio del núcleo) a la ventana de servidores (espacio de usuario, pero aún privilegiados). Sin embargo, como se señaló anteriormente, el estado BloqMayus se maneja internamente en el controlador, por lo tanto la captura de un evento que ya es demasiado tarde. El conductor le han permitido ya a la luz BloqMayus en el teclado (si es necesario en absoluto y no se realiza por el hardware por sí mismo) y se acordó el estado BloqMayus estar en, lo que tiene un efecto en todas las pulsaciones de teclas futuro.

Puede apagar la luz BloqMayus programación para dispositivos HID (Apple tiene aún código de ejemplo para que ), pero esto no será desvío BloqMayus, simplemente se apaga la luz.

La única forma que veo de implementar que el uso de grifos evento es manualmente volver a escribir cada pulsación de tecla con BloqMayus a una pulsación de tecla sin BloqMayus (uno donde la bandera BloqMayus no está establecido y la carta adjunta, en su caso, es menor caso). Además, para no confundir al usuario, que le apaga la luz BloqMayus como se muestra mediante código de ejemplo de Apple.

Otras alternativas son: Escribir su propio controlador de teclado, que toma el control sobre el teclado en lugar del controlador estándar de Apple (no es tan difícil como parece, pero aún lo suficientemente duro duro) o la piratería de su camino en el conductor (el mal, pero las obras ). P.ej. algunos remappers teclado anulan métodos sólo individuales del conductor (los conductores son C ++ en OS X, por lo que son OO-objetos y se puede reemplazar dinámicamente métodos C ++ en tiempo de ejecución; en realidad no anula, sino más bien manipular las tablas del método). Los problemas con las dos soluciones son: la primera significa que a menos que su controlador es tan bueno como el de Apple, algunos teclados USB no funcionen con su conductor, mientras que otros lo hacen, el segundo medio si hace algún error, el sistema castiga este error con un kernel panic.

Estoy buscando a mí mismo una manera de BloqMayus programación de palanca en Mac, sin éxito hasta el momento. Pero les puedo asegurar, grifos de eventos no son el camino a seguir.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top