diff --git a/pkg/gui/controllers/helpers/staging_helper.go b/pkg/gui/controllers/helpers/staging_helper.go index 2c6a0412b..2666c56ce 100644 --- a/pkg/gui/controllers/helpers/staging_helper.go +++ b/pkg/gui/controllers/helpers/staging_helper.go @@ -827,20 +827,24 @@ func (self *StagingHelper) diffLineInfoFromParsed(parsed parsedDiffLine) types.D // the existing content — the diff is unaffected by patch membership, so it never // re-renders. func (self *StagingHelper) RefreshInclusionGutter() { - mainContext := self.c.Contexts().Normal - v := mainContext.GetView() + // The gutter is painted on the Normal (commit-diff) pane, but it's a focused-main-view + // affordance of the whole pair: it stays visible while either pane holds focus, so it + // doesn't vanish when you tab to the secondary custom-patch pane. + v := self.c.Contexts().Normal.GetView() - // Check focus first: the gutter only shows while the main view holds focus, and - // NextInStack below requires the context to be in the stack — which it is exactly - // when it's the current one. + // Check focus first: the gutter only shows while the focused main view holds focus, and + // NextInStack below requires the context to be in the stack — which it is exactly when + // it's the current one. The side panel is found beneath whichever pane is current. patchBuilder := self.c.Git().Patch.PatchBuilder - focused := self.c.Context().CurrentStatic().GetKey() == mainContext.GetKey() + current := self.c.Context().CurrentStatic() + focused := current.GetKey() == self.c.Contexts().Normal.GetKey() || + current.GetKey() == self.c.Contexts().NormalSecondary.GetKey() if !focused || !patchBuilder.Active() { v.SetInclusionGutter(false, nil) return } - sidePanel := self.c.Context().NextInStack(mainContext) + sidePanel := self.c.Context().NextInStack(current) diffMainView, ok := sidePanel.(types.DiffMainViewContext) if !ok || diffMainView.GetDiffMainViewType() != types.DiffMainViewTypePatchBuilding { v.SetInclusionGutter(false, nil) diff --git a/pkg/gui/controllers/main_view_controller.go b/pkg/gui/controllers/main_view_controller.go index d42ecf341..8d44aa3f9 100644 --- a/pkg/gui/controllers/main_view_controller.go +++ b/pkg/gui/controllers/main_view_controller.go @@ -233,12 +233,14 @@ func (self *MainViewController) GetOnFocus() func(types.OnFocusOpts) { } } -// GetOnFocusLost hides the inclusion gutter when the focused main view loses focus — -// it's a focused-main-view affordance, so it shouldn't linger in the side panel's diff -// preview. A no-op when no gutter is shown. +// GetOnFocusLost re-evaluates the inclusion gutter as the focused main view loses focus. +// It's a focused-main-view affordance of the whole pair, so it must persist when tabbing +// between the two panes but hide when focus leaves the pair entirely. By the time this runs +// the new context is already current, so RefreshInclusionGutter decides correctly (and so +// the gutter doesn't flicker off-then-on across a pane switch). func (self *MainViewController) GetOnFocusLost() func(types.OnFocusLostOpts) { return func(types.OnFocusLostOpts) { - self.context.GetView().SetInclusionGutter(false, nil) + self.c.Helpers().Staging.RefreshInclusionGutter() } }