swift - MacOS Quartz Event Tap 监听错误事件
问题描述
我正在尝试使用CGEvent.tapCreate(tap:place:options:eventsOfInterest:callback:userInfo:)
如下所示的方法拦截鼠标移动事件:
let cfMachPort = CGEvent.tapCreate(tap: CGEventTapLocation.cghidEventTap,
place: CGEventTapPlacement.headInsertEventTap,
options: CGEventTapOptions.defaultTap,
eventsOfInterest:CGEventMask(CGEventType.mouseMoved.rawValue),
callback: {(eventTapProxy, eventType, event, mutablePointer) -> Unmanaged<CGEvent>? in event
print(event.type.rawValue) //Breakpoint
return nil
}, userInfo: nil)
let runloopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, cfMachPort!, 0)
let runLoop = RunLoop.current
let cfRunLoop = runLoop.getCFRunLoop()
CFRunLoopAddSource(cfRunLoop, runloopSource, CFRunLoopMode.defaultMode)
如文档中所示,eventsOfInterest
mouseMoved
我将原始值为 5 的事件类型事件作为事件类型传递。但由于某种原因,除非我用鼠标单击,否则 my 不会执行。在调试器中检查发送鼠标事件会给我一个原始值 2,根据文档,这是一个事件。print()
leftMouseUp
在它的文档中CGEvent.tapCreate(tap:place:options:eventsOfInterest:callback:userInfo:)
说:
事件点击接收按键向上和按键向下事件 [...]
所以看起来该方法mouseMoved
通常会忽略事件?!但是我应该如何收听mouseMoved
事件呢?我试图阻止我的光标(自定义光标)被替换(例如,当我将鼠标悬停在屏幕底部的应用程序坞上时)。
解决方案
您需要对CGEventType
用于创建CGEventMask
参数的值进行位移。在 Objective-C 中,有一个宏可以做到这一点:CGEventMaskBit。
从CGEventMask
文档中:
要形成位掩码,请使用 CGEventMaskBit 宏将每个常量转换为事件掩码,然后将各个掩码 OR 在一起
我不知道 swift 中的等效机制;但宏本身看起来像这样:
*/ #define CGEventMaskBit(eventType) ((CGEventMask)1 << (eventType))
在您的示例中,只需手动移动参数就足够了;例如
eventsOfInterest:CGEventMask(1 << CGEventType.mouseMoved.rawValue),
我要指出,问题中给出的代码示例有点危险;因为它创建了一个默认事件点击,然后删除事件而不是允许它们被处理。这会打乱鼠标单击处理,并且使用鼠标实际终止应用程序很棘手。运行该示例的任何人都可以将事件点击类型设置为CGEventTapOptions.listenOnly
以防止这种情况发生。
推荐阅读
- django - 在 Django 中使用 API 以及如何显示数据
- c# - 在没有 libusb 的情况下在 C# 中获取 USB 设备描述符?
- ssl - oauth2_proxy 不要求身份验证
- html - 如何在css中制作动态字体颜色
- javascript - 小屏幕的 HTML 高度/宽度属性覆盖
- sql - 计算其他列中 ID 的出现次数
- cassandra-3.0 - 在不提供主键的情况下查询表的最佳方式
- javascript - 如何上传 zip 多部分表单文件,将其提取并即时上传到 S3?
- atlassian-sourcetree - SourceTree 藏在哪里?
- javascript - 将字符串转换为二维数组