6

I'm looking to toogle capslock programmatically using applescript. Here is something I tried to make it work. It seems to work for all other keys except capslock.

tell application "System Events"
    key code 57
end tell

57 is the key code for caps lock

  • I don't think that can be done in AppleScript. Can you tell us what you are trying to accomplish and see if there is a work around that we can suggest? – Chris Norman Jun 01 '19 at 20:34
  • I think you mean you want to turn on and off the function of the caps lock. You are looking for a keyboard remapping tool. You will have to look at each of the packages you find to see if you can do the remapping dynamically. https://apple.stackexchange.com/questions/219629/how-can-i-rebind-keyboard-keys-in-os-x – historystamp Jun 01 '19 at 21:25
  • Re: Keyboard re-mapping tools: Karabiner Elements is well-known, highly-praised, open source and free to use/download with the option of contributing via PayPal to support its development. Its command-line interface will allow you to activate a mapping profile from inside a script. – CJK Jun 01 '19 at 23:47
  • 1
    If it doesn't have to be AppleScript, have a look at Toggle caps lock programmatically. I just tested the code at the link and it works without issue under macOS High Sierra. Just make sure you read and apply the minor correction to the code at the end. You'll need to have Command Line Tools for Xcode installed (or Xcode) to compile the main.c file created from the code in the link.. It makes as executable named capslock and you pass it 1 to turn on and 0 to turn off. You could also use it in an AppleScript do shell script command. – user3439894 Jun 02 '19 at 00:29

2 Answers2

5

Submitting a separate answer, as it is entirely distinct from my first in that it solves the issue at hand. Credit goes to @user3439894 who pointed the OP and I to a link (Toggle caps lock programmatically) that features some source code written in C that can programmatically toggle/set the state of the caps lock. Thus credit goes also to the original author of that code, for which I offer a translation into JavaScript for Automation (JXA), which is the JavaScript flavour of AppleScript.

This script toggles the state of caps lock upon each run:

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);
})();

This, like any AppleScript, can be run from within Script Editor (choose the language option in the navigation bar at the top of the window). Sadly, Script Debugger doesn't cater for JXA. But, in practice, the script will be most usefully executed by way of some other automation software, such as Automator, Keyboard Maestro, Alfred, etc., all of which can execute JXA scripts directly; and any software that doesn't provide this option can execute it by way of the shell command osascript:

osascript -l JavaScript /path/to/script.jxa.applescript

You can use an .applescript or .scpt file extension to save the script.

CJK
  • 5,512
  • 2
    Appreciate the credit mention; however, the real credit goes to the author of the C code and you for your translation into JAX. If I had posted an actual answer it would have been around compiling the C code and using do shell script "/path/to/capslock -1" to toggle the caps lock key. It works, but yours doesn't require having CLT for Xcode (or Xcode) and is much easier to implement for the non-techie user. – user3439894 Jun 02 '19 at 16:40
  • 1
    Under MacOSX 10.11.6 El Capitan you must replace () => with function () but the code has no effect and state[0] is always false regardless of the real CapsLock state. – Devon Oct 14 '19 at 10:54
  • @DevonSeanMcCullough Thanks for informing for the benefit of El Capitan users. If you’re able to debug and suggest a fix, I welcome an addendum you can feel free to add to the answer, or create one separately. I’m not in a position to debug El Capitan issues myself, and it’s outside the remit of the OP. Assuming those functions and constants were all available to El Capitan, another alternative would be to write it in Swift. – CJK Oct 14 '19 at 16:36
  • The C code at https://discussions.apple.com/thread/7094207 works in 10.6.8 Snow Leopard … 10.14.6 Mojave. – Devon Oct 15 '19 at 03:09
  • @CJK In 10.11.6 El Capitan, $.mach_task_self_ is undefined – Devon Oct 15 '19 at 06:18
  • @DevonSeanMcCullough Thank you. I’ll investigate what the equivalent alias is in El Capitan when I have time and my computer back, – CJK Oct 15 '19 at 09:05
  • 3
    @CJK I just tried this script in Script Editor on 10.15.4 and it does turn the Caps Lock on, but it never turns it back off. Not sure if that is an issue with your script, or if it is an issue with 10.15. – Chris Norman Apr 24 '20 at 19:45
  • NOW HOW DO YOU TURN IT OFF? I WANT TO TOGGLE IT INSTEAD OF TURN IT ON EVERY EXECUTION! – user14492 Aug 12 '20 at 20:31
  • 1
    I always get false from get state even when it is on. – user14492 Aug 12 '20 at 20:49
  • I'm also getting false for the value of state[0] no matter what state capslock is actually in. That means that with the code as it is now it always turns caps lock on and never toggles it. For my own sake I've modified it so that it takes a param and sets capslock to whatever you ask.

    The equivalent C code calling IOHIDGetModifierLockState still works fine though, so must be some obscurity particular to Catalina's "JavaScript for Automation" that's causing this bug.

    – Chris Aug 19 '20 at 03:48
1

Though not exactly the same thing, a similar action might be to simulate the shift key being held down. You can command System Events to keep the shift key down until you command it to be reset:

tell application "System Events" to key down shift

To reset:

tell application "System Events" to key up shift

It has obvious differences to activating caps lock, which are worth a footnote.


WARNING: It can be humorous then quickly annoying to execute the first command and lose the ability to, for example, input any digit (which can only be done if the shift key is up). The action of the shift key will affect mouse clicks, shortcuts, and so on. To illustrate, if you typically run a script by pressing R, this will not be possible while the shift key is active, as the system will register R (thankfully, +⟨click⟩ on menu items appears to perform the same action as a simple click).

CJK
  • 5,512