linux/x11: Do panic when unmapping/destroying of X11 window fails (#13262)

We saw this panic come up:

```
called `Result::unwrap()` on an `Err` value: IoError(Custom { kind: Other, error: UnknownError })
core::panicking::panic_fmt
core::result::unwrap_failed
<gpui::platform::linux::x11:🪟:X11Window as core::ops::drop::Drop>::drop
core::ptr::drop_in_place<gpui::platform::linux::x11:🪟:X11Window>
core::ptr::drop_in_place<gpui:🪟:Window>
gpui::app::AppContext::shutdown
gpui::app::AppContext:🆕:{{closure}}
gpui::platform::linux::platform::<impl gpui::platform::Platform for P>::run
gpui::app::App::run
zed::main
std::sys_common::backtrace::__rust_begin_short_backtrace
std::rt::lang_start::{{closure}}
std::rt::lang_start_internal
main
__libc_start_call_main
__libc_start_main_impl
_start
```

I'm not sure where exactly that error comes from, except from the X11
stuff. So let's be defensive and log error and only then tear down
everything.

I _think_ that if the error is repeatable that means we won't close the
window but instead just log errors, but I do think that's better than
panicking right now.

Release Notes:

- N/A
This commit is contained in:
Thorsten Ball 2024-06-19 14:36:57 +02:00 committed by GitHub
parent 59c005b086
commit 8524e87319
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,3 +1,5 @@
use anyhow::Context;
use crate::{ use crate::{
platform::blade::{BladeRenderer, BladeSurfaceConfig}, platform::blade::{BladeRenderer, BladeSurfaceConfig},
px, size, AnyWindowHandle, Bounds, DevicePixels, ForegroundExecutor, Modifiers, Pixels, px, size, AnyWindowHandle, Bounds, DevicePixels, ForegroundExecutor, Modifiers, Pixels,
@ -8,7 +10,7 @@ use crate::{
use blade_graphics as gpu; use blade_graphics as gpu;
use raw_window_handle as rwh; use raw_window_handle as rwh;
use util::ResultExt; use util::{maybe, ResultExt};
use x11rb::{ use x11rb::{
connection::Connection, connection::Connection,
protocol::{ protocol::{
@ -422,13 +424,17 @@ impl Drop for X11Window {
let mut state = self.0.state.borrow_mut(); let mut state = self.0.state.borrow_mut();
state.renderer.destroy(); state.renderer.destroy();
self.0.xcb_connection.unmap_window(self.0.x_window).unwrap(); let destroy_x_window = maybe!({
self.0 self.0.xcb_connection.unmap_window(self.0.x_window)?;
.xcb_connection self.0.xcb_connection.destroy_window(self.0.x_window)?;
.destroy_window(self.0.x_window) self.0.xcb_connection.flush()?;
.unwrap();
self.0.xcb_connection.flush().unwrap();
anyhow::Ok(())
})
.context("unmapping and destroying X11 window")
.log_err();
if destroy_x_window.is_some() {
// Mark window as destroyed so that we can filter out when X11 events // Mark window as destroyed so that we can filter out when X11 events
// for it still come in. // for it still come in.
state.destroyed = true; state.destroyed = true;
@ -442,6 +448,8 @@ impl Drop for X11Window {
client_ptr.drop_window(this_ptr.x_window); client_ptr.drop_window(this_ptr.x_window);
}) })
.detach(); .detach();
}
drop(state); drop(state);
} }
} }