applescriptjavascript-automation

JXA keystroke does not work with numbers?


I would like to trigger a keyboard shortcut using JXA.

This works:

system.keystroke('d', {
  using: ['control down', 'option down']
})

But this does not:

system.keystroke('3', {
  using: ['control down', 'option down']
})

The difference being the character ("3" instead of "d") used in the shortcut. Both work when manually triggering the shortcuts.

Anyone know why?


Solution

  • Executive summary: You can use keyCode codes instead of numbers to work around this issue. The number “20” is the code for the key that produces the number 3:

    system = Application("System Events")
    system.keyCode(20, {
        using: ['control down']
    })
    

    JXA does appear to successfully produce both a “d” and a “3”

    system = Application("System Events")
    system.keystroke('d')
    system.keystroke('3')
    

    It will also successfully produce both CMD-A and CMD-3. In Script Editor, this script will first select all (CMD-A), and then either hide or display the result window (CMD-3):

    system = Application("System Events")
    system.keystroke('a', {
        using: ['command down']
    })
    system.keystroke('3', {
        using: ['command down']
    })
    

    What it will not do is successfully handle the control key down with a number. I have verified that control-1, 2, and 3 will not switch desktops for me. If I change the shortcut for the second desktop from CTRL-2 to CTRL-A then the following will switch to the second desktop:

    system = Application("System Events")
    system.keystroke('a', {
        using: ['control down']
    })
    

    But this will not switch to the third desktop:

    system = Application("System Events")
    system.keystroke('3', {
        using: ['control down']
    })
    

    It beeps at me, and the result is “undefined”.

    This is not a JXA problem. The same occurs in AppleScript:

    tell application "System Events"
        keystroke "a" using control down
    end tell
    

    will switch to the second desktop.

    tell application "System Events"
        keystroke "3" using control down
    end tell
    

    will beep and do nothing.

    I do not know why this is happening. However, there does appear to be a workaround. You can use the key code for the keys that produce numbers to get the desired behavior. For example, the key code for the key that produces the number 3 (or the pound/hash symbol) is 20. The line key code 20 using {control down} in AppleScript does switch to desktop 3:

    tell application "System Events"
        key code 20 using {control down}
    end tell
    

    And the same is true of JXA:

    system = Application("System Events")
    system.keyCode(20, {
        using: ['control down']
    })
    

    This is on macOS Monterey 12.6.