Detecting keyboard layout through AS ObjC interface?


Short of defaults read on, what seems the best way to detect active keyboard layout from AppleScript ?

Is there some analogy of this JavaScript for Automation snippet ?

(() => {

    ObjC.bindFunction('CFMakeCollectable', ['id', ['void *']]);

    return ObjC.unwrap(



Do you mean something like this:

I changed the variable name from “InputContext” to “CurrentTextInput” because the new name is more descriptive (Bill Kopp 2/16/2018).

use framework "Foundation"

set CurrentTextInput to current application's NSTextInputContext's currentInputContext() --> <NSTextInputContext: 0x6000012b92c0>
class of CurrentTextInput --> (Class) NSTextInputContext

set KeyboardInputSource to CurrentTextInput's selectedKeyboardInputSource() --> (NSString) ""
set KeyboardInputSourceName to KeyboardInputSource as text --> ""
set LocalizedKeyboardInputSourceName to (current application's NSTextInputContext's localizedNameForInputSource:KeyboardInputSource) as text --> "U.S."

set TheResult to "Keyboard input source name: " & KeyboardInputSourceName & return & "Localized keyboard inputSource name: " & LocalizedKeyboardInputSourceName

The script outputs:

Keyboard input source name:
Localized keyboard inputSource name: U.S.

If I change to the British keyboard it outputs:

Keyboard input source name:
Localized keyboard inputSource name: British


That’s good – thank you !

(and in addition to an AS function (lower down) it also suggests an improvement to the JS for Automation version, which wasn’t obtaining a localised name)

Updated JS

(() => {

    ObjC.bindFunction('CFMakeCollectable', ['id', ['void *']]);

    // keyboardLayout :: IO () -> {source :: String, localName :: String}
    const keyboardLayout = () => {
        const source = $.TISCopyCurrentKeyboardInputSource();
        return [
                ['source', $.kTISPropertyInputSourceID],
                ['localized', $.kTISPropertyLocalizedName]
            .reduce((a, [k, p]) => Object.assign(a, {
                [k]: ObjC.unwrap($.CFMakeCollectable(
                    $.TISGetInputSourceProperty(source, p)
            }), {});

    return keyboardLayout();

An Applescript wrapping

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

-- keyboardLayout :: IO () -> {source :: String, localName :: String}
on keyboardLayout()
    set context to current application's NSTextInputContext
    set source to (context's currentInputContext())'s ¬
    {source:source as text, localName:¬
        (context's localizedNameForInputSource:source) as text}
end keyboardLayout