スクリーン座標
Mac の スクリーン座標 は、メインディスプレイの左下が原点 (x:0, y:0)
です。
他の OS では左上が原点でしょうから、macOS は独特です。
マルチディスプレイの構成
CGGetActiveDisplayList
を使用すると ディスプレイの枚数を、CGDisplayBounds
を使用すると ディスプレイの配置・サイズを得ることができます。
import AppKit
var displays = [CGDirectDisplayID](repeating: 0, count: 32)
var count = UInt32(0)
if CGGetActiveDisplayList(32, &displays, &count) != .success {
print("failed to get display list")
}
for n in 0 ..< Int(count) {
let displayID = displays[n]
print("DisplayID: \(displayID)", CGDisplayBounds(displayID))
}
DisplayID: 2 (0.0, 0.0, 2560.0, 1440.0)
DisplayID: 1 (-1440.0, -540.0, 1440.0, 2560.0)
上記の結果から、自分のディスプレイ環境は 下図の構成であることが分かります。
なお、CGDisplayBounds(0)
でメインディスプレイの情報を得ることができます。
マウスカーソルの現在位置
NSEvent.mouseLocation
で、マウスカーソルの現在位置を取得することができます。
var lastPos = CGPoint.zero
while true {
Thread.sleep(forTimeInterval: 0.1) //100ms
let mousePos = NSEvent.mouseLocation
if mousePos == lastPos { continue }
lastPos = mousePos
print(mousePos) //小数点以下をサプレスした方が見やすい
}
マルチディスプレイ構成の場合は、サブディスプレイの配置場所に従い、ディスプレイをまたがった座標位置となります。
- マウスカーソルを メインディスプレイの左側にあるサブディスプレイに移動すると、X座標がマイナス値になる
- マウスカーソルをメインディスプレイの下側にあるサブディスプレイに移動すると、Y座標がマイナス値になる
このように、マルチディスプレイ構成全体で一つの座標系となります。
マウスカーソルの移動
CGDisplayMoveCursorToPoint
を使用すると、任意の座標にマウスカーソルを移動することができます。
しかし、この API に指定する座標は 前項のスクリーン座標とは異なり、メインディスプレイの左上を原点とした座標系です。
例えば、前項のディスプレイ構成で、サブディスプレイの左上の スクリーン座標は (-1440, 1980)
ですが、この API に指定する座標は (-1440, -570)
となります。
同様に、サブディスプレイの左下の スクリーン座標は (-1440, -580)
ですが、この API に指定する座標は (-1440, 2020)
となります。
//サブディスプレイ左上 スクリーン座標 (-1440, 1980)
CGDisplayMoveCursorToPoint(0, CGPoint(x: -1440, y: -570))
//サブディスプレイ左下 スクリーン座標 (-1440, -580)
CGDisplayMoveCursorToPoint(0, CGPoint(x: -1440, y: 2020))
毎度 座標を計算するのが面倒なので、スクリーン座標 で指定できる マウスカーソル移動関数を作成しました。
func mouseMove(screenCoordinate pos: CGPoint) {
let mainDisplayBounds = CGDisplayBounds(0)
let point = CGPoint(x: pos.x, y: mainDisplayBounds.height - pos.y)
CGDisplayMoveCursorToPoint(0, point)
}
//サブディスプレイ左上 スクリーン座標 (-1440, 1980)
mouseMove(screenCoordinate: CGPoint(x: -1440, y: 1980))
//サブディスプレイ左下 スクリーン座標 (-1440, -580)
mouseMove(screenCoordinate: CGPoint(x: -1440, y: -580))
iPhoneミラーリングを使用して iPhone の操作を Mac から自動化しようとしてハマったポイントでした。
画面タップ(マウスクリック)には 別な問題があり、iPhone の自動操作の壁は 高くて厚い です。これについては、別な記事で取り上げようと思います。
以上