Merge pull request #776 from jesseduffield/copilot/disable-forced-project-view

Hide project/services panels when not in a docker-compose project directory
This commit is contained in:
Jesse Duffield 2026-04-19 11:55:51 +10:00 committed by GitHub
commit 9134abeefd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 59 additions and 29 deletions

View file

@ -176,23 +176,30 @@ func (gui *Gui) sidePanelChildren(width int, height int) []*boxlayout.Box {
}
// The project panel is compact (Size: 3) when not focused, but expands
// when focused to show the list of projects.
projectBox := &boxlayout.Box{
Window: sideWindowNames[0],
Size: 3,
}
if currentWindow == sideWindowNames[0] {
projectBox = &boxlayout.Box{
// when focused to show the list of projects. This only applies when the
// project panel is actually visible (i.e. we are inside a compose project).
if len(sideWindowNames) > 0 && sideWindowNames[0] == "project" {
projectBox := &boxlayout.Box{
Window: sideWindowNames[0],
Weight: 2,
Size: 3,
}
if currentWindow == sideWindowNames[0] {
projectBox = &boxlayout.Box{
Window: sideWindowNames[0],
Weight: 2,
}
}
return append([]*boxlayout.Box{
projectBox,
}, lo.Map(sideWindowNames[1:], func(window string, _ int) *boxlayout.Box {
return accordionBox(&boxlayout.Box{Window: window, Weight: 1})
})...)
}
return append([]*boxlayout.Box{
projectBox,
}, lo.Map(sideWindowNames[1:], func(window string, _ int) *boxlayout.Box {
return lo.Map(sideWindowNames, func(window string, _ int) *boxlayout.Box {
return accordionBox(&boxlayout.Box{Window: window, Weight: 1})
})...)
})
} else {
squashedHeight := 1
if height >= 21 {

View file

@ -83,25 +83,36 @@ func (gui *Gui) getContainersPanel() *panels.SideListPanel[*commands.Container]
return sortContainers(a, b, gui.Config.UserConfig.Gui.LegacySortContainers)
},
Filter: func(container *commands.Container) bool {
// Note that this is O(N*M) time complexity where N is the number of services
// and M is the number of containers. We expect N to be small but M may be large,
// so we will need to keep an eye on this.
if !gui.Config.UserConfig.Gui.ShowAllContainers && !isStandaloneContainer(container) {
return false
}
if !gui.State.ShowExitedContainers && container.Container.State == "exited" {
return false
}
// Filter by selected project. Containers with no project (truly
// standalone, not from any compose project) are always shown.
selectedProject := gui.getSelectedProjectName()
if selectedProject == "" {
selectedProject = gui.DockerCommand.LocalProjectName
}
if selectedProject != "" && container.ProjectName != "" && container.ProjectName != selectedProject {
return false
// Only apply project and standalone filtering when we are inside a
// docker-compose project. Outside of a compose project all
// containers are shown in a flat list regardless of which compose
// project they belong to.
if gui.DockerCommand.InDockerComposeProject {
// This check must be inside the InDockerComposeProject guard:
// outside a compose project, services are still derived from
// container labels, so compose-managed containers from other
// projects would be incorrectly hidden.
//
// Note that this is O(N*M) time complexity where N is the number of services
// and M is the number of containers. We expect N to be small but M may be large,
// so we will need to keep an eye on this.
if !gui.Config.UserConfig.Gui.ShowAllContainers && !isStandaloneContainer(container) {
return false
}
// Filter by selected project. Containers with no project (truly
// standalone, not from any compose project) are always shown.
selectedProject := gui.getSelectedProjectName()
if selectedProject == "" {
selectedProject = gui.DockerCommand.LocalProjectName
}
if selectedProject != "" && container.ProjectName != "" && container.ProjectName != selectedProject {
return false
}
}
return true

View file

@ -58,6 +58,14 @@ func (gui *Gui) getProjectPanel() *panels.SideListPanel[*commands.Project] {
// containers to show only those belonging to the selected project.
return gui.renderContainersAndServices()
},
Hide: func() bool {
// Only show the project panel when we are inside a docker-compose
// project directory. When launched outside of a compose project
// there is no meaningful local project to display, so we hide the
// panel and let the containers panel show all containers in a flat
// list (matching the behaviour from before v0.25).
return !gui.DockerCommand.InDockerComposeProject
},
}
}

View file

@ -90,8 +90,12 @@ func (gui *Gui) getServicesPanel() *panels.SideListPanel[*commands.Service] {
return presentation.GetServiceDisplayStrings(&gui.Config.UserConfig.Gui, service)
},
Hide: func() bool {
// Show services panel if there are any compose projects (local or discovered)
return !gui.DockerCommand.InDockerComposeProject && len(gui.Panels.Services.List.GetAllItems()) == 0
// Only show the services panel when we are inside a docker-compose
// project directory. When launched outside of a compose project
// there is no local project context, so the panel is hidden and
// all containers are shown in a flat list (matching pre-v0.25
// behaviour).
return !gui.DockerCommand.InDockerComposeProject
},
}
}