Fix side panel rendering when branches/commits are not their panel's first tab (#5825)

Side panel rendering was broken when 'branches' or 'commits' were not
the first tab in their respective side panel.

Fixes #5823.
This commit is contained in:
Stefan Haller 2026-07-17 12:16:24 +02:00 committed by GitHub
commit 4b97c2ba61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 99 additions and 1 deletions

View file

@ -154,7 +154,14 @@ func (gui *Gui) layout(g *gocui.Gui) error {
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
return err
}
view.Visible = gui.helpers.Window.GetViewNameForWindow(context.GetWindowName()) == context.GetViewName()
// A transient view is visible if it is the view its window is currently
// showing — but only if that window is part of the layout at all. For a
// window without dimensions, setViewFromDimensions parks the view at full
// screen size in the background, so making it visible would cover all
// windows below it.
_, windowHasDimensions := viewDimensions[context.GetWindowName()]
view.Visible = windowHasDimensions &&
gui.helpers.Window.GetViewNameForWindow(context.GetWindowName()) == context.GetViewName()
}
if gui.PrevLayout.Information != informationStr {

View file

@ -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())
}

View file

@ -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())
}

View file

@ -484,6 +484,8 @@ var tests = []*components.IntegrationTest{
tag.Reset,
tag.ResetToDuplicateNamedBranch,
ui.Accordion,
ui.BranchesNotFirstTab,
ui.CommitsNotFirstTab,
ui.DisableSwitchTabWithPanelJumpKeys,
ui.EmptyMenu,
ui.HideSidePanel,

View file

@ -0,0 +1,31 @@
package ui
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var BranchesNotFirstTab = NewIntegrationTest(NewIntegrationTestArgs{
Description: "With gui.sidePanels grouping branches behind another tab, no ghost view must appear over the side panels",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(cfg *config.AppConfig) {
cfg.GetUserConfig().Gui.SidePanels = []config.SidePanel{
{"worktrees", "branches", "remotes"},
{"files"},
{"commits", "tags"},
{"stash"},
}
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
// The remote branches and sub-commits views are only shown after
// drilling into a remote or a branch; at startup both must be hidden,
// or they'd cover the side panels.
t.Views().RemoteBranches().
IsInvisible()
t.Views().SubCommits().IsInvisible()
},
})

View file

@ -0,0 +1,29 @@
package ui
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var CommitsNotFirstTab = NewIntegrationTest(NewIntegrationTestArgs{
Description: "With gui.sidePanels grouping commits behind another tab, no ghost view must appear over the side panels",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(cfg *config.AppConfig) {
cfg.GetUserConfig().Gui.SidePanels = []config.SidePanel{
{"branches", "worktrees", "remotes"},
{"files"},
{"tags", "commits"},
{"stash"},
}
},
SetupRepo: func(shell *Shell) {
shell.EmptyCommit("one")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
// The commit files view is only shown after drilling into a commit; at
// startup it must be hidden, or it'd cover the side panels.
t.Views().CommitFiles().
IsInvisible()
},
})