macOS 应用程序:处理绑定到全局键盘快捷键的组合键

2024-01-02

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

我们希望在我们正在开发的应用程序中实现这样的模式,但很难弄清楚如何做到这一点。我应该指出,有问题的应用程序是常规的前台应用程序,是沙盒的,任何解决方案都必须遵守应用程序商店规则。商店中的其他应用程序可以做到这一点这一事实意味着这一定是可能的。

需要明确的是,我们想要:

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

Apple's 事件架构文档 https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW11表明前台应用程序应该已经接收到这些事件。 (它只讨论早期级别处理诸如电源和弹出按钮之类的事情,这很好。)它继续建议,并且关键事件文件还暗示 https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/EventOverview/HandlingKeyEvents/HandlingKeyEvents.html#//apple_ref/doc/uid/10000060i-CH7-SW11 that NSApplication's sendEvent:方法是根据修饰符标志检测潜在的快捷方式,将它们分派到窗口,如果失败,则分派到菜单栏。没有明确说明全局绑定的快捷方式会发生什么。

我尝试过子类化NSApplication并压倒一切sendEvent:。无论我是否将所有事件传递给超类实现,或者如果我说过滤修饰键事件,当我按 ⌘-Space 时,我都会收到按下和释放命令 (⌘) 键的事件,但不会收到空格键的事件。 Spotlight UI 始终会弹出。

我还没有从 Apple 或其他地方找到太多有关 NSApplication 子类及其早期事件处理的信息。我似乎无法找出在什么级别检测和处理全局快捷方式。

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

可能无效的解决方案:

我在其他 Stack Overflow 帖子中看到的建议,但不适用于我见过的执行此操作的其他应用程序(并且会违反 App Store 规则):

  • 辅助功能 API(需要特殊许可)
  • 事件点击/挂钩(需要以 root 身份运行)

无论如何,这两种方法都太过分了,因为它们可以让你拦截all活动于all次,而不仅仅是当您的应用程序是前台应用程序时。

NSevent's addGlobalMonitorForEventsMatchingMask:handler:同时并不能阻止全局快捷方式处理程序为这些事件触发,所以我什至懒得尝试它。


好吧,Cocoa 事件方法和 Quartz 事件点击已经过时了,因为它们要么需要 root 访问权限,要么需要可访问权限,或者不会在 Dock 之前捕获事件。

碳的PushSymbolicHotKeyMode已退出,因为根据文档,它需要可访问性访问。

碳的RegisterEventHotKey可能是因为苹果似乎不允许它(请参阅我对问题的评论中的链接)。然而,即便如此,我测试过,你不能用它来捕获 Command+Tab。

我快速证明了这一点can工作,但是 YMMV:

  • 实施KeyboardWatcher来自此的示例类answer https://stackoverflow.com/a/39834889/233944。您需要链接 IOKit。
  • 添加硬件 - USB (com.apple.security.device.usb) 沙箱权利。这是必要的,因为 KeyboardWatcher 使用 HID 来捕获按键操作
  • the Handle_DeviceEventCallback会给你按下的键。显然你可以根据你的需要修改它
  • Use 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 用户,或者为您的应用程序启用辅助功能访问权限。

在当前的沙箱规则中似乎不可能使用事件点击。这在开发者论坛 https://devforums.apple.com/message/742845#742845。该链接仅供登录,但引用线程:

是否有机会通过阻止启动 iTunes 来处理来自媒体键的事件。在沙箱之前,可以通过创建 CGEvent Tap 来实现,但不能使用 hid-controll 来拒绝沙箱。

不,目前在应用程序沙箱中不可能实现这一点。

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

VMWare Fusion 显然没有沙盒化,苹果自己的应用程序不受这些规则的约束。请记住,沙盒仅对 2012 年推出后添加的新应用程序强制执行。该日期之前添加的应用程序不会强制执行沙盒。看到这个answer https://stackoverflow.com/a/32248238/233944.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

