Change input source

Hi Maestro, i’m a KM user who uses french as my main input source. I’m trying to find a way to have my input source as English when photoshop is the active app, and revert to french the rest of the time. Any idea how this could be done?

This AppleScript will set the keyboard layout and return the keyboard layout that was previously in effect.

-- Set desiredKeyboard to "Azeri"
set desiredKeyboard to "Australian"

tell application "System Events"
  tell application process "SystemUIServer"
    tell (first menu bar item of menu bar 1 whose value of attribute "AXDescription" is "text input")
      set keyboardWas to its value
      perform action "AXPress"
      tell menu item desiredKeyboard of menu 1
        perform action "AXPress"
      end tell
    end tell
  end tell
end tell

return keyboardWas

Peter, while your solution definitely works, it involves visible action (clicking on appropriate menu item). I have been trying to come up with better solution and fortunately there is an excellent discussion on SE where a solution is given how to switch keyboard language programmatically through a shell command, which takes a fraction of second to run and does not involve any GUI elements.

Here is the link:

All the credits go to SE users Ken Thomases and mklement0

Steps to build this as of Xcode 6: New Project > Command Line Tool > enter details, choose Objective-C under Language. At the top of main.m, add @import carbon;. Paste the code in the appropriate place inside the main() function

NSArray* sources = CFBridgingRelease(TISCreateInputSourceList((__bridge CFDictionaryRef)@{ (__bridge NSString*)kTISPropertyInputSourceID : @"com.apple.keylayout.French" }, FALSE)); TISInputSourceRef source = (__bridge TISInputSourceRef)sources[0]; OSStatus status = TISSelectInputSource(source); if (status != noErr)
/* handle error */;

Yes, direct support for this is on the todo list and will likely happen at some point.

Peter, this would be awesome! As for myself i can see numerous uses for this.

In the meanwhile, I seem to be able to do a rough hack in Swift to get some toggling that I need. Not sure how easily transferable it is, and I've promised myself not to explore ObjC and Swift libraries (life is short :-), so I wouldn't be much help with getting it to work with other language pairs, and I have skipped understanding the data types properly, but KM's Execute Swift script action seems to work very well, and perhaps others would like to explore making more use of it ...

For reference, rather than use:

Toggling between two languages (Swift hack).kmmacros (18.5 KB)

import Carbon

let strMain = "en";                      // <-- edit
let strOther = "he";                     // <-- edit

let strCurrent = String(
    TISCopyCurrentKeyboardInputSource().takeRetainedValue()
  );

TISSelectInputSource(TISCopyInputSourceForLanguage(
    (strCurrent.rangeOfString(
      "British"                             // <-- edit
    ) != nil ? strOther : strMain)
  ).takeRetainedValue())

let strNewInput = String(
    TISCopyCurrentKeyboardInputSource().takeRetainedValue()
  );

print("→ ", strNewInput);

Have you ever tried “Set Keyboard Layout” action? Although this action doesn’t sound like changing input source, this works good to me when I switch between Chinese and English input source.

1 Like

Much better !

Thanks – I remember that Peter was planning to add that kind of action, and hadn’t noticed that it was already there : - )

(From the point of view of toggling, though, is there a KM route which I have also missed to detecting the active input language, other than, scripting the Preferences UI ?

The context is that I have six items on my input source menu, but for particular texts I often just need to continually do a one-key switch back and forth between two of them, without having to choose from a list.)

Do you mean that you want to switch between two input sources? If so, you can just use the system shortcut.

You’re right – it’s a good idea – and I probably should really do that.

( the only point at which it doesn’t quite work for me is when I’ve been using one language and then want to switch straight into toggling between two others)