Frage

Ich bin mit Quarz CGEventTap in einem Versuch abfangen capslock drückt global und blockieren sie (haben sie etwas Sinnvolles tun statt). Ich erkennen, erfolgreich capslock drückt aber bisher nicht gelungen, sie zu blockieren. Mein Code (aus diese Stackoverflow Antwort) ist so etwas wie folgt aus:

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

Wenn ich richtig NULL verstehen Rückkehr sollte den keypress effektiv blockieren ausbreitet. Tatsächlich macht es auch für „normale“ keyup und -down Ereignisse. CAPSLOCK jedoch unabhängig schaltet. Irgendwelche Ideen, warum das so ist? Was mache ich falsch Annahmen? Und / oder wie kann ich alles anders machen, um mein Ziel zu erreichen?

Danke,

Thor

War es hilfreich?

Lösung

Sie können nicht capslock so blockieren. Capslock ist eine Bedingung, die von der Tastaturtreiber gehandhabt wird, nicht von dem Windows Server oder den einzelnen Anwendungen. Ein Tastendruck-Ereignis breitet sich in OS X wie folgt aus:

Tastaturtreiber -> Window Server -> Benutzersitzung -> Active Application

Bei jeder Ausbreitungsebene (mit „->“) können Sie ein Ereignis tippen und Block platzieren und / oder Schlüsselereignisse ändern. Tastaturtreiber und Windows Server sind beide privilegierte Komponenten, sind die beiden anderen normalen Benutzerebene Komponenten.

Die früheste Sie ein Tastatur-Ereignis zu fangen, wenn das Ereignis pflanzt sich von dem Treiber (Kernel-Space) mit dem Windows Server (Benutzerraum, aber immer noch privilegiert). Jedoch, wie oben erwähnt, wird der capslock Zustand intern im Treiber behandelt, so dass ein Ereignis fangen es schon zu spät ist. Der Fahrer wird bereits die capslock Licht auf der Tastatur aktiviert (falls erforderlich bei allen und nicht von der Hardware auf eigene durchgeführt) und die capslock Zustand ist auf erinnert, die sich auf alle zukünftigen Tastendrücken einen Effekt hat.

Sie können das capslock Licht programmatisch für HID-Geräte ausschalten (hat Apple auch Beispielcode für diesen ), aber das wird nicht Ausschaltzeiten capslock, es stellt sich nur das Licht aus.

Die einzige Art, wie ich zu implementieren, dass Ereignisse Taps mit manuell zu jedem Tastendruck mit capslock auf einen Tastendruck ohne capslock neu schreiben (eine, wo die capslock Flag nicht gesetzt ist und der beigefügten Brief, falls vorhanden, niedriger ist Fall). Weiterhin nicht den Benutzer zu verwirren, dann würden Sie das capslock Licht auszuschalten, wie Apple-Beispielcode gezeigt.

Weitere Alternativen sind: Schreiben Sie Ihre eigene Tastaturtreiber, die Kontrolle über die Tastatur nimmt statt der Standard-Treiber von Apple (nicht so hart, wie du denkst, aber immer noch hart hart genug) oder hacken Sie Ihren Weg in den Treiber (Übel, sondern Werke ). Z.B. einige Tastatur remappers nur einzelne Methoden des Fahrers außer Kraft setzen (Treiber sind C ++ in OS X, so dass OO-Objekte, die sie sind, und Sie können dynamisch C ++ Methoden zur Laufzeit außer Kraft setzen, sie wirklich nicht außer Kraft setzen, sondern Methode Tabellen manipulieren). Die Probleme mit diesen beiden Lösungen sind: Die erste bedeutet, dass, wenn Ihr Fahrer so gut wie die von Apple ist, einige USB-Tastaturen mit Ihrem Fahrer können nicht arbeiten, während andere tun, das zweite Mittel, wenn Sie einen Fehler machen, die System straft diesen Fehler mit einer Kernel-Panik.

Ich suche mich für einen Weg, um programmatisch Toggle capslock auf Mac, bisher ohne Erfolg. Aber ich kann Ihnen versichern, Event-Armaturen sind nicht der Weg zu gehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top