From 63b794b27804652aa8b3306ba347e22a72897d88 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Wed, 10 Jun 2026 08:43:49 +0200 Subject: [PATCH] Return to the focused main view when escaping the staged half too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Diving into staging from a focused main view records a snapshot so escape can return there. But it was recorded only on the half we entered (unstaged), and staging the last unstaged hunk moves the selection to the staged half (RefreshStagingPanel pushes StagingSecondary when the unstaged state goes empty). Escaping from there found no snapshot and fell back to the files panel, instead of returning to the focused main view. Record the snapshot on both staging halves at entry, and clear both on escape. Escaping from either half now returns to the focused main view, and the identity-based restore lands on the line the explorer ended up selecting — which, with the last unstaged hunk gone, is shown in the main view (the file now has only staged changes, so no split). Routing the split-and-tabbed-to-staged case to the secondary focused main view is left for follow-up; see focused-main-view-notes.md §14.3. --- pkg/gui/controllers/files_controller.go | 11 ++++++++--- pkg/gui/controllers/helpers/patch_building_helper.go | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index fe35bab9b..0bd59ca16 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -779,9 +779,14 @@ func (self *FilesController) EnterFile(focusedMainViewSnapshot *types.FocusedMai } context := lo.Ternary(opts.ClickedWindowName == "secondary", self.c.Contexts().StagingSecondary, self.c.Contexts().Staging) - // Set on every entry (so it can't leak from a previous main-view entry into a - // subsequent normal one), right as we push the staging view. - context.SetFocusedMainViewSnapshot(focusedMainViewSnapshot) + // Record the focused-main-view return on *both* staging halves, not just the + // one we're entering: staging the last unstaged hunk (or tabbing) moves the + // selection to the other half, and escaping from there must still know to + // return to the focused main view rather than falling back to the files panel. + // Set on every entry (nil for a normal entry through the files panel) so a + // snapshot can't leak from a previous main-view entry into a subsequent normal one. + self.c.Contexts().Staging.SetFocusedMainViewSnapshot(focusedMainViewSnapshot) + self.c.Contexts().StagingSecondary.SetFocusedMainViewSnapshot(focusedMainViewSnapshot) self.c.Context().Push(context, opts) self.c.Helpers().PatchBuilding.ShowHunkStagingHint() diff --git a/pkg/gui/controllers/helpers/patch_building_helper.go b/pkg/gui/controllers/helpers/patch_building_helper.go index 9f821d2d7..35d3878c2 100644 --- a/pkg/gui/controllers/helpers/patch_building_helper.go +++ b/pkg/gui/controllers/helpers/patch_building_helper.go @@ -53,7 +53,13 @@ func EscapeFromPatchExplorer(c *HelperCommon, stagingHelper *StagingHelper, cont return } + // Clear the snapshot wherever it was set. The staging view records it on both + // its halves (see FilesController.EnterFile) so escape works after the selection + // crosses between them; clear both so a stale one can't linger. For patch + // building it's only on the context we're escaping from. context.SetFocusedMainViewSnapshot(nil) + c.Contexts().Staging.SetFocusedMainViewSnapshot(nil) + c.Contexts().StagingSecondary.SetFocusedMainViewSnapshot(nil) // Restore the side panel's selection before we render it, so it shows the // same content the main view had (diving into staging can change it, e.g.