The Swift (4.0) version of the accepted answer is basically the same:
let yellowView: NSView // your view that contains the point with the yellow arrow.
let yellowPoint = NSPoint(x: 100, y: 100)
let pointInWindow = yellowView.convert(yellowPoint, to: nil)
let pointOnScreen = yellowView.window?.convertToScreen(NSRect(origin: pointInWindow, size: .zero)).origin ?? .zero
let contentRect = NSRect(origin: pointOnScreen, size: NSSize(width: 32, height: 32))
let newWindow = NSWindow(contentRect: contentRect, styleMask: ...)
The following is an alternate way to do it:
let someView: NSView // Some existing view
var rect: NSRect
rect = NSRect(x: 100, y: 100, width: 0, height: 0)
rect = someView.convert(rect, to: nil)
rect = someView.window?.convertToScreen(rect) ?? rect
rect.size = NSSize(width: 32, height: 32)
let newWindow = NSWindow(contentRect: rect, styleMask: ...)
The latter way simply sets the rect up ahead of time. Here's a play-by-play for those who like walkthroughs:
1. Create a rectangle. Initialize a zero-sized rectangle at the desired location within the view's coordinate system.
let someView: NSView // Some existing view
var rect = NSRect(x: 100, y: 100, width: 0, height: 0)
2. Convert from view to window. Convert the rectangle from the view's coordinate system to the window's coordinate system by specifying nil
for the destination view
.
rect = someView.convert(rect, to: nil)
3. Convert from window to screen. Next, convert the rectangle from the window's coordinate system to the screen's coordinate system.
Note that someView.window
may be nil
, so we use optional chaining (i.e. the ?
in window?
) and fallback to the original value of rect
if that's the case. This probably isn't necessary, but it's a good habit to get into.
rect = someView.window?.convertToScreen(rect) ?? rect
4. Set the rectangle's size. Update the rectangle with the desired size of the new window.
rect.size = NSSize(width: 32, height: 32)
5. Create the window. Initialize a new window with the converted rectangle.
let newWindow = NSWindow(contentRect: rect, styleMask: ...)