Skip to content

fix: focusing a tabbed or stacked group returns to its last-used window - #569

Open
mattchristenson wants to merge 3 commits into
forge-ext:mainfrom
Reliable-Collaboration:fix/group-focus-last-used
Open

mattchristenson wants to merge 3 commits into
forge-ext:mainfrom
Reliable-Collaboration:fix/group-focus-last-used

Conversation

@mattchristenson

Copy link
Copy Markdown

Fixes #230. Builds on #568, whose focus handler now passes the focused window to updateStackedFocus() / updateTabbedFocus().

Stacked on #568: until that merges, this PR's diff also shows it and #557. Please review only the last commit.

Change.

  • Remembering. On every focus change, a tiled window is remembered in every tabbed or stacked group it is in (lastTabFocus, which main writes in a few places but never reads), also when it is nested inside a container in the group. Floating windows don't count.
  • Returning. In Tree.focus(), entering a container goes through one helper, _entryWindow():
    • a tabbed or stacked group returns its last-used window, if that is still a visible tile anywhere in it;
    • so does a split that contains a group;
    • otherwise the choice is unchanged.

Testing. scenarios/17_stack_tab_switching.py: 17.5 (stack) and 17.7 (tab group) fail on #568 (this PR's base) and on main, and pass here: 6/13 → 8/13. 17.10 checks the fallback when the last-used window is gone. On a build with all the related PRs, scenario 17 passes 13/13, in the sandbox and in a real GNOME Shell 50 session. prettier@2.7.1 --check is clean.

🤖 Generated with Claude Code

mattchristenson and others added 3 commits September 26, 2026 17:23
A container's tab bar could stay on screen after the container stopped
being tabbed or left the tree:
- updateDecorationLayout() showed the tab bar of every container with
  tiled windows, tabbed or not, so a container switched back to a split
  (auto-exit-tabbed, the tabbed toggle) kept an empty strip at its old
  size and position;
- removeChild() only destroyed the tab bar of a container that was still
  tabbed, so a container emptied after auto-exit-tabbed had switched it
  to a split (all of its windows closing at once, or moved out of it one
  by one) left its bar behind, with a tab for every former window. It
  also destroyed the tab bar of a tabbed container that was only being
  moved (appendChild/insertBefore), which then never got one again.

Show tab bars only for tabbed containers. Tear down tab bars only when
nodes really leave the tree (removeNode, removeWorkspace): destroy the
tabs of the windows that leave and the tab bars of the containers that
leave, whatever their layout, and detach any other tabs. Apply
auto-exit-tabbed to the container that lost a child, also when the
emptied parent in between was removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A stacked container placed each window one header height lower than the one
before, relying on the windows' own title bars peeking out. Only the windows
before the focused one showed: with focus on the first window of a stack,
every other window was completely hidden, with nothing showing it was there.
(A 2022 change meant to reorder the stack on focus never took effect: the
focus handler called updateStackedFocus() without the window.)

A stack now works like i3's: a title list at its top with one row per window
(the tabbed title bar laid out vertically, with the same icon, title, close
button and click-to-focus), and all the windows in the same place below it.
The focused window is raised and its row highlighted; the order never
changes, so Super+J/K walk the list. With title bars turned off
(showtab-decoration-enabled), stacks keep the old cascade.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moving focus into a stacked group from outside it (Super+H/J/K/L) always
focused the stack's last window, and into a tabbed group its first or last
tab, whichever window had been used there before (forge-ext#230).

Tabbed and stacked groups now remember their last focused window
(lastTabFocus, already used for tabs in some places, is now kept up to date
on every focus change for both), and focus arriving from outside the group
goes to it, if it is still a visible tile there. Moving within a group is
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: forge always focus the bottom window when switch focus in 2 different stacked group

1 participant