如何在Mac应用程序中模拟鼠标点击到其他应用程序?

25

我正在尝试使用CGEvents从macOS应用程序模拟在iPhone模拟器上的鼠标点击。

iPhone模拟器的进程ID为33554。

let point = CGPoint(x: 500  , y:300)
let eventMouseDown = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left)
let eventMouseUp = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left)
eventMouseDown?.postToPid(33554)
eventMouseUp?.postToPid(33554)

我还注意到,当 iOS 模拟器窗口处于焦点状态时,它会模拟鼠标点击并且仅适用于此工具栏,但不适用于模拟器。例如,如果我将 CGPoint 更改为 (0, 30),它将在模拟器选项上单击。

enter image description here

但是,当我给出点击 iOS 模拟器内应用的 CGPoints 时,它不起作用。 enter image description here

然而,我可以使用以下方法向模拟器发送键盘事件:

let keyboardDown = CGEvent(keyboardEventSource: nil, virtualKey: 6, keyDown: true)
let keyboardUp = CGEvent(keyboardEventSource: nil, virtualKey: 6, keyDown: false)
keyboardDown?.postToPid(33554)
keyboardUp?.postToPid(33554)

2
你还记得在 macOS 上 y 轴是反向的吗? - Alistra
你找到解决方法了吗?我有完全相同的问题。键盘事件运行得很好,但鼠标却不行。 - Juan Pedro Lozano
4个回答

15

首先,如果你看postToPid,那么根本没有任何文档说明。

PostToPID

因此甚至不确定它是否应该起作用,如果是的话,在什么情况下起作用,以及在什么情况下不起作用。但是你可以使用以下代码直接将事件发布到屏幕。

//
//  main.swift
//  mouseplay
//
//  Created by Tarun Lalwani on 22/05/18.
//  Copyright © 2018 Tarun Lalwani. All rights reserved.
//

import Foundation

let source = CGEventSource.init(stateID: .hidSystemState)
let position = CGPoint(x: 75, y: 100)
let eventDown = CGEvent(mouseEventSource: source, mouseType: .leftMouseDown, mouseCursorPosition: position , mouseButton: .left)
let eventUp = CGEvent(mouseEventSource: source, mouseType: .leftMouseUp, mouseCursorPosition: position , mouseButton: .left)


eventDown?.post(tap: .cghidEventTap)

//eventDown?.postToPid(71028)
usleep(500_000)
//eventUp?.postToPid(71028)
eventUp?.post(tap: .cghidEventTap)

print("Hello, World!")

你也可以看到它的运行效果

运行演示


我已经让 postToPid 成功处理键盘事件,但对于鼠标事件需要使用 post(tap:)。 - dldnh
请问您能否告诉我如何使postToPid在键盘事件中起作用? - Tarun Lalwani
你可以在这里查看我的实现:https://github.com/dldnh/sendkey/blob/master/main.swift - 希望能帮到你! - dldnh
请确保您已经在辅助功能设置中允许您的应用程序控制此计算机,以使其正常工作。 - TimD

6

您说您能够发布键盘事件,因此这不太可能是权限问题,但您可以尝试以root身份执行程序来排除这种可能性。

事件坐标可能与您预期的不同(翻转?)。尝试在模拟应用程序中设置一些内容,以报告应用程序级别上接收到的所有事件。

此外,坐标是否在屏幕坐标系统中?也许事件被模拟器接收并丢弃,因为没有窗口“在其下方”将其传递。尝试将模拟器窗口移动到屏幕的每个角落,并使用类似于(10,10)的坐标。

您还可以尝试使用NSEvent及其CGEvent方法获取底层cgevent,该方法可能已正确初始化以满足您的需求。如果成功了,那么更容易找出您缺少的内容。

最后,尝试不要nil传递给mouseEventSource。像CGEventSourceRef eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);这样的东西怎么样?

最后的帮助尝试:

我有一个(旧的)mac应用程序,将制造的鼠标事件分派到其他程序;也许它的源代码可以揭示一些有用的信息。

现在……如果所有这些都不起作用,您最好告诉我们您正在尝试实现什么。可能有更好的方法。


4

你就快做对了(Swift 4):

let mousePosition: CGPoint = .zero // your position here
let mouseEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, 
mouseCursorPosition: mousePosition, mouseButton: .left)
mouseEvent?.postToPid(33554)

一开始没有意识到的一个重要细节是,必须禁用应用程序沙箱才能使用此API。


0

在这里发布问题,因为这个问题在谷歌上关于在OS X中发送点击事件的最热门问题。

您可以查看工作中的拖放示例并创建一个点击函数。

只有一个注意事项,您要点击的窗口必须可见。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接