我正在编写一个简单的 Cocoa 应用程序,该应用程序将从 AppleScript 启动,只是为了将 Quartz 事件发布到另一个应用程序。
不需要用户界面,因此我从 Interface Builder 中删除了窗口,并从 Application Delegate 中删除了它的出口。postClickEvent()
我从方法中调用私有方法applicationDidFinishLaunching(_:)
。我用 nil mouseEventSource at初始化leftMouseDown
和CGEvents并将它们发布在 location 。leftMouseUp
mouseCursorPosition (x: 0, y: 0)
cghidEventTap
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
postClickEvent()
}
func applicationWillTerminate(_ aNotification: Notification) {
}
private func postClickEvent() {
let point = CGPoint(x: 0, y: 0)
let leftMouseDownEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left)
let leftMouseUpEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left)
leftMouseDownEvent?.post(tap: .cghidEventTap)
leftMouseUpEvent?.post(tap: .cghidEventTap)
}
}
我希望该应用程序在启动后立即单击左上角并打开 Apple 菜单,但它没有发生。
我可以想到几种可能的解决方案。
- 在调试器中运行的应用程序可能需要发布低级用户输入事件的权限。应用程序是否需要获得发布 Quartz 事件的权限?
- 该方法
applicationDidFinishLaunching(_:)
由默认通知中心在应用程序启动和初始化之后但在收到第一个事件之前发送。也许postClickEvent()
应该从 Application Delegate 的另一个方法调用? - 这些事件在初始化时可能需要一个事件源。但是为三个可能的事件源状态 ID 中的任何一个传递初始化的
init(stateID:)
事件源都不会改变它。 - 事件可以在应用程序在全屏 Xcode 后获得焦点时发布,太早而无法单击 Apple 菜单项。但是让线程休眠 10 秒并不会改变它。