Как переназначить CAPSLOCK на OSX?

CapsLock, по-видимому, является одной из двух самых сложных клавиш для переназначения (вторая — кнопка питания).

Я могу глобально перехватить NSEvent-ы:

    _eventTap = CGEventTapCreate( kCGHIDEventTap, 
                                  kCGHeadInsertEventTap,
                                  kCGEventTapOptionDefault,
                                     CGEventMaskBit( kCGEventFlagsChanged ),
                                  (CGEventTapCallBack)_tapCallback,
                                  (__bridge void *)(self));

:

Однако я не получаю событие для каждой клавиши вверх/вниз. На самом деле происходит следующее:

(исходное состояние CapsLock выключено)

Нажатие клавиши: NSSystemDefined: 40a00 NSSystemDefined: 40b00 (в этот момент горит зеленый свет)

Клавиша вверх: NSSystemDefined: 40b00

Клавиша вниз: NSSystemDefined: 40a00 (Зеленый свет в этот момент выключен)

Клавиша вверх: (ничего)

Поэтому я не могу составить карту на этом уровне.

Но я решил, что могу отслеживать на более низком уровне с помощью IOKit, который обнаруживает каждое нажатие/нажатие клавиши клавиатуры, а затем поглощает события CAPSLOCK на этом уровне (возвращая NULL):

- (CGEventRef)processEvent:(CGEventRef)cgEvent
{
    NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];

    NSUInteger modifiers = [event modifierFlags] &
        ( NSCommandKeyMask | NSAlternateKeyMask | NSShiftKeyMask | NSControlKeyMask | NSAlphaShiftKeyMask );

    NSUInteger flags_changed = _modifiers ^ modifiers;
    if( flags_changed & NSAlphaShiftKeyMask )
    {
        NSLog( @"Eating CAPSLOCK" );
        return NULL;
    }

    _modifiers = modifiers;
    :

Однако это не мешает CapsLock делать свое дело (т. е. делать заглавными буквы).

Я даже пытался удалить флаг модификатора CapsLock из каждого события клавиатуры в обработчике:

if( modifiers & NSAlphaShiftKeyMask )
    event = [NSEvent keyEventWithType: event.type
                             location: NSZeroPoint
                        modifierFlags: event.modifierFlags & ! NSAlphaShiftKeyMask
                            timestamp: event.timestamp
                         windowNumber: event.windowNumber
                              context: event.context
                           characters: event.characters
          charactersIgnoringModifiers: event.charactersIgnoringModifiers
                            isARepeat: event.isARepeat
                              keyCode: event.keyCode ];

... Но не повезло!

Есть ли способ приручить эту надоедливую клавишу CapsLock?

РЕДАКТИРОВАТЬ: Как имитировать нажатие клавиши Caps Lock с помощью CGEventCreateKeyboardEvent в OS X


person P i    schedule 30.05.2015    source источник
comment
event.modifierFlags & ! NSAlphaShiftKeyMask не делает то, что вы хотите. Вы использовали оператор логического отрицания, а не побитовый оператор отрицания. Вы хотели event.modifierFlags & ~NSAlphaShiftKeyMask. Однако это не объясняет проблему, которую вы видите. Ваш код эффективно удалит флаг модификатора альфа-сдвига. Просто он также удалит все другие флаги модификаторов. Возможно, вы захотите взглянуть на так называемые флаги модификатора, зависящие от устройства, которые на самом деле не зависят от устройства, в младших 16 битах. Например, NX_DEVICE_ALPHASHIFT_STATELESS_MASK из IOLLEvent.h.   -  person Ken Thomases    schedule 30.05.2015


Ответы (1)


Я полагаю, что Karabiner Elements делает это с помощью собственного драйвера клавиатуры, взгляните на исходный код.

person devon    schedule 21.01.2021