Calculating screen coordinates from NSView-relative coordinates in Cocoa

Published on 25/01/2012

For a recent release of SpriteRight I set out to integrate snap-to-grid functionality. Unfortunately this required that I calculate screen coordinates from a set of view-relative coordinates.

I’ve decided to make the code I ended up with public in the hope that it avoids someone a little head scratching down the road. It should be noted that the following code makes use of Oscar Del Ben’s fantastic NSScreen+PointConversion category to help with determining the active NSScreen and flipping said screens coordinates.

The following code should handle flipped coordinate systems and multi-monitor displays gracefully. Also included is a function to warp the mouse (without simulating any events) to a specified point in screen coordinates.

- (NSPoint)convertToScreenFromLocalPoint:(NSPoint)point relativeToView:(NSView *)view
{
	NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
	if(currentScreen)
	{
		NSPoint windowPoint = [view convertPoint:point toView:nil];
		NSPoint screenPoint = [[view window] convertBaseToScreen:windowPoint];
		NSPoint flippedScreenPoint = [currentScreen flipPoint:screenPoint];
		flippedScreenPoint.y += [currentScreen frame].origin.y;
 
		return flippedScreenPoint;
	}
 
	return NSZeroPoint;
}
 
- (void)moveMouseToScreenPoint:(NSPoint)point
{
	CGPoint cgPoint = NSPointToCGPoint(point);
 
	CGSetLocalEventsSuppressionInterval(0.0);
	CGWarpMouseCursorPosition(cgPoint);
	CGSetLocalEventsSuppressionInterval(0.25);
}