macOS 应用程序:处理绑定到全局键盘快捷键的组合键 的相关文章

  • 在“读取初始通信数据包”时失去与 MySQL 服务器的连接,系统错误:61

    3天了 已经碰壁了 我正在运行 mac os x 我已经安装了mysql 5 5 14 osx10 6 x86 64 dmg 就上下文而言 我需要安装 mysql gem 以便与 ruby on Rails 一起使用 除非有一个有效的 my
  • 使用常量 NSString 作为 NSUserDefaults 的键

    我正在使用 NSUSerDefaults 来存储用户首选项 我记得在某处读到过 将键设置为常量是一个好主意 我同意 以下代码是我目前拥有的 NSUserDefaults standardUserDefaults setObject NSNu
  • 如何使用 Objective-C 在 Mac Os X 中模拟 Unicode Char“按键”?

    我想在 Mac OS X 中模拟 unicode 字符发送到前台应用程序 我的意思是我有一个像 a 这样的unicode char 可以包含阿拉伯语 中文等 我想输入它 请注意 我并不是尝试使用虚拟按键或按键代码 只有一个角色 您忠诚的 佩
  • vim - 如何删除 netrw?

    我正在测试https github com skwp dotfiles https github com skwp dotfiles 不幸的是它确实安装了很多我不想要的东西 例如 现在 使用空的 vimrc 当我打开 vim 时 我得到 N
  • Visual Studio 的“右键单击”键盘快捷键?

    我试图强迫自己尽可能少地使用鼠标 但我在任何地方都找不到这个简单快捷方式的答案 步骤如下 打开 Visual Studio 打开任何 C 文件 或我认为的任何代码文件 将鼠标指向任意位置 窗口 文件 右键点击 是否有一个快捷键 这样我就不必
  • Sequel Pro / MAMP 在哪里存储本地数据库?

    我通过 Sequel Pro 和 MAMP 在我的计算机上创建了一些数据库 并运行 localhost 来查看它们 但是 我全新安装了 Mac OS Lion 但忘记将数据库备份到 sql 文件 我会定期备份文件 并预装计算机的副本 有谁知
  • 应用程序更新后,辅助功能权限会重置

    我制作了一个应用程序 要求用户授予访问功能的权限 当应用程序首次启动并请求可访问性时 它的工作方式如下 const void keys kAXTrustedCheckOptionPrompt const void values force
  • 使用 ImageMagick 进行 SVG 转换无法正确应用翻译

    我使用的是 Mac OS X 10 5 的 Mac 我正在尝试使用 ImageMagick 来转换SVG http en wikipedia org wiki Scalable Vector Graphics文件到一个PNG http en
  • 将 NSDictionary 保存到 plist

    我正在使用这篇文章中找到的代码 Plist 中的多个数组 https stackoverflow com questions 6192451 mulitple arrays from plist 6193397 6193397 具有相同的
  • $PATH 中 /usr/bin 和 /usr/local/bin 等的顺序

    在我的 Mac 上 我经常使用 bash 对于我的环境设置 我添加了 usr bin and usr local bin into PATH就像我平常做的那样 虽然我知道什么 usr bin and usr local bin关于 我很好奇
  • Java中如何做系统捷径跨平台集成?

    您可能知道 Mac OS X 中保存的快捷键是Cmd S在 Windows 上是Ctrl S 关闭应用程序的捷径是Cmd QWindows 是Alt F4 但问题是如何在 java 应用程序中执行这些操作 我是否需要找到我在应用程序中使用的
  • bash 别名中允许使用哪些字符[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我最近添加了 alias cd alias cd alias cd 到我的 bash aliases 文件 玩弄这个 我注意到在别名时 被
  • 如何在 R 中使用相对路径从 mac 上的目录读取数据?

    我正在编写需要同时适用于 Mac 和 Windows 用户的代码 所有用户的计算机上都有 google 驱动器目录的本地副本 我有一段代码可以自动将工作目录设置为源文件位置 我们将此目录称为 directory1 在directory1 中
  • NSDateComponents - EXC_BAD_ACCESS 错误

    我确信有一个简单的答案的基本问题 我正在尝试获取照片的时间戳 当我尝试访问 NSDateComponents 以检索特定日期元素 例如 日 时 我收到 EXC BAD ACCESS 错误 首先 我的代码的相关部分 formattedDate
  • Matlab 编辑器不使用 emacs 快捷方式

    Is there some way I can make the matlab integrated editor not use emacs shortcut but use more normal shortcuts such that
  • 如何为 Windows 和 macOS 更新 PyQT5 应用程序?

    我有一个使用 PyQT5 为 Windows 和 macOS 构建的应用程序 目前 用户通过单击按钮检查更新 当有可用的新更新时 我将它们重定向到浏览器到我的服务器以下载最新的 exe Windows 或 pkg macOS 问题在于 如果
  • OSX 上的 XAMPP 默认文件夹

    入门手册说我可以将文件放入 Applications XAMPP htdocs 文件夹和 Sites 文件夹中 但是当我将文件放入 Sites 文件夹中时 它会出现以下错误 Server error The server encounter
  • OSX/Cocoa 应用程序通常使用什么位置来存储数据文件?

    他们是否将它们写入 存储在应用程序包 包本身中 或者其他一些规范位置 还是好像没有什么标准 文件通常会进入 Library Application Support Your App 偏好设置进去 Library Preferences
  • 如何创建无法创建新文档的基于文档的应用程序?

    我有一个基于文档的应用程序 旨在处理现有文档 而不是创建新文档 如何防止应用程序在通过 Finder 打开应用程序时创建新的空白文档 您可以实现一个 NSApplication 委托协议方法 BOOL applicationShouldOp
  • Ctrl-退格键 Visual Studio 2010

    I recently upgraded to Visual Studio 2010 and found out that when I press Ctrl Backspace on an empty line it will delete

随机推荐