From 54ff9c3bb5e6b16f8b3f62cc8dbe8e73b323d9d9 Mon Sep 17 00:00:00 2001 From: Pascal Hertleif Date: Mon, 5 Aug 2024 12:44:18 +0200 Subject: [PATCH] macOS: skip releasing unavailable monitors Prevent assertion error when trying to close a fullscreen window that was on a display that got disconnected. --- src/changelog/unreleased.md | 1 + .../apple/appkit/window_delegate.rs | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 5993dc7dae..b1d18d5f88 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -110,3 +110,4 @@ changelog entry. ### Fixed - On Web, pen events are now routed through to `WindowEvent::Cursor*`. +- On macOS, fix panic when releasing not available monitor. diff --git a/src/platform_impl/apple/appkit/window_delegate.rs b/src/platform_impl/apple/appkit/window_delegate.rs index cab32ea734..bebe5d66d9 100644 --- a/src/platform_impl/apple/appkit/window_delegate.rs +++ b/src/platform_impl/apple/appkit/window_delegate.rs @@ -1428,13 +1428,7 @@ impl WindowDelegate { toggle_fullscreen(self.window()); }, (Some(Fullscreen::Exclusive(ref video_mode)), None) => { - unsafe { - ffi::CGRestorePermanentDisplayConfiguration(); - assert_eq!( - ffi::CGDisplayRelease(video_mode.monitor().native_identifier()), - ffi::kCGErrorSuccess - ); - }; + restore_and_release_display(&video_mode.monitor()); toggle_fullscreen(self.window()); }, (Some(Fullscreen::Borderless(_)), Some(Fullscreen::Exclusive(_))) => { @@ -1465,13 +1459,7 @@ impl WindowDelegate { ); app.setPresentationOptions(presentation_options); - unsafe { - ffi::CGRestorePermanentDisplayConfiguration(); - assert_eq!( - ffi::CGDisplayRelease(video_mode.monitor().native_identifier()), - ffi::kCGErrorSuccess - ); - }; + restore_and_release_display(&video_mode.monitor()); // Restore the normal window level following the Borderless fullscreen // `CGShieldingWindowLevel() + 1` hack. @@ -1667,6 +1655,21 @@ impl WindowDelegate { } } +fn restore_and_release_display(monitor: &MonitorHandle) { + let available_monitors = monitor::available_monitors(); + if available_monitors.contains(monitor) { + unsafe { + ffi::CGRestorePermanentDisplayConfiguration(); + assert_eq!(ffi::CGDisplayRelease(monitor.native_identifier()), ffi::kCGErrorSuccess); + }; + } else { + warn!( + monitor = monitor.name(), + "Tried to restore exclusive fullscreen on a monitor that is no longer available" + ); + } +} + impl WindowExtMacOS for WindowDelegate { #[inline] fn simple_fullscreen(&self) -> bool {