CapsLock appears to be one of the two trickiest keys to remap (the other being the power button).
I can global-intercept NSEvent-s:
_eventTap = CGEventTapCreate( kCGHIDEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionDefault,
CGEventMaskBit( kCGEventFlagsChanged ),
(CGEventTapCallBack)_tapCallback,
(__bridge void *)(self));
:
However, I don't get an event for each key up/down. What actually happens is this:
(initial state of CapsLock off)
Key down: NSSystemDefined: 40a00 NSSystemDefined: 40b00 (Green light is on at this point)
Key up: NSSystemDefined: 40b00
Key down: NSSystemDefined: 40a00 (Green light is OFF at this point)
Key up: (nothing)
So I can't map at this level.
But I figured I could monitor at a lower level using IOKit, which detects every keyboard key down/up event, and then eat the CAPSLOCK events at this level (by returning 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;
:
However, that doesn't prevent CapsLock from doing its thing (i.e. capitalising typed letters).
I've even tried removing the CapsLock modifier flag from every keyboard event within the handler:
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 ];
... But no luck!
Is there any way to tame this pesky CapsLock key?
EDIT: How to simulate Caps Lock keystroke with CGEventCreateKeyboardEvent in OS X