diff options
| author | Adam Malczewski <[email protected]> | 2026-06-14 19:07:20 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-14 19:07:20 +0900 |
| commit | e008b9a078c91b07947fba7748aae7fab8758a2f (patch) | |
| tree | bca95f794c8f5f8485fd783bb71cd102507d83f6 /packages/ext-layer-shell/src/ext_layer_shell.cpp | |
| parent | 7b1f149717116d7290ec76ae808a4d076af856d2 (diff) | |
| download | unbox-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.cpp | 20 |
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(); }); |
