Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
875 views
in Technique[技术] by (71.8m points)

macos - Mac OS X: Convert between NSView coordinates and global screen coordinates

I have the following situation in my multi-monitor setup:

OSX coordinate conversions

In this example I want to position a window exactly at the coordinates depicted with the yellow arrow. All I do have however, are the coordinates of an NSView that is a subview of the contentView of an NSWindow that spans the entire (bigger,upper) secondary monitor.

Here's how the global coordinate space is defined:

  • {0,0} is the coordinate of the upper left corner of my laptop screen. (green)
  • {-296, -1080} is the coordinate of the upper left corner of my second screen (black)
  • {0, 800} is the coordinate of the lower left corner (no arrow here)

Thus y is increasing going down from green arrow, decreasing going up from green arrow.

Problem:

How do I convert the point depicted by the yellow arrow ({100,100}, NSView inside NSWindow inside this NSScreen) into that global coordinate system. (Note: In an NSView the coordinate system has {0,0} in the bottom left corner, increasing upwards.)

I believe the correct answer is {-196, -980}, but whats the code to get this conversion for any window on any screen?

I have spent too much time on this problem already, so any help is very appreciated.

(Not sure if relevant, but the bottom screen has a retina resolution display.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Mac OS uses different coordinate systems in various places. Views can define if they have an upwards or downwards pointing y-axis (isFlipped). A window's origin is expressed in "screen coordinates" with an upwards y-axis. Screens are arranged using the global coordinate system with y pointing down.

It's better not to try to do the conversion of all the coordinate spaces yourself but let the responsible objects do the job:

NSView *yellowView; // your view that contains the point with the yellow arrow.
NSPoint yellowPoint = { 100, 100 };

NSPoint pointInWindow = [yellowView convertPoint:yellowPoint toView:nil];
NSPoint pointOnScreen = [[yellowView window] convertRectToScreen:(CGRect){.origin=pointInWindow}];

NSWindow *newWindow = [[NSWindow alloc] initWithContentRect:(CGRect){ pointOnScreen, {32, 32}} styleMask: ...];

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...