Use NSScreen to fetch primary display

Thorsten Ball created

According to Chromium source, `NSScreen::screens` should always get us
one display.

We made this change because we ran into panics caused by the previous
`unwrap()` when `CGGetActiveDisplayList` might return an empty list.

Change summary

crates/gpui/src/platform/mac/display.rs | 23 ++++++++++++++++++++++-
crates/gpui/src/platform/mac/window.rs  |  2 +-
2 files changed, 23 insertions(+), 2 deletions(-)

Detailed changes

crates/gpui/src/platform/mac/display.rs 🔗

@@ -1,10 +1,16 @@
 use crate::{point, size, Bounds, DisplayId, GlobalPixels, PlatformDisplay};
 use anyhow::Result;
+use cocoa::{
+    appkit::NSScreen,
+    base::{id, nil},
+    foundation::{NSDictionary, NSString},
+};
 use core_foundation::uuid::{CFUUIDGetUUIDBytes, CFUUIDRef};
 use core_graphics::{
     display::{CGDirectDisplayID, CGDisplayBounds, CGGetActiveDisplayList},
     geometry::{CGPoint, CGRect, CGSize},
 };
+use objc::{msg_send, sel, sel_impl};
 use std::any::Any;
 use uuid::Uuid;
 
@@ -27,7 +33,22 @@ impl MacDisplay {
     /// Get the primary screen - the one with the menu bar, and whose bottom left
     /// corner is at the origin of the AppKit coordinate system.
     pub fn primary() -> Self {
-        Self::all().next().unwrap()
+        // Instead of iterating through all active systems displays via `all()` we use the first
+        // NSScreen and gets its CGDirectDisplayID, because we can't be sure that `CGGetActiveDisplayList`
+        // will always return a list of active displays (machine might be sleeping).
+        //
+        // The following is what Chromium does too:
+        //
+        // https://chromium.googlesource.com/chromium/src/+/66.0.3359.158/ui/display/mac/screen_mac.mm#56
+        unsafe {
+            let screens = NSScreen::screens(nil);
+            let screen = cocoa::foundation::NSArray::objectAtIndex(screens, 0);
+            let device_description = NSScreen::deviceDescription(screen);
+            let screen_number_key: id = NSString::alloc(nil).init_str("NSScreenNumber");
+            let screen_number = device_description.objectForKey_(screen_number_key);
+            let screen_number: CGDirectDisplayID = msg_send![screen_number, unsignedIntegerValue];
+            Self(screen_number)
+        }
     }
 
     /// Obtains an iterator over all currently active system displays.

crates/gpui/src/platform/mac/window.rs 🔗

@@ -484,7 +484,7 @@ impl MacWindow {
 
             let display = options
                 .display_id
-                .and_then(|display_id| MacDisplay::all().find(|display| display.id() == display_id))
+                .and_then(MacDisplay::find_by_id)
                 .unwrap_or_else(MacDisplay::primary);
 
             let mut target_screen = nil;