#swift #macos #mouse
Вопрос:
поэтому мне нужно иметь возможность перемещать мышь в любую заданную точку (x и y). Я пытаюсь сделать это с помощью CGDisplayMoveCursor, пока он перемещает курсоры, он не помещает их туда, куда я ожидаю. У меня в настройках два монитора. Я получаю кадр через NSScreen.screens[i].кадр, и это их кадры.
Built-in Retina Display
NSRect (0.0, 0.0, 1440.0, 900.0)
SwitchResX4 - LG HDR WQHD
NSRect (-1186.0, 900.0, 3840.0, 1600.0)
Затем, когда я получаю новую точку, я использую NSRect.contains(NSPoint)
ее, чтобы найти, какой из двух мониторов содержит эту точку. Эта часть работает так, как и ожидалось.
Но затем я хочу переместить курсор в эту точку, но это работает не так, как вы ожидали (курсор перемещается, но не в точки, как вы ожидали бы, основываясь на кадрах). Вот код для этого.
let point = NSPoint(x: x, y: y)
guard let monitor = Monitor.displayIdWithPoint(point) else {
SendlogCallbackEvent("D", "", "Found nil in monitor with point", #function, #file, #line)
}
if CGDisplayMoveCursorToPoint(monitor.directDisplayId, point) == CGError.failure {
SendlogCallbackEvent("D", "", "CGError.failer to move cursor", #function, #file, #line)
}
Я читал, что это, вероятно, связано с тем, как CG и NS по-разному обрабатывают систему координат, но я не смог понять, как заставить ее работать. Как мне «преобразовать» свою точку NSPoint в точку CG, чтобы она работала с функцией CGDisplayMove…. Или как лучше всего это сделать.
Ответ №1:
Этот фрагмент вашего кода:
let point = NSPoint(x: x, y: y)
guard let monitor = Monitor.displayIdWithPoint(point) else {
SendlogCallbackEvent("D", "", "Found nil in monitor with point", #function, #file, #line)
}
у меня создается впечатление, что point
вы смотрите вверх-это точка в координатном пространстве оконной системы (координатное пространство, в котором описаны эти две оконные рамы).
Но , глядя на документацию CGDisplayMoveCursorToPoint(_:_:)
, мы видим (курсив мой):
точка
Координаты точки в локальном пространстве отображения. Начало координат-это верхний левый угол указанного дисплея.
Поэтому я думаю , что вам нужно будет взять свой point
и преобразовать его так, чтобы он был относительно источника желаемого отображения:
let pointRelativeToScreen = point - monitor.frame.origin
if CGDisplayMoveCursorToPoint(monitor.directDisplayId, pointRelativeToScreen) == CGError.failure { ... }
В качестве альтернативы может существовать какой-либо другой API, который ожидает, что точка курсора будет выражена в координатах оконной системы, что автоматически выведет ее на нужный вам экран. У меня сейчас нет доступа к Xcode, поэтому я не могу проверить это сам.
Комментарии:
1. да, это сработало. Я думал, что хорошо прочитал документацию, но, очевидно, я этого не сделал. Спасибо. Я также попытался CGEvent создать событие .mouseMove, но, похоже, это работает только на главном экране? хотя я был довольно расстроен и мог просто поступить неправильно.