Repository navigation
kawa: support layer shell surfaces - #17
Merged
Merged
Conversation
This was referenced Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
kawa advertises
zwlr_layer_shell_v1, butonNewLayerSurfacewas apanic("Not implemented."), so the first panel, wallpaper, notification daemon or launcher to connect took the whole session down. swaybg alone did it: it sentset_exclusive_zone(-1)andcommit(), and kawa died withpanic: Not implemented.atlayers.go:20.Scope
Each output keeps its layer surfaces in
Output.Layers, one list per layer, and caches the area they leave for windows inOutput.usable. Arrangement follows wlroots' scene helper and sway. It starts from the output minus kawa's status bar strip and places surfaces with an exclusive zone first, from overlay down to background, before the rest. Each mapped surface takes its zone off the remaining area. Tiling, centering, the New box and toplevel popups now stay inside that area. The wallpaper from-bgstill fills everything below the bar.Layer surfaces are drawn background, bottom, windows, top, overlay, then every layer popup, then the status bar. Hit testing uses the same order. Layer popups are unconstrained to the output minus the bar. A surface with no output goes on the output under the cursor. When its output is removed, the surface is closed.
Keyboard: a mapped
exclusivesurface in top or overlay takes the keyboard and keeps it until it unmaps or gives it up.on_demandsurfaces get the keyboard when clicked, and clicking a window takes it back. Afterwards, focus returns to the window that had it, or the topmost window if that one is gone. If there is no window, focus is cleared.This uses the bindings from DeedleFake/wlr#12, which is merged, and pins wlr to master at 8832710.
Tradeoffs
exclusivesurface in bottom or background is treated ason_demand.Blast Radius
The change is limited to layer surfaces, the usable area and focus handoff. With no layer clients,
usableis the same as the old tiling bounds, so window placement doesn't change.focusViewreturns early only while an exclusive layer surface is mapped.Verification
go build ./...andgo vet ./...pass on every commit against wlroots 0.20.2. I ran each client against the new build in a nested X11 session and checked itsWAYLAND_DEBUGlog and a screenshot:configure(1, 1024, 768).set_exclusive_zone(30)and gotconfigure(3, 1024, 30). Tiled windows moved down to y=70, and after waybar was killed they moved back to y=40.xdg_popup.configure(31, 16, 138, 86)and was drawn above the panel. Clicking an item worked.set_keyboard_interactivity(1)) gotwl_keyboard.enterand kept the keys even after a click on the terminal. After Escape, typing reached the terminal again.closed()to its layer surfaces, and kawa stayed up.The verify-kawa core flow also passed: boot, the registry, the main menu, New, Tile, both status bar menus and
-bg.