Add shortcut to focus the window occupying a zone - #219
Open
dssouza-ti wants to merge 1 commit into
Open
dssouza-ti wants to merge 1 commit into
dssouza-ti wants to merge 1 commit into
Conversation
Meta+Ctrl+Num+1..9 activates the window in the matching zone of the active layout, cycling through them when a zone holds more than one. Zones are resolved from the current layout instead of fixed geometry, so the shortcuts follow layout switches and layout edits. Candidates are matched by how much they overlap the zone rectangle rather than by the zone stored on the client, so windows that were never snapped by KZones still count as occupying a zone. Every window covering nearly as much of the zone as the best match counts as being in it, which keeps a stack of windows sharing a zone reachable. The cycle order comes from a stable per-window key rather than the stacking order: activating a window raises it, which would otherwise leave the window just left permanently next in line and ping-pong between two windows. Stacking order still decides where the cycle starts, so entering a zone lands on the window last used there. Also extract getZoneGeometry() from the two places that read a zone rect back from the rendered items, and keep the selection logic pure in pickWindowInZone().
dssouza-ti
force-pushed
the
feature/hotkeys-active-window-per-zone
branch
from
August 30, 2026 00:47
bdfd261 to
f5326aa
Compare
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.
Closes #111
Summary
Adds a shortcut to focus the window occupying a given zone: Meta + Ctrl + Num 1-9 activates the window in the matching zone of the active layout, and cycles through them when a zone holds more than one window.
KZones can already move windows into zones, but there is no way to jump focus to a zone. The existing "Switch to next/previous window in current zone" only cycles inside the zone the active window already occupies, so it cannot be used to reach a different zone. On a wide monitor with a multi column layout, this fills that gap: the zone number becomes a direct focus target.
Motivation
I had been using a small standalone KWin script for this, but it hardcoded its zone list as fixed screen percentages, so it silently disagreed with KZones whenever I switched or edited a layout. This PR merges that behaviour into KZones proper and resolves the zones from
config.layouts[currentLayout]instead, so the shortcuts always follow the active layout.What changed
src/contents/ui/components/Shortcuts.qmlfocusZone(int zone)signal and aRepeaterof nineShortcutHandlers bound toMeta+Ctrl+Num+1..9src/contents/ui/main.qmlfocusWindowInZone(),getWindowsOverlappingZone()andgetZoneGeometry(), plus theonFocusZonehandlersrc/contents/code/utils.mjsoverlapArea(),windowKey()andpickWindowInZone()README.mdNo new configuration settings, so
config/main.xml,ui/config.uiandloadConfig()are untouched.Design notes
Zone geometry comes from the rendered items.
getZoneGeometry(layout, zone)reads the zone rect back viamapToGlobal()on theZones.qmlitem, which is whatmoveClientToZone()already did. That block was duplicated inmoveClientToZone()and inonFullScreenChanged(), so I extracted it and both now call the helper. This keeps a single source of truth for zone geometry, so focusing and snapping can never disagree about where a zone is.Matching is by geometric overlap, not by the stored
client.zone. Windows that KZones never snapped, or that were snapped while a different layout was active, still count as occupying a zone. This complements the existinggetWindowsInZone()/switchWindowInZone()pair, which remain untouched and keep using the stored zone.Every window covering nearly as much of the zone as the best match counts as being in it (
area >= bestArea * 0.9). Without this, only the single best overlapping window is reachable and a stack of windows sharing a zone is not.The cycle order comes from a stable per window key, not the stacking order. Activating a window raises it, so a stacking ordered ring would put the window you just left permanently back in "next" position, ping-ponging between two windows and never reaching the rest. The key is
internalId(a stable per window UUID). Stacking order is still used, but only to decide where the cycle starts, so entering a zone from outside lands on the window last used there.Window filtering reuses the existing
checkFilter(), so the user's Include/Exclude filter list applies to focusing as well as to snapping, plus checks forminimized,output,desktopsandactivities(an empty desktop or activity list means "on all", matching KWin's semantics). If you would rather the filter list govern snapping only, that is a one line change.Enumeration uses
Workspace.stackingOrder. The declarative scripting API does not exposewindowList(); that exists only on the imperative API. I hit this during testing and it is noted in a comment so it does not get reintroduced.Choice of key binding
Ctrl+Alt+NumandMeta+Numare already taken by "Move active window to zone" and "Activate layout", so this usesMeta+Ctrl+Num. Shift deliberately is not part of the sequence: XKB'sKEYPADkey type mapsShift+NumLockback to the base level (KP_End,KP_Down, and so on), which makes anyShift+Num+Nbinding physically unreachable while NumLock is on. There is a comment inShortcuts.qmlrecording this.As with the other numeric shortcuts, these may not bind by default if the sequence is already claimed on a given system.
Testing
Environment: Fedora Linux 44 (KDE Plasma Desktop Edition), Plasma 6.7.4, KWin 6.7.4, Qt 6.11.1, Wayland.
make test, and confirmed all nine actions register with kglobalaccel.I also checked the pure selection logic (
pickWindowInZone) with a standalone Node harness covering the overlap maths, the area threshold, the entry point, and specifically the raise-reshuffle case described above. I have not included it in this PR, since the repository has no test setup and I did not want to impose one, but I am happy to add it if you would like.Formatting note:
CONTRIBUTING.mdasks forqmlformat, and my distribution shipsqmlformat-qt6(Qt 6.11), whose output style differs from the committed formatting. Running it reformatted both files wholesale (stripping()from parameterless signals, collapsing blank lines, rewritingreturn ;), so I reverted that and matched the surrounding style by hand to keep the diff reviewable. Say the word if you would prefer the files run through your version of the tool.Compatibility and risk
getZoneGeometry()helper, which is a straight refactor of two duplicated blocks.KPlugin.Versioninmetadata.jsonis deliberately not bumped, since version bumps appear to be separate release commits in this repository.Reviewer notes, full disclosure