I’m trying to move the location of a Mac cursor using Objective-C along a path outside of any UI element (not just on some window, but around the entire screen irrelevant of what the mouse is hovering over). I don’t want to directly warp the mouse to a position, but rather progressively move it there (i.e. iterate through a loop, and in each iteration move the cursor 1 pixel to the right).
The problem is that the cursor constantly jumps back and forth over the horizontal center line of the screen (if I start the cursor at y=289, it jumps to y=511, and then back to y=289, and so forth, as my screen is 800 pixels high) even if I don’t actually move it anywhere.
NSPoint mPoint = [NSEvent mouseLocation];
NSPoint mouseWarpLocation = NSMakePoint(mPoint.x, mPoint.y);
CGWarpMouseCursorPosition(mouseWarpLocation);
The code above effectively warps the mouse to its current position, but for some reason the cursor jumps back and forth over the horizontal center line. Any thoughts as to why or what I can do to fix it?
The problem is that AppKit (which provides the
NSEventclass) and Quartz Display Services (which providesCGWarpMouseCursorPosition) use different coordinate systems for the screen.In Quartz, the origin of the screen coordinate system is at the top-left corner of the “main” screen, which is the screen that contains the menu bar, and Y coordinates increase as you move down the screen.
In AppKit, the origin of the screen coordinate system is at the bottom-left corner of the main screen, and Y coordinates increase as you move up the screen.
So if you ask AppKit for the mouse location (in screen coordinates), you need to convert the Y coordinate to the Quartz coordinate system before passing it to a Quartz function.
To transform the Y coordinate, subtract it from the height of the main screen: