summaryrefslogtreecommitdiff
path: root/src/clients
diff options
context:
space:
mode:
authortcmal <me@aria.rip>2024-06-21 21:31:59 +0100
committertcmal <me@aria.rip>2024-06-21 21:31:59 +0100
commit28d1cbca91c35175137ec8f9a9f816f3448467b6 (patch)
tree0e0671d7bbbe2b6946383731fc8bd8189e315878 /src/clients
parenta4504f118b4ba653ca3587331ba16a9ebe72746c (diff)
fix some problems when clients were destroyed
Diffstat (limited to 'src/clients')
-rw-r--r--src/clients/client.rs20
-rw-r--r--src/clients/mod.rs11
2 files changed, 20 insertions, 11 deletions
diff --git a/src/clients/client.rs b/src/clients/client.rs
index a7b1a8d..3648f0c 100644
--- a/src/clients/client.rs
+++ b/src/clients/client.rs
@@ -3,7 +3,7 @@ use xcb::{
ChangeProperty, ChangeWindowAttributes, ConfigWindow, ConfigureNotifyEvent,
ConfigureWindow, Cw, EventMask, MapWindow, SendEvent, SendEventDest, Window,
},
- Xid,
+ VoidCookie, VoidCookieChecked, Xid,
};
use crate::{config::BORDER_WIDTH, conn_info::Connection};
@@ -125,11 +125,15 @@ impl Client {
/// Set the event mask for this window
/// This function does not check for success, so `conn.flush()` should be called after.
- pub fn set_event_mask(&self, conn: &Connection<'_>, event_mask: EventMask) {
- conn.send_request(&ChangeWindowAttributes {
+ pub fn set_event_mask(
+ &self,
+ conn: &Connection<'_>,
+ event_mask: EventMask,
+ ) -> VoidCookieChecked {
+ conn.send_request_checked(&ChangeWindowAttributes {
window: self.window(),
value_list: &[Cw::EventMask(event_mask)],
- });
+ })
}
/// Sync the non-geometry related properties with EWMH hints
@@ -150,14 +154,14 @@ impl Client {
}
/// Set the given window as withdrawn / not withdrawn.
- pub fn set_withdrawn(&self, conn: &Connection<'_>, withdrawn: bool) {
- conn.send_request(&ChangeProperty {
+ pub fn set_withdrawn(&self, conn: &Connection<'_>, withdrawn: bool) -> VoidCookieChecked {
+ conn.send_request_checked(&ChangeProperty {
mode: xcb::x::PropMode::Replace,
window: self.window,
property: conn.atoms.wm_state,
r#type: conn.atoms.wm_state,
- data: &[u8::from(!withdrawn), 0_u8],
- });
+ data: &[u32::from(!withdrawn), 0_u32],
+ })
}
pub fn set_urgent(&mut self, urgent: bool) {
diff --git a/src/clients/mod.rs b/src/clients/mod.rs
index d07de74..70e3798 100644
--- a/src/clients/mod.rs
+++ b/src/clients/mod.rs
@@ -94,7 +94,9 @@ impl WM<'_> {
pub(crate) fn handle_unmap_notify(&mut self, e: &UnmapNotifyEvent) -> Result<()> {
if let Some(c) = self.clients.find_client_mut(e.window()) {
if e.is_from_send_event() {
- c.set_withdrawn(&self.conn, true);
+ let cookie = c.set_withdrawn(&self.conn, true);
+ // The above may fail if the window has already been destroyed - just discard the error here.
+ let _ = self.conn.check_request(cookie);
} else {
self.clients.unmanage(&self.conn, e.window(), false);
}
@@ -237,9 +239,12 @@ impl ClientState {
let c = self.mons[mon].clients.remove(i);
if !already_destroyed {
- c.set_event_mask(conn, EventMask::empty());
+ c.set_event_mask(conn, EventMask::NO_EVENT);
// TODO: Ungrab button
- c.set_withdrawn(conn, true);
+ let cookie = c.set_withdrawn(conn, true);
+
+ // If any of the above requests fail, it's just a race condition and the window is already destroyed, so discard the error here.
+ let _ = conn.check_request(cookie);
}
self.rearrange(conn);
}