diff --git a/pkg/gui/side_panels.go b/pkg/gui/side_panels.go index 361d54fb1..8b327b197 100644 --- a/pkg/gui/side_panels.go +++ b/pkg/gui/side_panels.go @@ -125,4 +125,13 @@ func (gui *Gui) assignSidePanelWindows(contextTree *context.ContextTree) { ctx.SetWindowName(name) } } + + // The transient contexts take over the window of the context they are + // drilled into from, but they need a valid initial window before their + // first use. Assign the window hosting branches or commits, respectively; + // unlike e.g. remotes, those tabs can't be hidden, so their windows are + // always part of the layout. + contextTree.RemoteBranches.SetWindowName(contextTree.Branches.GetWindowName()) + contextTree.SubCommits.SetWindowName(contextTree.Branches.GetWindowName()) + contextTree.CommitFiles.SetWindowName(contextTree.LocalCommits.GetWindowName()) } diff --git a/pkg/gui/side_panels_test.go b/pkg/gui/side_panels_test.go index b1240c357..24813b4ae 100644 --- a/pkg/gui/side_panels_test.go +++ b/pkg/gui/side_panels_test.go @@ -28,3 +28,23 @@ func TestSidePanelLookupsCoverAllValidTabs(t *testing.T) { assert.Equal(t, want, sortedKeys(gui.sidePanelTabTitles())) assert.Equal(t, want, sortedKeys(sidePanelContexts(gui.contextTree()))) } + +// The transient contexts must end up in windows that exist under the configured +// panel layout, or their views would be laid out for a window that is never +// shown. +func TestAssignSidePanelWindowsCoversTransientContexts(t *testing.T) { + gui := NewDummyGui() + gui.c.UserConfig().Gui.SidePanels = []config.SidePanel{ + {"worktrees", "branches", "remotes"}, + {"files"}, + {"tags", "commits"}, + {"stash"}, + } + + contextTree := gui.contextTree() + gui.assignSidePanelWindows(contextTree) + + assert.Equal(t, "worktrees", contextTree.RemoteBranches.GetWindowName()) + assert.Equal(t, "worktrees", contextTree.SubCommits.GetWindowName()) + assert.Equal(t, "tags", contextTree.CommitFiles.GetWindowName()) +}