如何在OSX上重新映射CAPSLOCK键?

5

大写锁定键似乎是两个最难重新映射的键之一(另一个是电源按钮)。

我可以全局拦截NSEvent-s:

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

:

然而,每次按键/释放键并不会触发一个事件。实际上的情况是这样的:
(初始状态下 CapsLock 关闭) 按下键: NSSystemDefined: 40a00 NSSystemDefined: 40b00 (Green light 在此时亮起)
释放键: NSSystemDefined: 40b00
按下键: NSSystemDefined: 40a00 (Green light 在此时熄灭)
释放键: (无任何反应)
所以我不能在这个级别上进行映射。但是我想我可以使用 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 ];

...但是没有运气!

有没有任何方法可以驯服这个恼人的大写锁定键?

编辑:如何在OS X中使用CGEventCreateKeyboardEvent模拟大写锁定键击键


1
event.modifierFlags & ! NSAlphaShiftKeyMask 并不能实现你想要的功能。你使用了逻辑非运算符而不是按位非运算符。你想要的是 event.modifierFlags & ~NSAlphaShiftKeyMask。然而,这并不能解释你所看到的问题。你的代码实际上会移除 alpha-shift 修改器标志。只是它也会移除所有其他修改器标志。你可能需要查看所谓的设备相关修改器标志,在低 16 位中并不真正依赖于设备。例如,来自 IOLLEvent.h 的 NX_DEVICE_ALPHASHIFT_STATELESS_MASK - Ken Thomases
1个回答

0

我相信Karabiner Elements使用自己的键盘驱动程序来实现它,可以查看源代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接