srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/udev
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2024-08-09 10:34:00 +0200
committersrdusr <[email protected]>2024-08-09 10:34:00 +0200
commit09e63d204132f767cee7d0846e291d659f79fe90 (patch)
treedb861dc95cbe9db9e628beb351c8b9d977046a09 /crates/wayland/src/udev
parent31de54096243fb000fa6e7008a914861293482a5 (diff)
downloadsrdwm-09e63d204132f767cee7d0846e291d659f79fe90.tar.gz
srdwm-09e63d204132f767cee7d0846e291d659f79fe90.zip
Fix closing an XWayland window doing nothing on both backends
Platform::close only ever called w.toplevel(), which is None for an XWayland window - closing one (the WM's own close binding, or `srd dispatch close`) silently did nothing at all, on both udev and winit. Found live: a leftover untitled fullscreen window wouldn't close via srd dispatch close even after several seconds, tracing back to this. Fixed by falling back to X11Surface::close() when there's no xdg toplevel - it already handles both cases smithay-side (a polite WM_DELETE_WINDOW for a cooperating client, outright destroy_window for one that doesn't support it), so no new logic was needed, just calling it.
Diffstat (limited to 'crates/wayland/src/udev')
-rw-r--r--crates/wayland/src/udev/platform.rs13
1 files changed, 11 insertions, 2 deletions
diff --git a/crates/wayland/src/udev/platform.rs b/crates/wayland/src/udev/platform.rs
index bf887b1..8043e20 100644
--- a/crates/wayland/src/udev/platform.rs
+++ b/crates/wayland/src/udev/platform.rs
@@ -355,8 +355,17 @@ impl Platform for UdevPlatform {
}
fn close(&mut self, window: srdwm_core::WindowId) -> PlatformResult<()> {
- if let Some(w) = self.state.id_to_window.get(&window).and_then(|w| w.toplevel()) {
- w.send_close();
+ let Some(w) = self.state.id_to_window.get(&window) else { return Ok(()) };
+ if let Some(toplevel) = w.toplevel() {
+ toplevel.send_close();
+ } else if let Some(x11) = w.x11_surface() {
+ // `w.toplevel()` is `None` for an XWayland window - without
+ // this arm, closing one (the WM's own close binding, or `srd
+ // dispatch close`) silently did nothing at all. `close()` itself
+ // handles both cases: a polite WM_DELETE_WINDOW for a
+ // cooperating client, outright `destroy_window` for one that
+ // doesn't support it.
+ let _ = x11.close();
}
Ok(())
}