我想编写一个应用程序来捕获媒体键事件并对其进行修改以供进一步使用。在引用https://github.com/nevyn/SPMediaKeyTap之后,我使用Swift 4启动了我的代码,如下所示:
func tapEventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? {
let keyCode = event.getIntegerValueField(.keyboardEventKeycode)
print("Key code: \(keyCode)")
return Unmanaged.passRetained(event)
}
class MediaKeyTaps: NSObject {
var eventPort: CFMachPort?
var eventPortSources: CFRunLoopSource?
@objc func eventTapThread() {
let tapThreadRL = CFRunLoopGetCurrent()
CFRunLoopAddSource(tapThreadRL, eventPortSources, .commonModes)
print(CGEvent.tapIsEnabled(tap: eventPort!))
CFRunLoopRun()
}
func startListening() {
eventPort = CGEvent.tapCreate(tap: .cgSessionEventTap, place: .headInsertEventTap, options: .defaultTap, eventsOfInterest: CGEventMask(NX_SYSDEFINED), callback: tapEventCallback, userInfo: UnsafeMutableRawPointer(Unmanaged.passRetained(self).toOpaque()))
if let eventPort = eventPort {
print("Succeed to create tap…")
eventPortSources = CFMachPortCreateRunLoopSource(kCFAllocatorSystemDefault, eventPort, 0)
Thread.detachNewThreadSelector(#selector(eventTapThread), toTarget: self, with: nil)
} else {
fatalError("Failed to create event tap…")
}
}
}
一个非常奇怪的事情是,如果我从终端运行此代码,通过运行swift test.swift
,它可以工作,但只能获取鼠标按钮事件。错过了所有键盘按键事件。但是,如果将这些代码放入Cocoa应用程序项目并从Xcode运行,则CGEvent.tapCreate
将返回nil
。另外,我检查了AXIsProcessTrusted()
的返回值,即true
。