Repository navigation
internal/kawa: separate pointer routing, focus, and drawing - #27
Open
DeedleFake wants to merge 8 commits into
Open
DeedleFake wants to merge 8 commits into
DeedleFake wants to merge 8 commits into
Conversation
moveCursor had no users, and the move mode carried a commented-out status bar clamp.
Hover, presses, the window picker, and tiled swaps each had their own query, and presses tested the status bar on their own. hitAt walks the stack once and returns a tagged hit. Each caller passes the planes that it can see, so what a caller skips is one constant.
Windows and layer surfaces each had their own focus function, restoring focus cleared it on its own, and destroying a window picked the next one with its own rule. focus takes a focusTarget for all three, and destroy and restoreFocus share topView.
onFrame type-asserted the mode to draw its menu or box and to find the window to highlight. Modes write an overlay that onFrame only reads. The New box was mode memory aliased into newViews. newViews holds values keyed by the pid that exec returns, and the drag updates that entry for as long as it exists.
InputMode was any, with optional interfaces for motion, buttons, cursor requests, and drawing, so one object owned the phase, client delivery, and the cursor image. An interaction is a small closed interface that never talks to clients. pointer.go is the only code that calls seat.PointerNotify*, and cursor.go is the only code that sets the cursor image.
focusTarget was a struct of optional fields that focus switched on to find out what it was focusing. Windows, the surfaces inside them, and layer surfaces implement it now, each deciding whether it can take the keyboard and what changes once it has it. Clearing the keyboard has no target, so it's clearFocus.
onDestroyView read overlay.target to decide whether to end the interaction, so window lifecycle depended on what gets drawn. begin records the window an interaction acts on next to it, and overlay.target is only the highlight.
A window's focusSurface saved prevFocus when an exclusive layer surface blocked it, so asking a target for its surface could change state. Targets now only report their surface and window, and focus makes every decision: the exclusive layer check, saving prevFocus, and whether the target already has the keyboard.
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
One
InputMode anyvalue owned the interaction phase, pointer delivery to clients, the cursor image, what got drawn on top, and which window was highlighted. Render and input reached into it with type assertions, so changing how a menu or a resize behaves meant reading input.go, mode.go, render.go, and view.go together. Hit testing and keyboard focus were also decided in several places with slightly different rules.What changed
Each of those jobs now has one owner in internal/kawa:
seat.PointerNotify*.overlaythat interactions write (open menu and selection, box, target window) andonFrameonly reads.hitAtthat returns a tagged result. Each caller passes the planes it can see.focustakes a window or layer surface through a small interface, andclearFocusclears it.InputMode, its six optional interfaces, and all eight type assertions on it are gone. The New box is now a value innewViewskeyed by pid instead of aliased mode memory.Scope
Behavior is unchanged, including known bugs, which are left for follow-ups. A few of them: the status bar click uses the layout Y, menus all use the main menu's last selection, axis events reach clients during grabs, move and resize end on any release, and the window picker ignores layer surfaces. Each now sits in one owner, usually on one line.
Blast Radius
All pointer, keyboard focus, and drawing paths in internal/kawa. No other packages, dependencies, or the wlr bindings.
Verification
go vet, golangci-lint,go fix -diff, andgo test. New unit tests cover the border edge test and the New box overlay.