添加带有NSEventMaskKeyDown掩码的全局监视器不会触发 [英] Adding a global monitor with NSEventMaskKeyDown mask does not trigger

查看:178
本文介绍了添加带有NSEventMaskKeyDown掩码的全局监视器不会触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MacOS菜单栏应用程序,该应用程序需要跟踪一些全局快捷方式,以便于调整外部监视器的显示亮度.但是,我无法在任何与键盘相关的事件上触发处理程序(鼠标事件可以正常工作).

I'm working on a MacOS menu bar app which needs to track some global shortcuts in order to facilitate adjusting display brightness on external monitors. However, I cannot get it to fire a handler on any keyboard related events (mouse events work just fine).

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

I'm checking Accessibility with the following code

NSDictionary *options = @{CFBridgingRelease(kAXTrustedCheckOptionPrompt): @YES};
BOOL accessibilityEnabled = AXIsProcessTrustedWithOptions((CFDictionaryRef)options);

然后,我使用以下命令添加一个全局事件监视器:

Then, I'm adding a global event monitor using:

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

如果我将NSEventMaskKeyDown切换为NSEventMaskMouseMove或其他与鼠标相关的功能,则一切正常.如果我尝试NSEventMaskAny,则什么都不会再次触发(这很奇怪,因为它应该仍然在鼠标上触发).

If I switch NSEventMaskKeyDown to NSEventMaskMouseMove or something else mouse related, everything works fine. If I try NSEventMaskAny, nothing triggers again (which seems strange, as it should trigger on mouse still).

推荐答案

NSEventMaskMouseMove有效但NSEventMaskKeyDown无效的事实明确表明您的应用当前完全填充了所有内容跟踪关键事件所需的要求. NSEventMaskMouseMove不被认为是需要特殊安全保护的事件,甚至在AXIsProcessTrustedWithOptions返回false时也可以使用.

The fact that NSEventMaskMouseMove works but NSEventMaskKeyDown doesn't is a clear sign that your app currently does not fullfill all requirements needed for tracking key events. NSEventMaskMouseMove is not considered as an event that needs special security protection and even works when AXIsProcessTrustedWithOptions returns false.

关键事件需要更多权限,如 Charles Srstka 所述.com/a/45994269/251839>此答案:

Key events require more permissions as mentioned by Charles Srstka in this answer:

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

The reason this doesn't work is because global monitors for .keyDown events require more permissions than some of the other event handlers, including the one that somebody thought this was a duplicate of. This is mainly because global .keyDown monitors can be used for nefarious purposes, such as keyloggers. So there are additional security measures in place to make sure we're legit:

1)您的应用需要进行代码签名.

1) Your app needs to be code-signed.

2)您的应用无需启用应用沙箱,并且:

2) Your app needs to not have the App Sandbox enabled, and:

3)您的应用需要在安全性和隐私权中注册 偏好设置窗格中,在辅助功能"下.

3) Your app needs to be registered in the Security and Privacy preference pane, under Accessibility.

您需要在应用目标的常规"窗格中启用代码签名.确保同时设置了团队"和签名证书":

You need to enable code-signing in the General pane of your app target. Make sure that both "Team" and "Signing Certificate" are set:

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

You also have to disable the "App Sandbox" in the Capabilities pane:

请注意,为了满足第三个要求,您还需要将Xcode本身添加到可访问性"窗格中.否则,您希望能够调试事件监视.

Please note, that in order the meet the third requirement you als need to add Xcode itself to the Accessibility pane. Otherwise you want be able to debug your event monitoring.

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

Two more tips regarding key events:

  • Global monitoring only report events that occur in other apps. To monitor events in your own apps you need to use addLocalMonitorForEventsMatchingMask or the implementations from the Cocoa Event Handling Guide.
  • Key events sent to secure text field are masked, as mentioned by Jeff in this answer:
发送给NSSecureTextField(或NSSecureTextFieldCell)的

键事件被屏蔽,因此任何事件监视器都无法截获或读取它们.这是一项安全功能,可防止应用程序在键入密码时窃取密码,而且没有API可以解决.

Key events sent to NSSecureTextField (or NSSecureTextFieldCell) are masked so that no event monitor can intercept or read them. This is a security feature to prevent applications from stealing passwords as they're typed, and there's no API to get around it.

关于与AppStore兼容的全局快捷方式的说明:很明显,您无法将应用程序上载到禁用了沙箱的AppStore.如果您打算通过Mac AppStore(MAS)分发您的应用程序,则必须使用其他API. 此线程提到了一堆解决方案,对MAS友好.他们使用 Carbon 年代的RegisterEventHotKey API.苹果承诺 拒绝使用它的应用.

A note about AppStore-compatible global shortcuts: It's clear that you can't upload an app to the AppStore that has its sandbox disabled. If you plan to distribute your app via the Mac AppStore (MAS) you have to use a different API. This thread mentions a bunch of solutions that are MAS-friendly. They use the RegisterEventHotKey API from the old Carbon days. Apple promised to not reject apps that use it.

这篇关于添加带有NSEventMaskKeyDown掩码的全局监视器不会触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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