Switch to a specific input source in OS X in Catalina with AppleScript

applescriptinput-sourcemenu bar

I use different keyboard layouts and switched between them using a simple script

on changeKeyboardLayout(layoutName)
    tell application "System Events" to tell process "SystemUIServer"
        tell (1st menu bar item of menu bar 1 whose description is "text input") to {click, click (menu 1's menu item layoutName)}
    end tell
end changeKeyboardLayout
changeKeyboardLayout("German LaTeX2")

That worked well until the latest update.
I don't really speak AppleScript, but a bit of testing indicates that SystemUIServer no longer has access to a menu item with name "text input".
Trying

tell application "System Events" to tell process "SystemUIServer" to get value of attribute "AXDescription" of every menu bar item of menu bar 1

gives me Siri, blutooth, time machine, clock and a few others. So somehow the input source menu is managed differently now, but I have now clue how or how to find out (all searches pointed me to scripts similar to mine)

Update 2019/12/10

The suggested solutions so far both have defects, in one case you always get a delay of 5 seconds which is rather long and the trick with killing "System Events" as taken from the other posting doesn't always seem to work, sometimes it results in the script getting a timeout (which is even worse then have the 5 seconds delay all the time), so it looks as if this is still in need for a better solution

Best Answer

I stumbled upon the same issue of wanting to switch between multiple input sources with keyboard shortcuts quickly since Catalina broke the old method using AppleScript. Although the above methods work, they're rather clunky, unreliable, and slow (at least for me).

After a bit of digging around the internet I found a better solution. Someone wrote a terminal / command line utility program that changes input source layouts by name that works really well, and changes input sources instantaneously (tested in Catalina).

Here are the steps to make it work:

  1. Download the source files from https://github.com/minoki/InputSourceSelector - click on the green button Code → Download ZIP
  2. Extract the ZIP file
  3. Open terminal and navigate to the unzipped folder
  4. Run the make command in that folder, and an executable "InputSourceSelector" will be produced. (You may have to add executable permissions to it via chmod +x InputSourceSelector).

Now you can list and switch input sources with these commands:

  • ./InputSourceSelector list-enabled - to list all currently enabled input sources
  • ./InputSourceSelector current - to show the currently selected input source id
  • ./InputSourceSelector select <InputSourceId> - to switch to an input source by its id

See the README on the author's page for more commands.

Then to switch layouts, use the command 'select' with an <InputSourceId>:

  • ./InputSourceSelector select com.apple.keylayout.US
  • ./InputSourceSelector select com.apple.keylayout.Dvorak
  • ./InputSourceSelector select com.apple.keylayout.Spanish

The <InputSourceId> is the id before the parentheses, for example:

  • For "com.apple.keylayout.US (U.S.)" the id is "com.apple.keylayout.US"
  • For "com.apple.keylayout.Dvorak (Dvorak)" the id is "com.apple.keylayout.Dvorak"
  • For "com.apple.keylayout.Spanish (Spanish)" the id is "com.apple.keylayout.Spanish"

For ids with spaces, you may have to enclose them in double quotes.

You can now place the executable file in '/usr/local/bin' to make it available system-wide, and run the command without the preceding './' from anywhere in the system.

You can also make a couple shortcuts to quickly switch between the various input sources in BetterTouchTool or a similar program.

In BetterTouchTool just add a global keyboard shortcut, and for the Assigned Action select "Execute Terminal Command". In the terminal command window use the command /usr/local/bin/InputSourceSelector select com.apple.keylayout.Dvorak or whatever input source you want to switch to.