Short of defaults read
on com.apple.HIToolbox.plist
, what seems the best way to detect active keyboard layout from AppleScript ?
Is there some analogy of this JavaScript for Automation snippet ?
(() => {
ObjC.import('Carbon');
ObjC.bindFunction('CFMakeCollectable', ['id', ['void *']]);
return ObjC.unwrap(
$.CFMakeCollectable(
$.TISGetInputSourceProperty(
$.TISCopyCurrentKeyboardInputSource(),
$.kTISPropertyInputSourceID
)
)
);
})();
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) "com.apple.keylayout.US"
set KeyboardInputSourceName to KeyboardInputSource as text --> "com.apple.keylayout.US"
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: com.apple.keylayout.US
Localized keyboard inputSource name: U.S.
If I change to the British keyboard it outputs:
Keyboard input source name: com.apple.keylayout.British
Localized keyboard inputSource name: British
2 Likes
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.import('Carbon');
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 ¬
selectedKeyboardInputSource()
{source:source as text, localName:¬
(context's localizedNameForInputSource:source) as text}
end keyboardLayout
keyboardLayout()