2014-09-24 73 views
0

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

Switching my keyboard settings to German

我可以叫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最终被“融为一体。 apple.keylayout.German“,这大部分是我想要的。不包括:

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

回答

2

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

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

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

+0

谢谢!很棒。 – 2014-09-25 17:11:26