macOS App:处理绑定到全局键盘快捷键的组合键 [英] macOS App: handling key combinations bound to global keyboard shortcuts

查看:121
本文介绍了macOS App:处理绑定到全局键盘快捷键的组合键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In some apps, it makes sense for the app to directly handle keyboard shortcuts which are otherwise bound to system wide combinations. For example, ⌘-Space (normally Spotlight) or ⌘-Tab (normally app switcher). This works in various Mac apps, such as VMWare Fusion, Apple's own Screen Sharing and Remote Desktop clients (forwarding the events to the VM or server, respectively, instead of handling them locally), and also some similar third-party apps in the App Store.

我们想在我们正在开发的应用程序中实现这种模式,但是却很难确定如何做到这一点.我应该指出,所涉及的应用程序是常规的前台应用程序,已被沙盒化,并且任何解决方案都必须遵守App Store规则.商店中的其他应用程序可以做到这一点的事实表明,这必须是可能的.

We would like to implement such a mode in the app we're working on, but are having a hard time working out how to do it. I should point out that the app in question is a regular foreground app, is sandboxed, and any solution must comply with App Store rules. The fact that other apps on the store can do it implies that this must be possible.

为清楚起见,我们要:

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

Apple的

Apple's Event Architecture document suggests that the foreground application should already be receiving these events. (It only talks about earlier levels handling things such as the power and eject buttons, which is fine.) It goes on to suggest, and the key events document also implies that NSApplication's sendEvent: method is what detects potential shortcuts based on modifier flags, dispatching them to the windows and if that fails, on to the menu bar. It's not explicitly stated what happens to globally-bound shortcuts.

我尝试了子类化NSApplication并覆盖了sendEvent:.无论我是否将所有事件都传递给超类实现,或者如果我说过滤修饰符键事件,当我按⌘-空格键时,我都会收到按和释放命令(⌘)键的事件,但不会收到空格键.始终会弹出Spotlight用户界面.

I tried subclassing NSApplication and overriding sendEvent:. No matter if I pass through all events to the superclass implementation, or if I say, filter modifier key events, when I press ⌘-Space, I receive the events for pressing and releasing the command (⌘) key, but not the spacebar. The Spotlight UI always pops up.

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

I haven't found much information on subclassing NSApplication and its early event handling, from Apple or otherwise. I can't seem to find out at what level global shortcuts are detected and handled.

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

Can someone please point me in the right direction?

不可行的解决方案:

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

Suggestions I've seen in other Stack Overflow posts but which don't apply to the other apps I've seen which do this (and which would break App Store rules):

  • 可访问性API(需要特殊权限)
  • 点击/挂钩事件(需要以root身份运行)

这两种方法无论如何都是过大的杀伤力,因为它们使您可以在 all 次内拦截 all 事件,而不仅仅是在您的应用程序是前台应用程序时.

Both of these would be overkill anyway, as they let you intercept all events at all times, not just while your app is the foreground app.

NSeventaddGlobalMonitorForEventsMatchingMask:handler:不会阻止全局快捷方式处理程序为这些事件触发,因此,我什至不必费心尝试.

NSevent's addGlobalMonitorForEventsMatchingMask:handler: meanwhile doesn't prevent the global shortcut handler from firing for those events, so I didn't even bother trying it.

推荐答案

我很久以前就解决了这个问题,但我只是注意到我从未在这里发表过.答案最终涉及CGSSetGlobalHotKeyOperatingMode().这不是公共API,但是许多Mac App Store应用程序通过混淆函数名称并动态查找来使用它.苹果似乎并不介意.该API使用起来非常简单,并且有很多开放的示例源代码.

I solved this ages ago but I only just noticed I never posted it here. The answer ended up involving CGSSetGlobalHotKeyOperatingMode(). This is not a public API, but there are a number of Mac App Store apps which use it by obfuscating the function name and looking it up dynamically. Apple doesn't seem to mind. The API is pretty straightforward to use, and there's plenty of open example source code floating about.

这篇关于macOS App:处理绑定到全局键盘快捷键的组合键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