gpui: Do not panic when `GetMonitorInfoW` fails (#43397)

Lukas Wirth created

Fixes ZED-29R

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/gpui/src/platform/windows/display.rs | 37 +++++++++++-----------
crates/gpui/src/platform/windows/events.rs  |  4 +-
2 files changed, 20 insertions(+), 21 deletions(-)

Detailed changes

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

@@ -63,22 +63,21 @@ impl WindowsDisplay {
         })
     }
 
-    pub fn new_with_handle(monitor: HMONITOR) -> Self {
-        let info = get_monitor_info(monitor).expect("unable to get monitor info");
+    pub fn new_with_handle(monitor: HMONITOR) -> anyhow::Result<Self> {
+        let info = get_monitor_info(monitor)?;
         let monitor_size = info.monitorInfo.rcMonitor;
         let uuid = generate_uuid(&info.szDevice);
         let display_id = available_monitors()
             .iter()
             .position(|handle| handle.0 == monitor.0)
             .unwrap();
-        let scale_factor =
-            get_scale_factor_for_monitor(monitor).expect("unable to get scale factor for monitor");
+        let scale_factor = get_scale_factor_for_monitor(monitor)?;
         let physical_size = size(
             (monitor_size.right - monitor_size.left).into(),
             (monitor_size.bottom - monitor_size.top).into(),
         );
 
-        WindowsDisplay {
+        Ok(WindowsDisplay {
             handle: monitor,
             display_id: DisplayId(display_id as _),
             scale_factor,
@@ -95,21 +94,20 @@ impl WindowsDisplay {
                 size: physical_size,
             },
             uuid,
-        }
+        })
     }
 
-    fn new_with_handle_and_id(handle: HMONITOR, display_id: DisplayId) -> Self {
-        let info = get_monitor_info(handle).expect("unable to get monitor info");
+    fn new_with_handle_and_id(handle: HMONITOR, display_id: DisplayId) -> anyhow::Result<Self> {
+        let info = get_monitor_info(handle)?;
         let monitor_size = info.monitorInfo.rcMonitor;
         let uuid = generate_uuid(&info.szDevice);
-        let scale_factor =
-            get_scale_factor_for_monitor(handle).expect("unable to get scale factor for monitor");
+        let scale_factor = get_scale_factor_for_monitor(handle)?;
         let physical_size = size(
             (monitor_size.right - monitor_size.left).into(),
             (monitor_size.bottom - monitor_size.top).into(),
         );
 
-        WindowsDisplay {
+        Ok(WindowsDisplay {
             handle,
             display_id,
             scale_factor,
@@ -126,7 +124,7 @@ impl WindowsDisplay {
                 size: physical_size,
             },
             uuid,
-        }
+        })
     }
 
     pub fn primary_monitor() -> Option<Self> {
@@ -140,7 +138,7 @@ impl WindowsDisplay {
             );
             return None;
         }
-        Some(WindowsDisplay::new_with_handle(monitor))
+        WindowsDisplay::new_with_handle(monitor).log_err()
     }
 
     /// Check if the center point of given bounds is inside this monitor
@@ -154,7 +152,9 @@ impl WindowsDisplay {
         if monitor.is_invalid() {
             false
         } else {
-            let display = WindowsDisplay::new_with_handle(monitor);
+            let Ok(display) = WindowsDisplay::new_with_handle(monitor) else {
+                return false;
+            };
             display.uuid == self.uuid
         }
     }
@@ -163,11 +163,10 @@ impl WindowsDisplay {
         available_monitors()
             .into_iter()
             .enumerate()
-            .map(|(id, handle)| {
-                Rc::new(WindowsDisplay::new_with_handle_and_id(
-                    handle,
-                    DisplayId(id as _),
-                )) as Rc<dyn PlatformDisplay>
+            .filter_map(|(id, handle)| {
+                Some(Rc::new(
+                    WindowsDisplay::new_with_handle_and_id(handle, DisplayId(id as _)).ok()?,
+                ) as Rc<dyn PlatformDisplay>)
             })
             .collect()
     }

crates/gpui/src/platform/windows/events.rs 🔗

@@ -138,7 +138,7 @@ impl WindowsWindowInner {
             // monitor is invalid, we do nothing.
             if !monitor.is_invalid() && lock.display.handle != monitor {
                 // we will get the same monitor if we only have one
-                lock.display = WindowsDisplay::new_with_handle(monitor);
+                lock.display = WindowsDisplay::new_with_handle(monitor).log_err()?;
             }
         }
         if let Some(mut callback) = lock.callbacks.moved.take() {
@@ -829,7 +829,7 @@ impl WindowsWindowInner {
             log::error!("No monitor detected!");
             return None;
         }
-        let new_display = WindowsDisplay::new_with_handle(new_monitor);
+        let new_display = WindowsDisplay::new_with_handle(new_monitor).log_err()?;
         self.state.borrow_mut().display = new_display;
         Some(0)
     }