diff options
| author | srdusr <[email protected]> | 2025-02-15 14:56:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-02-15 14:56:00 +0200 |
| commit | 0a4c4b5941fe982ccb3d3175e26d9d83f0025ffd (patch) | |
| tree | 7672d0af277664f457c6c9462925c0005fe35dcf /crates/x11/src/platform/events.rs | |
| parent | 413daa7ba2ea0ebd1424c024fd0566423aaea3f8 (diff) | |
| download | srdwm-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.rs | 39 |
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); |