添加带有 NSEventMaskKeyDown 掩码的全局监视器不会触发

Cat*_*inM 3 macos nsevent keydown

我正在开发一个 MacOS 菜单栏应用程序,它需要跟踪一些全局快捷方式,以便于调整外部显示器上的显示亮度。但是,我无法让它在任何键盘相关事件上触发处理程序(鼠标事件工作得很好)。

我正在使用以下代码检查可访问性

NSDictionary *options = @{CFBridgingRelease(kAXTrustedCheckOptionPrompt): @YES};
BOOL accessibilityEnabled = AXIsProcessTrustedWithOptions((CFDictionaryRef)options);
Run Code Online (Sandbox Code Playgroud)

然后,我使用以下方法添加全局事件监视器:

self.eventMonitor = [NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown handler:^(NSEvent * event) {
    NSLog(@"Some event");
}];
Run Code Online (Sandbox Code Playgroud)

如果我切换NSEventMaskKeyDown到鼠标NSEventMaskMouseMove或其他与鼠标相关的东西,一切都会正常。如果我尝试NSEventMaskAny,不会再次触发任何内容(这看起来很奇怪,因为它仍然应该在鼠标上触发)。

mxg*_*gzf 7

NSEventMaskMouseMove有效但NSEventMaskKeyDown无效的事实清楚地表明您的应用程序当前满足跟踪关键事件所需的所有要求。NSEventMaskMouseMove不被认为是需要特殊安全保护的事件,甚至AXIsProcessTrustedWithOptions返回时也有效false

正如Charles Srstka此答案中提到的,关键事件需要更多权限:

这不起作用的原因是因为 .keyDown 事件的全局监视器比其他一些事件处理程序需要更多的权限,包括有人认为这是重复的事件处理程序。这主要是因为全局 .keyDown 监视器可用于恶意目的,例如键盘记录器。因此,我们采取了额外的安全措施来确保我们的合法性:

1) 您的应用程序需要进行代码签名。

2) 您的应用程序不需要启用应用程序沙箱,并且:

3) 您的应用程序需要在“安全和隐私”首选项窗格中的“辅助功能”下注册。

您需要在应用程序目标的“常规”窗格中启用代码签名。确保“团队”和“签名证书”均已设置:

打开代码签名

您还必须在“功能”窗格中禁用“应用程序沙箱”:

关闭沙箱

请注意,为了满足第三个要求,您还需要将 Xcode 本身添加到“辅助功能”窗格中。否则您希望能够调试您的事件监控。

关于关键事件的另外两个提示:

发送到NSSecureTextField(或NSSecureTextFieldCell) 的按键事件被屏蔽,以便事件监视器无法拦截或读取它们。这是一项安全功能,可防止应用程序在输入密码时窃取密码,并且没有 API 可以绕过它。

关于与 AppStore 兼容的全局快捷方式的注意事项:很明显,您无法将应用程序上传到禁用沙箱的 AppStore。如果您计划通过 Mac AppStore (MAS) 分发应用程序,则必须使用不同的 API。该帖子提到了一系列 MAS 友好的解决方案。他们使用RegisterEventHotKeyCarbon时代的 API。苹果承诺不会拒绝使用它的应用程序。