【发布时间】:2015-08-13 04:39:52
【问题描述】:
CapsLock 似乎是最难重新映射的两个键之一(另一个是电源按钮)。
我可以全局拦截 NSEvent-s:
_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 键?
编辑:How to simulate Caps Lock keystroke with CGEventCreateKeyboardEvent in OS X
【问题讨论】:
-
event.modifierFlags & ! NSAlphaShiftKeyMask不会做你想做的事。您使用了逻辑否定运算符而不是按位否定运算符。你想要event.modifierFlags & ~NSAlphaShiftKeyMask。但是,这并不能解释您所看到的问题。您的代码将有效地删除 alpha-shift 修饰符标志。只是它也会删除所有其他修饰符标志。您可能想查看低 16 位中所谓的设备相关修饰符标志,它们实际上并不依赖于设备。例如,来自 IOLLEvent.h 的NX_DEVICE_ALPHASHIFT_STATELESS_MASK。
标签: macos keyboard-events capslock