summaryrefslogtreecommitdiffhomepage
path: root/packages/ext-layer-shell/src/ext_layer_shell.cpp
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-14 19:07:20 +0900
committerAdam Malczewski <[email protected]>2026-06-14 19:07:20 +0900
commite008b9a078c91b07947fba7748aae7fab8758a2f (patch)
treebca95f794c8f5f8485fd783bb71cd102507d83f6 /packages/ext-layer-shell/src/ext_layer_shell.cpp
parent7b1f149717116d7290ec76ae808a4d076af856d2 (diff)
downloadunbox-e008b9a078c91b07947fba7748aae7fab8758a2f.tar.gz
unbox-e008b9a078c91b07947fba7748aae7fab8758a2f.zip
ext-layer-shell: fix configure feedback loop; default Super toggles fuzzel
The intermittent "Super needs several presses to open fuzzel" bug was a layer-shell configure storm, not a keybinding issue. The per-surface commit handler called arrange() on EVERY wl_surface commit, and arrange() unconditionally calls wlr_scene_layer_surface_v1_configure, which in wlroots 0.20 emits a fresh configure each call. A client acking + applying its configure re-entered the commit handler, producing an unbounded configure -> ack_configure -> commit -> configure loop that overflowed the client's 4 KiB connection buffer ("Data too big for buffer") and got it killed mid-handshake. fuzzel therefore only displayed when the burst happened to flush in time. Fix: only re-arrange on the initial commit or a commit that changes a layout-relevant field (current.committed != 0); a plain buffer/frame commit no longer triggers a configure. Also: - ext-keybindings: tap-Super now defaults to a launcher TOGGLE ("pkill -x fuzzel || fuzzel") in both default_bindings() and the sample unbox.toml — pressing Super while fuzzel is open closes it. - ext-keybindings: a genuine Super press always re-arms a clean tap, so a dropped Super release can no longer eat the next tap (robustness). - tests: update default-command assertions; add a bounded-configure invariant guard to the layer-shell client test.
Diffstat (limited to 'packages/ext-layer-shell/src/ext_layer_shell.cpp')
-rw-r--r--packages/ext-layer-shell/src/ext_layer_shell.cpp20
1 files changed, 16 insertions, 4 deletions
diff --git a/packages/ext-layer-shell/src/ext_layer_shell.cpp b/packages/ext-layer-shell/src/ext_layer_shell.cpp
index 5670c52..3ca013d 100644
--- a/packages/ext-layer-shell/src/ext_layer_shell.cpp
+++ b/packages/ext-layer-shell/src/ext_layer_shell.cpp
@@ -397,11 +397,23 @@ LayerSurface::LayerSurface(LayerShellExt& owner, wlr_layer_surface_v1* surface,
// RAII handle is a member; it unregisters when this LayerSurface dies.
host_reg_ = owner_.host().host_surface(surface_->surface, scene_->tree);
- // Re-arrange this surface's output on every commit (covers the mandatory
- // initial-commit configure and any later anchor/zone/size change), then
- // re-evaluate keyboard focus.
+ // Re-arrange this surface's output ONLY when the arrangement could have
+ // changed: the mandatory initial-commit configure, or a commit that changed
+ // a layout-relevant field (anchor / desired size / exclusive zone / margin /
+ // layer / exclusive edge — i.e. current.committed != 0). A plain buffer or
+ // frame commit changes none of these (committed == 0, not the initial
+ // commit) and MUST NOT trigger a configure: arrange() unconditionally calls
+ // wlr_scene_layer_surface_v1_configure, and in wlroots 0.20 that emits a
+ // fresh configure event every call. Reconfiguring on every commit created a
+ // configure -> ack_configure -> apply-commit -> configure feedback loop that
+ // flooded the client's 4 KiB connection buffer ("Data too big for buffer")
+ // and got it killed mid-handshake — the intermittent "fuzzel needs several
+ // Super presses to open" bug. Keyboard focus is still re-evaluated every
+ // commit (cheap; it only acts once mapped).
commit_.connect(surface_->surface->events.commit, [this](void*) {
- owner_.arrange(surface_->output);
+ if (surface_->initial_commit || surface_->current.committed != 0) {
+ owner_.arrange(surface_->output);
+ }
update_keyboard_focus();
});