【问题标题】:How do I get keyboard events in an NSStatusWindowLevel window while my application is not frontmost?当我的应用程序不在最前面时,如何在 NSStatusWindowLevel 窗口中获取键盘事件?
【发布时间】:2008-11-27 15:27:46
【问题描述】:

创建半透明窗口 (based on example code by Matt Gemmell) 后,我想在此窗口中获取键盘事件。当我的应用程序是活动应用程序时,似乎只有键盘事件,而我想要键盘事件,即使我的应用程序不活动但窗口可见。

基本上我想要 Quicksilver 应用程序(由 blacktree)提供的行为。

有人对如何做到这一点有任何提示吗?

【问题讨论】:

    标签: cocoa macos


    【解决方案1】:

    有两种选择:

    1. 使用 GetEventMonitorTarget() 和附加的 Carbon 运行循环来抓取键盘事件。示例代码可在 CocoaDev 的 this page 上获得。

    2. CGEventTapCreate 注册事件陷阱。示例代码可在 Apple 开发人员邮件列表中的 this thread 中找到。

    编辑:请注意,只有在通用访问首选项窗格中选中“启用辅助设备访问”时,这些方法才有效。

    【讨论】:

    • 好消息。我只想补充一点,您需要启用“启用辅助设备访问”才能从事件点击中获取关键事件。
    • 谢谢!我没有意识到这是对事件陷阱的要求。我会将其添加到我的答案中。
    • 感谢您的回答,但不能选择“启用辅助设备访问”。 Quicksilver 也不需要它,所以必须有另一种可能性。
    • 此信息并不完全正确,但仍然很好。 CGEventTap 不需要启用辅助设备。仅当您在事件进入用户当前会话之前捕获事件并且您的进程不是 root 时才需要启用此功能。始终可以捕获用户会话事件。
    • @Mecki:感谢您澄清这一点。我很确定 Kristof 需要捕获具有键盘焦点的应用程序之外的事件。这算不算在用户会话之外?
    【解决方案2】:

    可能更适合您的更简单的方法是让您的应用仅在后台运行。 LSUIElement plist 键的 CocoaDev 上的讨论解释了如何设置它。基本上,您的应用程序不会出现在 Dock 或应用程序切换器中,并且在激活时不会替换当前应用程序的菜单栏。从用户的角度来看,它永远不是“活动”应用程序,但您打开的任何窗口都可以被激活并正常响应事件。唯一需要注意的是你永远不会显示你的菜单栏,所以你可能必须设置一个 NSStatusItem (显示在菜单栏右侧的图标菜单之一)来控制(即退出,调出首选项等)您的应用程序。

    编辑:我完全忘记了 Interface Builder 中的非激活面板复选框。您需要使用 NSPanel 而不是 NSWindow 来获得此选择。此设置允许您的面板在不激活您的应用程序的情况下接受点击和键盘输入。我敢打赌,QuickSilver 在他们的 UI 中使用了这个设置和 Carbon Hot Keys API 的某种组合。

    【讨论】:

    • 我的应用程序也需要完全存在,这意味着将我的应用程序拆分为仅后台应用程序和普通应用程序,这意味着应用程序间通信并使事情变得更加复杂。 Quicksilver 表明没有必要。我猜我得研究它的代码。谢谢
    • 您可以通过使您的窗口成为非激活面板来执行类似的操作,这将(​​大部分)阻止面板中的点击激活您的应用程序。我怀疑这就是 Quicksilver 正在做的事情,因为它有一个常见的关联 buglet,点击表格视图仍然会激活应用程序。
    【解决方案3】:

    更新:
    Apple 实际上似乎从 10.5 BTW 开始再次改变了一切(我最近升级了,我的示例代码没有像以前那样工作)。

    现在,您确实只能捕获设置事件点击的 keydown 事件,前提是您是 root 或启用了辅助设备,无论您计划捕获哪个级别以及是否选择捕获(这允许您修改甚至丢弃事件)或只听。当 flags 发生变化(实际上甚至改变这些)和其他事件时,您仍然可以获得信息,但在其他情况下没有 keydown。

    但是,使用 carbon 事件处理程序和方法 RegisterEventHotKey() 允许您注册一个热键,并且在按下它时您会收到通知,您既不需要是 root 也不需要启用辅助设备之类的东西.我认为 Quicksilver 可能就是这样做的。

    【讨论】:

    • 您只需要启用辅助设备访问即可注册对上键和下键事件的点击。没有它,其他所有工作都很好。但是,鉴于原始问题的性质,如果他使用事件点击来解决他的问题,仍然可能需要它。
    • 看起来 Apple 已将其更改为 10.5,即使没有在 10.4 中启用 AD,我也可以获取 keydown,只要我仅在 SessionLevel 上捕获它们而不尝试更改它们 - 至少以前是这样正在工作:(
    猜你喜欢
    • 1970-01-01
    • 2014-02-11
    • 2014-08-03
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 2011-07-14
    相关资源
    最近更新 更多