I am trying to create a game where the mouse is locked at the center of the screen. To complete this task, I found the appropriate method: CGWarpMouseCursorPosition
Then I searched for how to get the center of an NSView
and found this: Getting the center point of an NSView
I used the provided answers but get incorrect results. No matter where window is is, the point the mouse is moved to is always half of the frame width and height away from the top left corner of the screen. It is as if the frame.origin
of the view is always {0, 0}
even when the window is somewhere else.
In my code, window
is a member inherited from implementing NSWindowController
and NSWindowDelegate
:
override func mouseMoved(with Event: NSEvent) {
if let window = window, let view = window.contentView {
let frame = view.frame
CGWarpMouseCursorPosition(CGPoint(x: frame.midX, y: frame.midY))
// ...
}
}
What is the correct way to get the center point of an NSView
for use with the CGWarpMouseCursorPosition()
function?
There are 2 problems with the existing implementation. The reason why view.frame.origin
is always {0, 0}
is because the view.frame
is relative to the window and not absolute. As the other answer states the frame origin is always at {0, 0}
'inside' the window. I was expecting the frame
to be absolute.
This can be solved by using window.frame
directly instead of view.frame
.
A second problem is that even if the frame
is 'absolute' the coordinate system used by NSView
is different from the coordinate system used by CGWarpMouseCursorPosition()
. The answer here explains how to convert between them.
Corrected code:
if let window = window, let view = window.contentView {
let frame = window.frame
let originY = NSScreen.main.frame.maxY-frame.maxY;
CGWarpMouseCursorPosition(CGPoint(x: frame.midX, y: originY+frame.height*0.5))
// ...
}