通过终端或AppleScript以编程方式更改OSX键盘布局("输入源")?

时间:2014-05-19 04:25:27

标签: macos applescript alfred

我目前正在通过Alfred运行GUI AppleScript来切换输入源,并且GUI脚本有时可能需要1秒才能完成更改。它有时很烦人。

我遇到了Determine OS X keyboard layout (“input source”) in the terminal/a script。我想知道,因为我们可以找到当前的输入源,如果有办法改变输入源以编程方式?我试过覆盖com.apple.HIToolbox.plist,但它没有改变输入。

(我确实知道系统偏好中有输入源的映射快捷方式,但我更喜欢用Alfred映射关键字)

6 个答案:

答案 0 :(得分:16)

您可以使用文本输入服务API执行此操作:

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 */;

第一行中的字典可以使用其他属性来选择其他条件来选择输入源。

还有NSTextInputContext。它有一个selectedKeyboardInputSource,可以设置为输入源ID以选择不同的输入源。问题在于,您需要NSTextInputContext的实例才能使用,其中一个实例仅在您有一个带有文本视图的关键窗口作为其第一响应者时才存在。

答案 1 :(得分:7)

@Ken Thomases' solution可能是最强大的 - 但它需要创建一个命令行实用程序。

非GUI脚本shell脚本/ AppleScripting解决方案很遗憾选项:而 可以更新{{ 1}}文件反映当前选定的输入源(键盘布局) - *.plist - 系统将忽略更改。

但是,以下 GUI脚本解决方案(基于this)虽然仍然涉及可见操作,但健壮且合理快< / strong>在我的机器上(约0.2秒):

(如果您只想通过已安装的布局循环,使用系统偏好设置中定义的键盘快捷键可能是您最好的选择; 解决方案的优势在于您可以定位特定的布局。)

请注意评论中提到的先决条件。

~/Library/Preferences/com.apple.HIToolbox.plist

答案 2 :(得分:2)

使用Xcode命令行工具的解决方案

对于那些想要构建@Ken Thomases' solution但没有安装Xcode的人(这是几个GiB,除非认真使用,否则花太多的空间完全没有用),可以使用Xcode命令行来构建它工具。

Internet上有一些有关如何安装Xcode命令行工具的教程。重点仅在于,与成熟的Xcode相比,它仅占用空间的一部分。

安装完成后,请按以下步骤操作:

  1. 创建一个名为what.m的文件
  2. 在what.m中输入以下内容:
#include <Carbon/Carbon.h>

int main (int argc, const char * argv[]) {
    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)
        return -1;

    return 0;
}
  1. 用所需的布局替换French
  2. 保存文件
  3. 在与what.m相同的文件夹中打开终端
  4. 运行以下命令: clang -framework Carbon whatever.m -o whatever

您的应用程序在同一文件夹中创建为whatever,并可以按以下方式执行: .\whatever

另外

我从未创建过任何Objective-C程序,因此这可能不是最佳选择,但是我想要一个可以将键盘布局作为命令行参数的可执行文件。对于任何有兴趣的人,这是我想出的解决方案:

在第2步中,使用以下代码:

#import <Foundation/Foundation.h>
#include <Carbon/Carbon.h>

int main (int argc, const char * argv[]) {
    NSArray *arguments = [[NSProcessInfo processInfo] arguments];

    NSArray* sources = CFBridgingRelease(TISCreateInputSourceList((__bridge CFDictionaryRef)@{ (__bridge NSString*)kTISPropertyInputSourceID : [@"com.apple.keylayout." stringByAppendingString:arguments[1]] }, FALSE));
    TISInputSourceRef source = (__bridge TISInputSourceRef)sources[0];
    OSStatus status = TISSelectInputSource(source);
    if (status != noErr)
        return -1;

    return 0;
}

在步骤6中,运行以下命令: clang -framework Carbon -framework Foundation whatever.m -o whatever

您现在可以从命令行切换到任何布局,例如: ./whatever British

注意:它仅允许切换到系统上已配置的布局!

答案 3 :(得分:2)

另一种选择是使用 Swift。它可以以类似脚本的方式使用(无需编译)。

  • 安装 Xcode 命令行工具
  • 从下面的代码创建一个脚本
  • 使用 swift script_file_name 运行脚本

代码:

import Carbon

let command = ProcessInfo.processInfo.arguments.dropFirst().last ?? ""
let filter = command == "list" ? nil : [kTISPropertyInputSourceID: command]

guard let cfSources = TISCreateInputSourceList(filter as CFDictionary?, false),
      let sources = cfSources.takeRetainedValue() as? [TISInputSource] else {
    print("Use \"list\" as an argument to list all enabled input sources.")
    exit(-1)
}

if filter == nil { // Print all sources
    print("Change input source by passing one of these names as an argument:")
    sources.forEach {
        let cfID = TISGetInputSourceProperty($0, kTISPropertyInputSourceID)!
        print(Unmanaged<CFString>.fromOpaque(cfID).takeUnretainedValue() as String)
    }
} else if let firstSource = sources.first { // Select this source
    exit(TISSelectInputSource(firstSource))
}

这详细说明了 Ken Thomasessbnc.eu 的答案。

答案 4 :(得分:1)

在AppleScript上,您只能使用cmd +“space”(或其他用于更改键盘源的内容)。

所有你需要的东西:

    key code 49 using command down

49 - AppleScript中ASCII码的“空格”按钮代码。

P.S。:不要忘记在系统偏好设置中获取AppleScript实用程序。

答案 5 :(得分:0)

tell application "System Events"
    key code 49 using control down
end tell

通过按键更改布局