macOS App:处理绑定到全局键盘快捷键的键组合

macOS App:处理绑定到全局键盘快捷键的键组合,第1张

概述在某些应用程序中,应用程序直接处理键盘快捷键是有意义的,否则键盘快捷键将绑定到系统范围的组合.例如,⌘-Space(通常是Spotlight)或⌘-Tab(通常是app切换器).这适用于各种Mac应用程序,例如VMWare Fusion,Apple自己的屏幕共享和远程桌面客户端(分别将事件转发到VM或服务器,而不是在本地处理它们),以及应用程序中的一些类似的第三方应用程序商店. 我们希望在我们正在 在某些应用程序中,应用程序直接处理键盘快捷键是有意义的,否则键盘快捷键将绑定到系统范围的组合.例如,⌘-Space(通常是Spotlight)或⌘-Tab(通常是app切换器).这适用于各种Mac应用程序,例如VMWare Fusion,Apple自己的屏幕共享和远程桌面客户端(分别将事件转发到VM或服务器,而不是在本地处理它们),以及应用程序中的一些类似的第三方应用程序商店.

我们希望在我们正在开发的应用程序中实现这样的模式,但是很难确定如何做到这一点.我应该指出,有问题的应用程序是一个常规的前台应用程序,是沙箱,任何解决方案都必须符合App Store规则.商店中的其他应用程序可以执行此 *** 作的事实意味着这必须是可能的.

要清楚,我们希望:

>检测并处理所有按键,包括绑定到全局快捷键的按键.
>防止全局快捷方式触发其全局约束效应.

Apple的Event Architecture document表明前台应用程序应该已经接收了这些事件. (它只涉及早期级别处理诸如电源和d出按钮之类的东西,这很好.)它继续建议,并且key events document also implies NSApplication的sendEvent:方法是检测基于修改器标志的潜在快捷方式,将它们分派给窗口,如果失败,请转到菜单栏.它没有明确说明全局绑定快捷方式会发生什么.

我尝试了子类化NSApplication并重写sendEvent:.无论我是否将所有事件都传递给超类实现,或者如果我说,过滤修饰键事件,当我按⌘-Space时,我会收到按下并释放命令(⌘)键的事件,但不会显示空格键. Spotlight UI总是会d出.

我没有从Apple或其他方面找到有关子类化NSApplication及其早期事件处理的更多信息.我似乎无法找出检测和处理全局快捷方式的级别.

有人可以指点我正确的方向吗?

可行的解决方案不起作用:

建议我在其他Stack Overflow帖子中看到但不适用于我见过的其他应用程序(这会破坏App Store规则):

> Accessibilty API(需要特殊许可)
>事件点击/挂钩(需要以root身份运行)

无论如何,这两个都是过度杀戮,因为它们让你随时拦截所有事件,而不仅仅是当你的应用程序是前台应用程序时.

NSevent的addGlobalMonitorForEventsMatchingMask:handler:同时不会阻止全局快捷方式处理程序为这些事件触发,所以我甚至都不打算尝试它.

解决方法 好的,所以Cocoa事件方法和Quartz事件抽头都没有了,因为它们需要root或accessibility访问权限,或者在dock之前没有捕获事件.

Carbon的PushSymbolicHotKeyMode已经用完,因为根据文档,它需要访问权限.

Carbon的RegisterEventHotKey可能已经出局了,因为Apple似乎不允许它(请参阅我在评论中的链接).然而,即便如此,我测试了你不能用它来捕获命令选项卡.

我快速证明了这是如何工作的,但是YMMV:

>实现此answer中的KeyboarDWatcher示例类.您需要链接IOKit.
>添加硬件 – USB(com.apple.security.device.usb)沙盒权利.这是必要的,因为KeyboarDWatcher使用HID来捕获按键
> Handle_DeviceEventCallback将为您提供按下的键.您显然可以根据需要进行修改
>使用SetsystemUIMode阻止任务切换器和Spotlight.你需要链接Carbon.

SetsystemUIMode(kUIModeContentSuppressed,kUIOptiondisableProcessSwitch);

请注意,这仅适用于您的应用程序位于前台(可能是您想要的).我使用跟踪矩形在我的视图上设置了它,所以只有当鼠标在我的视图上时才会生效(如在Remotix中):

- (voID)vIEwDIDLoad {[super vIEwDIDLoad];NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:[self.vIEw bounds] options: (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];    [self.vIEw addTrackingArea:trackingArea];}- (voID) mouseEntered:(NSEvent*)theEvent {    SetsystemUIMode(kUIModeContentSuppressed,kUIOptiondisableProcessSwitch);}- (voID) mouseExited:(NSEvent*)theEvent {    SetsystemUIMode(kUIModenormal,0);}

Remotix似乎链接了Carbon和IOKit,但我看不出他们是否拥有USB授权(我试过演示,而不是App Store版本).他们有可能做这样的事情.

实现此目的的常规方法是安装Quartz事件抽头.但是,要接收定位到其他应用程序的事件,您需要(如您所说)为root,或者为您的应用启用辅助功能访问权限.

似乎无法使用当前沙盒规则的事件点击.这已在@L_502_3@中得到确认.该链接仅限登录,但引用该主题:

Is there are any chance to handle events that comming from media keys by prevents launch iTunes. Before sandBox it was possible by create CGEventTap but Now sandBox deny using hID-controll.

No,this is not currently possible within App SandBox.

我不确定另一种方法可以做到这一点;我有兴趣知道App Store中的哪些应用可以?

VMWare Fusion显然不是沙盒,Apple自己的应用程序不受规则约束.请记住,沙盒仅在2012年引入后添加的新应用程序上强制执行.在该日期之前添加的应用程序没有强制执行沙盒.见answer.

总结

以上是内存溢出为你收集整理的macOS App:处理绑定到全局键盘快捷键的键组合全部内容,希望文章能够帮你解决macOS App:处理绑定到全局键盘快捷键的键组合所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1009991.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存