srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/wayland/src/protocols.rs
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2025-02-06 09:28:00 +0200
committersrdusr <[email protected]>2025-02-06 09:28:00 +0200
commitef2eff8f654884406c8989baf1ad345a2da43a58 (patch)
tree6638e1b0d5fb573ecc8b8bc5e51ebeb3dfddee42 /crates/wayland/src/protocols.rs
parentd25f28c5a779438bef01106ba2b28874e24d5029 (diff)
downloadsrdwm-ef2eff8f654884406c8989baf1ad345a2da43a58.tar.gz
srdwm-ef2eff8f654884406c8989baf1ad345a2da43a58.zip
Fix layer surfaces spuriously hiding/re-showing on their own realization
sync_layer_visibility could not tell a real hide (null-buffer commit on an already-visible surface) apart from a layer-shell client's ordinary realization sequence (commit with no buffer -> configure -> ack-commit with no buffer again -> attach real content): both look like "committed, no buffer" from has_buffer alone. Every layer surface's first realization was spuriously unmapped and immediately remapped, doubling LayerMap arrange() passes on every single popup open. Live-reproduced via an AGS peer session: a full-monitor click-outside-to- close popup surface came back from a hit-test with geometry wider than the real output after several open/close cycles on a wl_surface GTK had reused across role destroy/recreate, and sat in the Top layer above every real window with no input region set - silently swallowing clicks meant for windows, dropdowns, and CSD title bars alike. layer_surfaces_shown_once now gates the hide path on a surface having actually shown a buffer at least once, and is cleared in layer_destroyed so a reused wl_surface's next role starts clean rather than inheriting the previous role's flag.
Diffstat (limited to 'crates/wayland/src/protocols.rs')
-rw-r--r--crates/wayland/src/protocols.rs9
1 files changed, 9 insertions, 0 deletions
diff --git a/crates/wayland/src/protocols.rs b/crates/wayland/src/protocols.rs
index 94075c2..0b0eea2 100644
--- a/crates/wayland/src/protocols.rs
+++ b/crates/wayland/src/protocols.rs
@@ -661,6 +661,15 @@ impl WlrLayerShellHandler for CompState {
// `new_surface` - see that function's doc comment for the bug
// this exists to route around.
self.dead_layer_surfaces.insert(surface.wl_surface().clone());
+ // GTK (confirmed live via an AGS peer session's WAYLAND_DEBUG trace)
+ // reuses the same `wl_surface` for the next `get_layer_surface` role
+ // rather than creating a fresh one - so without this, a "shown at
+ // least once" flag from *this* role would leak onto the next one
+ // and make `sync_layer_visibility` treat that new role's own
+ // ack-configure commit as eligible to hide again, the same bug
+ // `layer_surfaces_shown_once` exists to prevent, just reintroduced
+ // for exactly the reused-surface case that matters here.
+ self.layer_surfaces_shown_once.remove(surface.wl_surface());
// The surface belongs to exactly one output's map, but which one is
// the client's choice, so unmap from whichever holds it.
for output in self.outputs().cloned().collect::<Vec<_>>() {