srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/x11/src/platform/events.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-02-15 14:56:00 +0200
committersrdusr <[email protected]>2025-02-15 14:56:00 +0200
commit0a4c4b5941fe982ccb3d3175e26d9d83f0025ffd (patch)
tree7672d0af277664f457c6c9462925c0005fe35dcf /crates/x11/src/platform/events.rs
parent413daa7ba2ea0ebd1424c024fd0566423aaea3f8 (diff)
downloadsrdwm-0a4c4b5941fe982ccb3d3175e26d9d83f0025ffd.tar.gz
srdwm-0a4c4b5941fe982ccb3d3175e26d9d83f0025ffd.zip
Checkpoint: preserve all uncommitted rust-rewrite worktree work
Safety commit before reconciling this worktree with main, which has diverged with its own separate fixes today. Nothing here is reviewed or curated yet - this exists purely so none of this work can be lost to a git operation, disk issue, or worktree cleanup while that reconciliation happens.
Diffstat (limited to 'crates/x11/src/platform/events.rs')
-rw-r--r--crates/x11/src/platform/events.rs39
1 files changed, 37 insertions, 2 deletions
diff --git a/crates/x11/src/platform/events.rs b/crates/x11/src/platform/events.rs
index ef970f1..30e3f8d 100644
--- a/crates/x11/src/platform/events.rs
+++ b/crates/x11/src/platform/events.rs
@@ -31,8 +31,43 @@ impl X11Platform {
self.conn.flush().map_err(err)?;
Ok(None)
}
- XEvent::UnmapNotify(ev) => Ok(self.unmanage(ev.window)),
- XEvent::DestroyNotify(ev) => Ok(self.unmanage(ev.window)),
+ XEvent::UnmapNotify(ev) => {
+ let struts_changed = self.forget_strut_window(ev.window);
+ let unmanaged = self.unmanage(ev.window);
+ // `unmanage`'s own `Event::WindowDestroyed` wins if this
+ // window was somehow both a managed client *and* a tracked
+ // strut window (shouldn't happen in practice - see
+ // `track_strut_window`'s own doc comment - but `unmanage`
+ // returning `Some` either way takes priority, since a
+ // closed window matters more to core than a reservation
+ // change on the very same event).
+ Ok(unmanaged.or_else(|| struts_changed.then(struts::monitors_changed_event)))
+ }
+ XEvent::DestroyNotify(ev) => {
+ let struts_changed = self.forget_strut_window(ev.window);
+ let unmanaged = self.unmanage(ev.window);
+ Ok(unmanaged.or_else(|| struts_changed.then(struts::monitors_changed_event)))
+ }
+ // Only a window we aren't already managing as a regular
+ // top-level client - see `track_strut_window`'s own doc
+ // comment for why a real panel/dock typically needs this path
+ // specifically (override-redirect, so it never goes through
+ // `manage_new_window`/`MapRequest` at all). Fires for *every*
+ // other window that maps too (a client's own subwindows, an
+ // override-redirect tooltip/menu popup), but `read_strut`
+ // inside it is a cheap couple of `GetProperty` round-trips
+ // that come back empty for anything that never sets the
+ // property, so this costs nothing beyond that for the common
+ // case of "not a bar".
+ XEvent::MapNotify(ev) => {
+ if self.xid_to_core.contains_key(&ev.window) {
+ return Ok(None);
+ }
+ Ok(self.track_strut_window(ev.window).then(struts::monitors_changed_event))
+ }
+ XEvent::PropertyNotify(ev) if ev.atom == self.atoms._NET_WM_STRUT || ev.atom == self.atoms._NET_WM_STRUT_PARTIAL => {
+ Ok(self.update_strut_property(ev.window).then(struts::monitors_changed_event))
+ }
XEvent::ButtonPress(ev) => {
let (x, y) = (ev.root_x as i32, ev.root_y as i32);
let hit = self.wm.borrow().hit_test(x, y);