fix(movewindow): prevent windows from escaping tab groups#295
Open
sim590 wants to merge 2 commits into
Open
Conversation
When moving a window out of a sub-group (e.g. SplitH) inside a tab group, the window would traverse the entire tab group instead of stopping at its boundary. Add group.isTab() to the break condition in the parent traversal loop and to the neighbor descent guard so that movewindow stops at tab group boundaries.
sim590
force-pushed
the
fix/movewindow-tab-containment
branch
from
May 27, 2026 18:31
baa1d6c to
1f2bf4a
Compare
sim590
added a commit
to sim590/hy3
that referenced
this pull request
May 28, 2026
The merge conflict resolution between outfoxxed#295 (movewindow-tab-containment) and outfoxxed#296 (wrap-tab-single-child) kept only the outfoxxed#296 condition (break_parent->parent isTab) and dropped the outfoxxed#295 condition (group.isTab). Both are needed: outfoxxed#295 stops traversal when break_parent itself is a tab group, outfoxxed#296 stops when a split's parent is a tab. Without outfoxxed#295's check, windows escape tab groups when moved at the boundary.
When a split group's parent is a tab group, the shift traversal must also stop at that boundary. Without this, windows can escape a tab group that contains split children. This complements the existing group.isTab() check which handles the case where break_parent itself is a tab group.
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.
Summary
When using
hy3:movewindowto move a window out of a sub-group (e.g.SplitH) nested inside a tab group, the window escapes the tab group entirely instead of being placed as a sibling within it.For example, given
t(h(a, b)), movingbto the right should producet(h(a), b), but insteadbexits the tab group completely.Root cause
In
shiftOrGetFocus, the parent traversal loop usesonceas the sole condition to stop at group boundaries after breaking out of a child group. Sinceonceisfalseby default, the loop keeps climbing past tab groups. Similarly, after the break, the neighbor descent logic enters adjacent groups instead of placing the window next to them.Fix
Two one-line changes in
src/Hy3Layout.cpp:Break condition (line 1477): Add
group.isTab()so the traversal loop stops at tab group boundaries:Neighbor descent guard (line 1526): Add
parent_group.isTab()so the window is placed next to the neighboring group instead of descending into it:Testing
Manually tested the following scenarios:
t(h(a, b))bt(h(a), b)t(a, b, c)bt(a, c, b)t(a)ah(a, b)ah(b, a)(unchanged)t(v(a, b))at(v(b, a))(unchanged)t(h(a, b), c)bt(h(a), b, c)h(t(a,b,c), d)dt(a,b,c,d)