From 41c8f2caa63b551dd02257ae8438df7e91e649b6 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 17 Apr 2024 15:29:10 -0600 Subject: [PATCH] Attempt to fix segfault in window drop (#10690) By default NSWindow's release themselves when closed, which doesn't interact well with rust's lifetime system. Disable that behaviour, and explicitly release the NSWindow when the window handle is dropped. Release Notes: - Fixed a (rare) panic when closing a window. --- crates/gpui/src/platform/mac/window.rs | 29 +++++++++++++------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 09181d5766bc0f148f23cdf253d572258bceea37..793caca8d25fb551726f4741a84a470078fef1d0 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -337,7 +337,6 @@ struct MacWindowState { handle: AnyWindowHandle, executor: ForegroundExecutor, native_window: id, - native_window_was_closed: bool, native_view: NonNull, display_link: Option, renderer: renderer::Renderer, @@ -605,6 +604,10 @@ impl MacWindow { registerForDraggedTypes: NSArray::arrayWithObject(nil, NSFilenamesPboardType) ]; + let () = msg_send![ + native_window, + setReleasedWhenClosed: NO + ]; let native_view: id = msg_send![VIEW_CLASS, alloc]; let native_view = NSView::init(native_view); @@ -622,7 +625,6 @@ impl MacWindow { handle, executor, native_window, - native_window_was_closed: false, native_view: NonNull::new_unchecked(native_view), display_link: None, renderer: renderer::new_renderer( @@ -770,19 +772,17 @@ impl Drop for MacWindow { this.renderer.destroy(); let window = this.native_window; this.display_link.take(); - if !this.native_window_was_closed { - unsafe { - this.native_window.setDelegate_(nil); - } - - this.executor - .spawn(async move { - unsafe { - window.close(); - } - }) - .detach(); + unsafe { + this.native_window.setDelegate_(nil); } + this.executor + .spawn(async move { + unsafe { + window.close(); + window.autorelease(); + } + }) + .detach(); } } @@ -1592,7 +1592,6 @@ extern "C" fn close_window(this: &Object, _: Sel) { let close_callback = { let window_state = get_window_state(this); let mut lock = window_state.as_ref().lock(); - lock.native_window_was_closed = true; lock.close_callback.take() };