Swift脚本化鼠标移动在ScheduledTimer中不可靠

时间:2018-10-16 11:26:22

标签: swift xcode macos

我正在尝试编写一段代码,将屏幕上的鼠标光标移动到指定位置。这是我尝试实现的一些方法:

下面的代码将在所有尝试中使用(禁用沙箱操作):

let mouseCursorPosition = CGPoint.zero;
CGAssociateMouseAndMouseCursorPosition(1)

尝试1:

CGWarpMouseCursorPosition(mouseCursorPosition)

尝试2:

CGDisplayMoveCursorToPoint(CGMainDisplayID(), CGPoint.zero)

尝试3:

let moveEvent = CGEvent(mouseEventSource: nil, mouseType: CGEventType.mouseMoved, mouseCursorPosition: mouseCursorPosition, 
mouseButton: CGMouseButton.left)
moveEvent?.post(tap: CGEventTapLocation.cghidEventTap)

预期的行为:更新鼠标位置以及屏幕上的光标。

如果直接在viewDidLoad()内部调用,到目前为止,所有尝试都可以按预期进行。应用程序加载后,光标将立即移动到请求的屏幕位置。但是,在scheduledTimer中调用时,事情变得有些奇怪。使用以下代码:

class ViewController: NSViewController {
    var mouseTimer: Timer!

    override func viewDidLoad() {
        super.viewDidLoad()

        mouseTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(moveCursor), userInfo: nil, repeats: true)
    }

    @objc func moveCursor() {
        print(NSDate().timeIntervalSince1970)

        let mouseCursorPosition = CGPoint.zero;
        CGAssociateMouseAndMouseCursorPosition(1)

        //insert attempt code here
    }
}

每5秒调用一次moveCursor方法(每次都会显示时间戳),但是只要我不移动物理鼠标,光标就不会在屏幕上移动。但是,当我移动鼠标时,光标首先会捕捉到最后一个脚本位置。似乎发生的是脚本位置已注册,但是直到触发某种刷新事件后,屏幕上的位置才会更新。

对此事的任何想法都将受到赞赏。

1 个答案:

答案 0 :(得分:1)

我无法在macOS 11.14上重现此问题。我使用情节提要创建了一个新的Cocoa应用程序,并将ViewController.swift编辑为以下内容:

import Cocoa

class ViewController: NSViewController {
    var mouseTimer: Timer!

    override func viewDidLoad() {
        super.viewDidLoad()
        mouseTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(moveCursor), userInfo: nil, repeats: true)

    }

    @objc func moveCursor() {
        print(NSDate().timeIntervalSince1970)
        let mouseCursorPosition = CGPoint.zero;
        CGAssociateMouseAndMouseCursorPosition(1)
        CGWarpMouseCursorPosition(mouseCursorPosition)
    }
}

然后我在Xcode下运行它。 5秒钟后(及其后每5秒钟)将打印一个时间戳,并且光标跳到左上角。我可以将光标移到其他位置,然后它会再次跳转。

无论是否调用CGAssociateMouseAndMouseCursorPosition,我都有相同的行为。 (我不确定为什么要在测试中调用它;默认值为1。)


根据您的评论进行了更新,但我仍然无法复制:

import Cocoa

class ViewController: NSViewController {
    var mouseTimer: Timer!

    override func viewDidLoad() {
        super.viewDidLoad()
        mouseTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(moveCursor), userInfo: nil, repeats: true)

    }

    @objc func moveCursor() {
        let mouseCursorPosition = CGPoint(x: Int.random(in: 0...500), y: Int.random(in: 0...500))
        print("\(Date().timeIntervalSince1970): \(mouseCursorPosition)")
        CGWarpMouseCursorPosition(mouseCursorPosition)
    }
}

每5秒钟,无论我是否移动鼠标指针,这都会导致鼠标指针跳到一个新位置。这与您的代码相同吗?