Skip to content
Apr 20 / kkrizka

Converting Between kCGWindowBounds and NSWindow#frame

kCGWindowBounds is a field in a dictionary returned by the CGWindowListCopyWindowInfo function. This fields lists the dimensions of a window displayed by the Quartz Window System (Mac OS X’s analogue of X11). I was trying to use this field to resize a NSWindow object that I was controlling, with the idea to create a window picker. The problem is that kCGWindowBounds’ coordinates are not the same ones as used by NSWindow’s frame property, and it took me a while to realize this. Which is why I am sharing what I found out.

Both kCGWindowBounds and NSWindow’s frame property are instances of CGRect (technically, NSWindow uses a NSRect but all literature I found says it is equivalent to CGRect). This object has two attributes; a point (origin) and dimensions (size). The difference between the CGRect returned by kCGWindowBounds and NSWindow’s frame property is that:

  • kCGWindowBounds measures the origin as the top-left corner of the rectangle relative to the top-left corner of the screen
  • NSWindow’s frame property measures the origin as the bottom-left corner of the rectangle relative to the bottom-left corner of the screen

So if you want to convert between the two representations of the same information, you have to do the following. It is the same conversion if you are going from kCGWindowBounds to NSWindow#frame or in the other direction.

bounds.origin.y=[[NSScreen mainScreen] frame].size.height-bounds.origin.y-bounds.size.height;

2 Comments

Leave a comment
  1. Craig Hockenberry / Aug 2 2011

    Thanks for the information!

    There’s a slight problem with this code: it won’t work correctly if there are multiple screens with different dimensions. (Think laptop with an external screen.)

    It’s best to iterate through [NSScreens screens] to find the right one before adjusting the window bounds.

    • Karol Krizka / Aug 4 2011

      Good to know. I never used an external screen with my laptop, so I never bothered to check that.

Leave a comment
Cancel reply