监听键盘鼠标事件
今儿要做一个监听全局的键鼠事件的操作,之前使用的都是指监听应用内某一个控件的事件
只需要空间是继承 NSResponder
的就可以了,按需实现下面的方法就行了
每个键盘上的按键都有一个对应的编码,下面是针对command c
和command v
的处理,c
和v
分别对应编码是8
和9
,command
对应的是NSEventModifierFlagCommand
。记得把事件传递下去
1 | typedef NS_ENUM(unsigned short, LBKeyboardCode) { |
创建监听
1 | CGEventTapLocation tapLocation = kCGHIDEventTap; |
正常处理
1 | CGEventRef _captureKeyStroke(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* userInfo) |
超时处理
如果回调的处理时间过长,这个事件会被置为失效,重新设置下可以就可以了。
由于监听的事件调用特别频繁,还是要注意下对于事件处理的效率问题。
1 | if (type == kCGEventTapDisabledByTimeout) { |
调试
在.plist 文件添加下面的内容
1 | <key>NSAppleEventsUsageDescription</key> |
调试的时候比较麻烦,
第一次运行会提示:
需要在 system preferences -> security -> privacy -> accessibility
里面添加并勾选
然后每次调试前都要在这个设置里面先删除,然后再添加勾选,特别蛋疼。暂时还不知道有啥好的解决办法
NSEvent
还有可以通过 NSEvent 的API 来做事件监听
1 | + (nullable id)addGlobalMonitorForEventsMatchingMask:(NSEventMask)mask handler:(void (^)(NSEvent*))block NS_AVAILABLE_MAC(10_6); |
Global是全局的(除自己的 app 之外的 event),local就是监听自己 app 的 event。
关于 NSEventMask 暂时不清楚为什么设置的 NSEventMaskAny 有些事件并不能响应,比如触摸板的双指滑动。
使用 Global 的时候,会有监听不到其他应用的键盘输入事件的时候,比如微信、QQ等输入事件。
参考
- https://developer.apple.com/documentation/coregraphics/quartz_event_services?language=objc
- https://stackoverflow.com/questions/10365487/segmentation-fault-11-cgeventtap-application-stops-processing-mouse-events-aft
- https://forums.developer.apple.com/thread/109283
- https://stackoverflow.com/questions/2969110/cgeventtapcreate-breaks-down-mysteriously-with-key-down-events