Call CGGetActiveDisplayList once to avoid panic

Thorsten Ball created

Previously we called CGGetActiveDisplayList twice: once to get the
number of displays and then to get the displays.

We saw a panic due to no displays being returned here. As a first
attempt to fix the panic, we're reducing the amount of calls to
CGGetActiveDisplayList and just do one with the trade-off being that we
pre-allocate 32 pointers in a Vec.

Change summary

crates/gpui/src/platform/mac/display.rs | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

Detailed changes

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

@@ -33,17 +33,20 @@ impl MacDisplay {
     /// Obtains an iterator over all currently active system displays.
     pub fn all() -> impl Iterator<Item = Self> {
         unsafe {
-            let mut display_count: u32 = 0;
-            let result = CGGetActiveDisplayList(0, std::ptr::null_mut(), &mut display_count);
+            // We're assuming there aren't more than 32 displays connected to the system.
+            let mut displays = Vec::with_capacity(32);
+            let mut display_count = 0;
+            let result = CGGetActiveDisplayList(
+                displays.capacity() as u32,
+                displays.as_mut_ptr(),
+                &mut display_count,
+            );
 
             if result == 0 {
-                let mut displays = Vec::with_capacity(display_count as usize);
-                CGGetActiveDisplayList(display_count, displays.as_mut_ptr(), &mut display_count);
                 displays.set_len(display_count as usize);
-
                 displays.into_iter().map(MacDisplay)
             } else {
-                panic!("Failed to get active display list");
+                panic!("Failed to get active display list. Result: {result}");
             }
         }
     }