OS X.如何在守护进程中获取所有系统当前活动窗口的TISInputSourceRef(键盘布局)?

时间:2014-10-28 15:51:34

标签: macos daemon keyboard-layout

我希望在Windows中获得类似GetKeyboardLayout(threadId)的键盘布局。 threadId是具有活动窗口的应用程序的id。我想将虚拟键码转换为当前语言的字符。

现在我使用TISCopyCurrentKeyboardInputSource()函数,但它没有参数,只返回" U. S"语言。我认为这是守护进程的布局。 此外,我无法使用TISCopyInputSourceForLanguage(语言)函数的TISInputSourceRef转换代码。它只返回美国字符。

更新 好。我找到了转换keyCodes的解决方案。我用参数修饰符等于0来调用函数UCKeyTranslate。但是我无法找到如何获取活动窗口的输入源或只是任何正在运行的应用程序。

更新2: plist路径为/ Library / LaunchAgents

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>my.keylogger</string>
    <key>Program</key>
    <string>/Users/Titan/Desktop/keylogger</string>
    <key>ProgramArguments</key>
    <array>
      <string>keylogger</string>
    </array>
    <key>KeepAlive</key>
    <true/>
  </dict>
</plist>

1 个答案:

答案 0 :(得分:0)

每当您想要从守护进程访问用户会话的状态时,您就是在做错了。它无法可靠地工作。

标准解决方案是使用在每个用户会话中启动的用户代理。如有必要,每个代理都可以联系中央守护程序并报告用户会话的状态。

有关详细信息,请参阅Technical Note TN2083: Daemons and Agents


<强>更新

上述技术说明与了解为什么不能从守护进程中执行此操作相关。

对于代理,它应使用分布式通知中心观察kTISNotifySelectedKeyboardInputSourceChanged通知,以了解所选键盘输入源何时更改。然后它可以调用TISCopyCurrentKeyboardInputSource()来了解当前的键盘输入源。

为了让代理接收通知,它必须以其中一种常见模式运行其主线程的运行循环。在普通的Cocoa应用程序中,这是作为主事件循环的一部分为您完成的。在另一种程序中,你必须自己做。

BOOL shouldKeepRunning = YES;        // global
...

[[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                    selector:@selector(myMethod:)
                                                        name:(__bridge NSString*)kTISNotifySelectedKeyboardInputSourceChanged
                                                      object:nil
                                          suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately];

while (shouldKeepRunning && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
    /* do nothing */;

...
- (void) myMethod:(NSNotification*)note
{
    TISInputSourceRef inputSource = TISCopyCurrentKeyboardInputSource();
    // do something with inputSource ...
}
相关问题