【问题标题】:OSX Cocoa input source detect changeOSX Cocoa 输入源检测变化
【发布时间】:2014-09-24 18:57:15
【问题描述】:

有谁知道如何检测用户何时更改 OSX 中的当前输入源?

我可以致电TISCopyCurrentKeyboardInputSource() 来了解正在使用的输入源 ID,如下所示:

    TISInputSourceRef isource = TISCopyCurrentKeyboardInputSource();
    if ( isource == NULL )
    {
        cerr << "Couldn't get the current input source\n.";
        return -1;
    }

    CFStringRef id = (CFStringRef)TISGetInputSourceProperty(
        isource, 
        kTISPropertyInputSourceID);
    CFRelease(isource);

如果我的输入源是“德语”,那么 id 最终会是“com.apple.keylayout.German”,这主要是我想要的。除了:

  1. 我的进程启动后TISCopyCurrentKeyboardInputSource() 的结果不会改变吗?特别是,我可以在循环中调用TISCopyCurrentKeyboardInputSource() 并切换我的输入源,但TISCopyCurrentKeyboardInputSource() 不断返回我的进程开始时使用的输入源。
  2. 我真的很想在输入源更改时收到通知。有没有办法做到这一点?要获得通知或某种事件告诉我输入源已更改?

【问题讨论】:

    标签: macos cocoa keyboard macos-carbon


    【解决方案1】:

    您可以观察到NSTextInputContext 发布到默认Cocoa 通知中心的NSTextInputContextKeyboardSelectionDidChangeNotification 通知。或者,您可以观察通过 Core Foundation 分布式通知中心传递的kTISNotifySelectedKeyboardInputSourceChanged 通知。

    但是,任何此类更改都始于您应用外部的系统进程。然后系统会通知每个应用程序进程中的框架。框架只能在允许运行其事件循环时接收此类通知。同样,如果您自己观察分布式通知,则只有在允许事件循环(或至少主线程的运行循环)运行时才会发生这种情况。

    所以,这就解释了为什么运行一个反复检查TISCopyCurrentKeyboardInputSource() 结果的循环不起作用。您不允许框架监视通知更改的渠道。如果不是循环,而是使用频率足够低的重复计时器,以使其他东西有机会运行,并且您将控制权返回给应用程序的事件循环,您会看到 TISCopyCurrentKeyboardInputSource() 的结果发生变化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-21
      • 2018-06-13
      • 2015-11-29
      • 2019-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多