Think & Build

screens

Dealing with multiple screens programming

During the development of some applications, it’s really important to make adjustments to make them works correctly on multiple screens… fear not! The OSX global coordinate system works in a really clever way and thanks to the NSScreen class you can get every information you need about users’ displays.

There are two specific screen definitions to know about:
The “Primary screen” is the screen which contains the menu bar, and by this screen it’s defined how the coordinates will be assigned in the other screens (continue reading for more info).

The “Main screen” is the screen containing the window that is currently receiving keyboard events. Don’t let this name deceive you. Keep in mind that the main screen is not necessarily the Primary screen!

Global Screen Coordinates:

So let’s see how the global screen coordinate system works for an hypothetical configuration with two screens.
Take a look a this image which describes how the coordinate system will be drawn in our environment:

As you can see the point 0,0 is located at the bottom left corner of the Primary screen. You can look at the secondary screen as an extension of the primary screen. As you can see from the image, the Y coordinate defined in the primary screen continues on the other monitor maintaining its value. And Moving down from the coordinate 0 we get negative values.

So the global coordinates are defined starting from the Primary screen. The value that these coordinates assume in a secondary screen depend on where you locate this screen relatively to the Main screen.

(Note: CoreGraphics uses a different coordinate system, it sets the point [0,0] at the top-left corner but it has the same rules shown above).

NSScreen Class:

This class helps us with really useful information!
For example we can obtain the current “Main screen” using the class function mainscreen.

[NSScreen mainscreen];

This function returns a pointer to the object of type NSScreen which hosts the current key window.

The class function screens returns an NSArray of all the NSScreen objects available. Just keep in mind that the object at index 0 corresponds to the main screen.

To get the screen dimensions we can use the function frame, which obviously returns an NSRect.

NSRect theFrame = [[NSScreen mainscreen]frame];

And last but not least, the function backingScaleFactor is really useful if you have to deal with Retina display.
In fact this function returns the scale factor of the linear unit in the screen. Retina display has a backing Scale Factor of 2.0 but a simple display of 1.0.

if([[NSScreen mainscreen]backingScaleFactor] == 2.0){ 
....
}

Hope you found these notes useful!
See you next time :)