How to simulate toggling the CAPS Lock key?

I've read https://wiki.keyboardmaestro.com/trigger/USB_Device_Key but I cannot say whether there is a KM action to detect whether the CAPS Lock key on my Apple Keyboard (with num pad) is activated (indicated by the green LED burning).

What I want to achieve is:

  • If a variable SourceSegmentNoTags is ALL CAPS, press the CAPS Lock key.

At https://apple.stackexchange.com/questions/361373/toggle-caps-lock-programmatically-using-applescript I've found this script:

ObjC.import("IOKit");
ObjC.import("CoreServices");


(() => {
    var ioConnect = Ref();
    var state = Ref();

    $.IOServiceOpen(
        $.IOServiceGetMatchingService(
            $.kIOMasterPortDefault,
            $.IOServiceMatching(
                $.kIOHIDSystemClass
            )
        ),
        $.mach_task_self_,
        $.kIOHIDParamConnectType,
        ioConnect
    );
    $.IOHIDGetModifierLockState(ioConnect, $.kIOHIDCapsLockState, state);
    $.IOHIDSetModifierLockState(ioConnect, $.kIOHIDCapsLockState, !state[0]);
    $.IOServiceClose(ioConnect);
})();

But on Catalina it only turns the CAPSLOCK on. As for now, I can live with that. I'll just have to remember to switch CAPSLOCK off manually.

Update: Tested on Big Sur too. Script only activates the CAPSLOCK, but doesn't deactivate it.

I have a Microsoft Natural Ergonomic 4000 keyboard, and I can detect the Caps Lock key being pressed by using a USB Device Key trigger. Then I can use a variable to track the state (by default, it's off.)

1 Like

Just in case this is of use to anyone, rather than toggle, have a capslockON and capslockOFF macro, it’s just a minor tweak to the original code but seems to work fine:

ObjC.import("IOKit");
ObjC.import("CoreServices");

(() => {
    var ioConnect = Ref();

    $.IOServiceOpen(
        $.IOServiceGetMatchingService(
            $.kIOMasterPortDefault,
            $.IOServiceMatching(
                $.kIOHIDSystemClass
            )
        ),
        $.mach_task_self_,
        $.kIOHIDParamConnectType,
        ioConnect
    );
    $.IOHIDSetModifierLockState(ioConnect, $.kIOHIDCapsLockState, 0);
    $.IOServiceClose(ioConnect);
})();

Change the line:

$.IOHIDSetModifierLockState(ioConnect, $.kIOHIDCapsLockState, 0);

The value 0 will turn caps lock off and 1 will turn it on. So the above code is for capslockOFF just insert it into an execute javascript for automation block.

This is based on the stack exchange code with minor changes just to set the state rather than to toggle.

1 Like

Thank you for the update, very happy with this. I confirm that it works on Big Sur 11.7.8 too.