【问题标题】:How to programmatically switch an input method on OS X如何以编程方式在 OS X 上切换输入法
【发布时间】:2014-05-18 02:57:00
【问题描述】:

我正在尝试编写一个在 OS X 上切换输入法的程序。正常布局没有问题。例如。此代码有效(为简洁起见,去掉了 CFReleases/CFRetains):

TISInputSourceRef getref(char* id) {
    CFStringRef name     = CFStringCreateWithCString(kCFAllocatorDefault, id, kCFStringEncodingUTF8);
    CFStringRef keys[]   = { kTISPropertyLocalizedName };
    CFStringRef values[] = { name };
    CFDictionaryRef dict = CFDictionaryCreate(kCFAllocatorDefault, (const void **)keys, (const void **)values, 1, NULL, NULL);
    CFArrayRef array     = TISCreateInputSourceList(dict, true);
    return (TISInputSourceRef) CFArrayGetValueAtIndex(array, 0);
}

int main() {
    TISSelectInputSource(getref("U.S. International - PC"));
}

但是当我选择输入法而不是布局时:

TISSelectInputSource(getref("Hiragana"));

发生了奇怪的事情:在菜单栏中正确选择并显示了 IM,但是它没有启用(键入会产生罗马字母而不是日语)。如果我然后切换到任何其他应用程序并返回 IM 开始正常工作。文档没有提及此案例的任何具体内容。请帮我修复它并提前感谢。

【问题讨论】:

  • 谢谢,克里斯,但不一样。这个问题基本上是“我如何切换输入源”,而我的问题是“我知道如何切换输入源,但是当它是输入法而不是简单布局时为什么它不切换”。
  • 好的,我已经撤回了结束投票。
  • “布局”是什么意思?你是说风景吗?
  • 我正在尝试使用来自developer.apple.com/library/mac/documentation/TextFonts/… 的术语:“键盘输入源,包括键盘布局、键盘输入法和输入模式”。基本上我在布局下的意思是“只能使用键盘输入的字母,例如'a'”。在输入法下,我的意思是“需要输入特殊应用程序的字母,例如'あ',后者使用加载并应用于输入的 /System/Library/Input Methods/Kotoeri.app/Contents/MacOS/Kotoeri 应用程序盒子”。

标签: macos ime


【解决方案1】:

这个答案显示了一个程序化 UI operation 方法来切换输入源 macOS Big Sur / macOS 11 或更高版本。

首先,使用以下 Swift 函数和 Applescript 来获取当前输入源的名称:

func UseApplescriptToGetSystemInputSourcesInMenubar() -> [InputSource] {
    let applesript = """
    tell application "System Events"
        tell process "TextInputMenuAgent"
            get the name of menu item of menu 1 of menu bar item 1 of menu bar 2
        end tell
    end tell
    """

    if let script = NSAppleScript(source: applesript) {
        var error: NSDictionary?
        let descriptor = script.executeAndReturnError(&error)
        /// descriptor: <NSAppleEventDescriptor: [ 'utxt'("Pinyin - Simplified"), 'utxt'("ABC"), 'utxt'("Hiragana"), 'msng', 'utxt'("Handwriting - Simplified"), 'msng', 'utxt'("Show Emoji & Symbols"), 'utxt'("Show Keyboard Viewer"), 'msng', 'utxt'("Show Input Source Name"), 'msng', 'utxt'("Open Keyboard Preferences…") ]>
        if let err = error {
            print(Time() + "[Applescript] NSAppleScript.executeAndReturnError(): \(err)")
        } else {
            var currentInputSources: [InputSource] = []
            for i in 1 ... descriptor.numberOfItems {
                if let inputSource = descriptor.atIndex(i)?.stringValue {
                    currentInputSources.append(InputSource(name: inputSource, id: i))
                } else {
                    print(Time() + "[Applescript] Got \(currentInputSources.count) input sources from menu bar.")
                    return currentInputSources
                }
            }
        }
    } else {
        print(Time() + "[Applescript] NSAppleScript.init()")
    }
    return []
}

然后使用这个 Swift 函数来改变输入源:

func UseApplescriptToSwitchInputSource(to inputSourceName: String) {
    let applesript = """
    tell application "System Events"
        tell process "TextInputMenuAgent"
            click menu item "\(inputSourceName)" of menu 1 of menu bar item 1 of menu bar 2
            click menu bar item 1 of menu bar 2
        end tell
    end tell
    """

    if let script = NSAppleScript(source: applesript) {
        var error: NSDictionary?
        script.executeAndReturnError(&error)
        if let err = error {
            print(Time() + "[Applescript] NSAppleScript.executeAndReturnError(): \(err)")
        }
    } else {
        print(Time() + "[Applescript] NSAppleScript.init()")
    }
}

我已经使用上述方法开发了一个使用快捷方式更改输入源的应用程序。你可以在 GitHub 上查看它 - https://github.com/Yang-Xijie/InputSourceSwitcher。在该 repo 的 README 中,您可以找到我的方法和其他更改输入源的方法的优缺点。

【讨论】:

    猜你喜欢
    • 2012-04-30
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 2011-03-16
    • 1970-01-01
    相关资源
    最近更新 更多