From 4e441127f399bf3865f1f16732977349b46bcd86 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 16 Jun 2024 10:59:53 +0200 Subject: [PATCH] Clear highlight in HandleFocusLost Remove the old mechanism of clearing the highlight in Layout. This fixes a problem with a wrong highlight showing up in the staging panel when entering a file with only staged changes. Reproduction recipe: 1. stage all changes in a file by pressing space on it in the files panel 2. enter the staged changes panel by pressing enter 3. unstage one of the changes This makes the unstaged changes panel visible, but keeps the focus in the staged changes panel. However, the highlight in the unstaged changes view becomes visible, as if it were focused. To explain why this happens, you need to know how the selection highlighting of a view is turned on or off. It is turned on when it gains the focus, i.e. when ActivateFocus is called on it, which in turn happens when PushContext is called. It is turned off in Layout when gocui sees that the current view is no longer the same as last time, in which case it calls onViewFocusLost on the previous current view. This mechanism only works reliably when there is at most one PushContext call per event handler. If there is more than one, then the first one gets its highlight turned on, then the second one, but since gocui has never seen the first one as the active view in Layout, it doesn't get the highlight turned off again even though it should. And this happens in the above scenario. When pressing enter on a file with only staged changes, we first push the staging context (in FilesController.EnterFile), and then later we push the stagingSecondary context when we realize we only have staged changes. This leaves the highlight of the staging context on. --- pkg/gui/context/simple_context.go | 2 ++ pkg/gui/gui.go | 2 +- pkg/gui/layout.go | 29 ----------------------------- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/pkg/gui/context/simple_context.go b/pkg/gui/context/simple_context.go index 7c00e09f7..cef871cef 100644 --- a/pkg/gui/context/simple_context.go +++ b/pkg/gui/context/simple_context.go @@ -52,6 +52,8 @@ func (self *SimpleContext) HandleFocus(opts types.OnFocusOpts) error { } func (self *SimpleContext) HandleFocusLost(opts types.OnFocusLostOpts) error { + self.GetViewTrait().SetHighlight(false) + _ = self.view.SetOriginX(0) if self.onFocusLostFn != nil { return self.onFocusLostFn(opts) } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 06228e759..66fe5cb9c 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -678,7 +678,7 @@ func (gui *Gui) Run(startArgs appTypes.StartArgs) error { return err } - gui.g.SetManager(gocui.ManagerFunc(gui.layout), gocui.ManagerFunc(gui.getFocusLayout())) + gui.g.SetManager(gocui.ManagerFunc(gui.layout)) if err := gui.createAllViews(); err != nil { return err diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index 2123731e4..861bb0bd1 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -288,35 +288,6 @@ func (gui *Gui) onInitialViewsCreation() error { return nil } -// getFocusLayout returns a manager function for when view gain and lose focus -func (gui *Gui) getFocusLayout() func(g *gocui.Gui) error { - var previousView *gocui.View - return func(g *gocui.Gui) error { - newView := gui.g.CurrentView() - // for now we don't consider losing focus to a popup panel as actually losing focus - if newView != previousView && !gui.helpers.Confirmation.IsPopupPanel(newView.Name()) { - if err := gui.onViewFocusLost(previousView); err != nil { - return err - } - - previousView = newView - } - return nil - } -} - -func (gui *Gui) onViewFocusLost(oldView *gocui.View) error { - if oldView == nil { - return nil - } - - oldView.Highlight = false - - _ = oldView.SetOriginX(0) - - return nil -} - func (gui *Gui) transientContexts() []types.Context { return lo.Filter(gui.State.Contexts.Flatten(), func(context types.Context, _ int) bool { return context.IsTransient()