Dominik Palo Dominik Palo - 5 months ago 55
Swift Question

Determine external screen connected to the MacBook computer using NSScreen

I need to show a window on the external screen (e.g. monitor connected to the Macbook). But I don't know how to distinguish between internal MacBook screen and external one. Calling of

returns list of all screens and in my case screen with index 0 is my connected external screen and screen with index 1 is my internal (built in) MacBook screen. But documentation says:

The screen at index 0 in the returned array corresponds to the primary screen of the user’s system.

So why is my connected screen marked as primary? Is external screen on all systems is marked as primary => can I suppose that on all systems with connected external screen is this screen on 0 position?

Also, OS X dock is visible only on my internal screen and I thought that dock is by default visible on the primary screen, but that is not true.

Is there a way to reliable determine the correct external screen?


To expand on werediver's answer, here's one implementation:

extension NSScreen {
    class func externalScreens() -> [NSScreen] {
        guard let screens = NSScreen.screens() else {
            return []

        return screens.filter {
            guard let deviceID = $0.deviceDescription["NSScreenNumber"] as? NSNumber else { return false }
            return CGDisplayIsBuiltin(deviceID.unsignedIntValue) == 0

Usage is simple:

let externalScreens = NSScreen.externalScreens()

You might want to adjust the behavior in the guard statements' else blocks depending on your needs.