objective-ccxcodemacoscgeventtap

Simulate/Toggle CAPS LOCK programatically in OS X


I have seen many post on this topic. But haven't found a clear answer anywhere.

Is there a way to toggle CAPS LOCK in Objective-C or C code? I am not looking for a solution using X11 libs. I am not bothered about the LED on/off status. But just the functionality of CAPS LOCK (changing the case of letters and printing the special characters on number keys).

Why is CGEvent not supporting this the way it does for other keys?


Solution

  • I got this working, after a long struggle.

    Invoke the method given below twice. Once for up event and another for down event. For example for simulating CAPS A, we need to do the following.

    [self handleKeyEventWithCapsOn:0 andKeyDown:NO];
    [self handleKeyEventWithCapsOn:0 andKeyDown:YES];
    

    0 is the keycode for 'a'.

    - (void) handleKeyEventWithCapsOn:(int) keyCode andKeyDown:(BOOL)keyDown
    {
        if(keyDown)
        {
            CGEventRef eventDown;
            eventDown = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)keyCode, true);
            CGEventSetFlags(eventDown, kCGEventFlagMaskShift);
            CGEventPost(kCGSessionEventTap, eventDown);
            CFRelease(eventDown);
        }
        else
        {
            CGEventRef eventUp;
            eventUp = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)keyCode, false);
            CGEventSetFlags(eventUp, kCGEventFlagMaskShift);
            CGEventPost(kCGSessionEventTap, eventUp);
    
            // SHIFT Up Event
            CGEventRef eShiftUp = CGEventCreateKeyboardEvent(NULL, (CGKeyCode)56, false);
            CGEventPost(kCGSessionEventTap, eShiftUp);
            CFRelease(eventUp);
            CFRelease(eShiftUp);
        }
    }