From 4e441127f399bf3865f1f16732977349b46bcd86 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 16 Jun 2024 10:59:53 +0200 Subject: [PATCH 1/2] 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() From db0a1586d99393cda79e6022f3b3b8b4138b0e8b Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 16 Jun 2024 18:09:21 +0200 Subject: [PATCH 2/2] Highlight inactive selection in bold An inactive selection is one where the view is part of the context stack, but not the active view. For example, the files view when you enter the staging panel, or any view when you open a panel. --- docs/Config.md | 4 +++ go.mod | 2 +- go.sum | 4 +-- pkg/config/user_config.go | 25 +++++++++++-------- pkg/gui/context.go | 4 +++ pkg/gui/context/view_trait.go | 1 + pkg/gui/views.go | 1 + pkg/theme/theme.go | 6 +++++ schema/config.json | 12 +++++++++ vendor/github.com/jesseduffield/gocui/view.go | 15 ++++++++++- vendor/modules.txt | 2 +- 11 files changed, 60 insertions(+), 16 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index 11cc13333..67d73ebd4 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -122,6 +122,10 @@ gui: selectedLineBgColor: - blue + # Background color of selected line when view doesn't have focus. + inactiveViewSelectedLineBgColor: + - bold + # Foreground color of copied commit cherryPickedCommitFgColor: - blue diff --git a/go.mod b/go.mod index 4e189992b..69546555d 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/integrii/flaggy v1.4.0 github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d - github.com/jesseduffield/gocui v0.3.1-0.20240623095254-05e1204c2454 + github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e diff --git a/go.sum b/go.sum index 19c698189..dae59e807 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE= github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o= -github.com/jesseduffield/gocui v0.3.1-0.20240623095254-05e1204c2454 h1:rTPA5WiPM1SPUA3r2kSb3RiILC93am6irMvOLjO7JNA= -github.com/jesseduffield/gocui v0.3.1-0.20240623095254-05e1204c2454/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= +github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d h1:I6rViLB+ZW5SnS8P7ZE0FdY6lMfx803qZ9ZYEYCvfro= +github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0= github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo= github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY= diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 47fbe2eea..7ab567fbe 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -179,6 +179,8 @@ type ThemeConfig struct { // Background color of selected line. // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#highlighting-the-selected-line SelectedLineBgColor []string `yaml:"selectedLineBgColor" jsonschema:"minItems=1,uniqueItems=true"` + // Background color of selected line when view doesn't have focus. + InactiveViewSelectedLineBgColor []string `yaml:"inactiveViewSelectedLineBgColor" jsonschema:"minItems=1,uniqueItems=true"` // Foreground color of copied commit CherryPickedCommitFgColor []string `yaml:"cherryPickedCommitFgColor" jsonschema:"minItems=1,uniqueItems=true"` // Background color of copied commit @@ -668,17 +670,18 @@ func GetDefaultConfig() *UserConfig { TimeFormat: "02 Jan 06", ShortTimeFormat: time.Kitchen, Theme: ThemeConfig{ - ActiveBorderColor: []string{"green", "bold"}, - SearchingActiveBorderColor: []string{"cyan", "bold"}, - InactiveBorderColor: []string{"default"}, - OptionsTextColor: []string{"blue"}, - SelectedLineBgColor: []string{"blue"}, - CherryPickedCommitBgColor: []string{"cyan"}, - CherryPickedCommitFgColor: []string{"blue"}, - MarkedBaseCommitBgColor: []string{"yellow"}, - MarkedBaseCommitFgColor: []string{"blue"}, - UnstagedChangesColor: []string{"red"}, - DefaultFgColor: []string{"default"}, + ActiveBorderColor: []string{"green", "bold"}, + SearchingActiveBorderColor: []string{"cyan", "bold"}, + InactiveBorderColor: []string{"default"}, + OptionsTextColor: []string{"blue"}, + SelectedLineBgColor: []string{"blue"}, + InactiveViewSelectedLineBgColor: []string{"bold"}, + CherryPickedCommitBgColor: []string{"cyan"}, + CherryPickedCommitFgColor: []string{"blue"}, + MarkedBaseCommitBgColor: []string{"yellow"}, + MarkedBaseCommitFgColor: []string{"blue"}, + UnstagedChangesColor: []string{"red"}, + DefaultFgColor: []string{"default"}, }, CommitAuthorFormat: "auto", CommitLength: CommitLengthConfig{Show: true}, diff --git a/pkg/gui/context.go b/pkg/gui/context.go index be5a720e3..28ecf2405 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -230,6 +230,10 @@ func (self *ContextMgr) ActivateContext(c types.Context, opts types.OnFocusOpts) self.gui.helpers.Window.SetWindowContext(c) self.gui.helpers.Window.MoveToTopOfWindow(c) + oldView := self.gui.c.GocuiGui().CurrentView() + if oldView != nil && oldView.Name() != viewName { + oldView.HighlightInactive = true + } if _, err := self.gui.c.GocuiGui().SetCurrentView(viewName); err != nil { return err } diff --git a/pkg/gui/context/view_trait.go b/pkg/gui/context/view_trait.go index 191419897..5342071ef 100644 --- a/pkg/gui/context/view_trait.go +++ b/pkg/gui/context/view_trait.go @@ -49,6 +49,7 @@ func (self *ViewTrait) SetContent(content string) { func (self *ViewTrait) SetHighlight(highlight bool) { self.view.Highlight = highlight + self.view.HighlightInactive = false } func (self *ViewTrait) SetFooter(value string) { diff --git a/pkg/gui/views.go b/pkg/gui/views.go index 9fd775764..9a4fa0a47 100644 --- a/pkg/gui/views.go +++ b/pkg/gui/views.go @@ -92,6 +92,7 @@ func (gui *Gui) createAllViews() error { (*mapping.viewPtr).FrameRunes = frameRunes (*mapping.viewPtr).FgColor = theme.GocuiDefaultTextColor (*mapping.viewPtr).SelBgColor = theme.GocuiSelectedLineBgColor + (*mapping.viewPtr).InactiveViewSelBgColor = theme.GocuiInactiveViewSelectedLineBgColor } gui.Views.Options.Frame = false diff --git a/pkg/theme/theme.go b/pkg/theme/theme.go index 78be46fb6..acd8ebf71 100644 --- a/pkg/theme/theme.go +++ b/pkg/theme/theme.go @@ -24,11 +24,15 @@ var ( // GocuiSelectedLineBgColor is the background color for the selected line in gocui GocuiSelectedLineBgColor gocui.Attribute + // GocuiInactiveViewSelectedLineBgColor is the background color for the selected line in gocui if the view doesn't have focus + GocuiInactiveViewSelectedLineBgColor gocui.Attribute OptionsColor gocui.Attribute // SelectedLineBgColor is the background color for the selected line SelectedLineBgColor = style.New() + // InactiveViewSelectedLineBgColor is the background color for the selected line if the view doesn't have the focus + InactiveViewSelectedLineBgColor = style.New() // CherryPickedCommitColor is the text style when cherry picking a commit CherryPickedCommitTextStyle = style.New() @@ -49,6 +53,7 @@ func UpdateTheme(themeConfig config.ThemeConfig) { InactiveBorderColor = GetGocuiStyle(themeConfig.InactiveBorderColor) SearchingActiveBorderColor = GetGocuiStyle(themeConfig.SearchingActiveBorderColor) SelectedLineBgColor = GetTextStyle(themeConfig.SelectedLineBgColor, true) + InactiveViewSelectedLineBgColor = GetTextStyle(themeConfig.InactiveViewSelectedLineBgColor, true) cherryPickedCommitBgTextStyle := GetTextStyle(themeConfig.CherryPickedCommitBgColor, true) cherryPickedCommitFgTextStyle := GetTextStyle(themeConfig.CherryPickedCommitFgColor, false) @@ -62,6 +67,7 @@ func UpdateTheme(themeConfig config.ThemeConfig) { UnstagedChangesColor = unstagedChangesTextStyle GocuiSelectedLineBgColor = GetGocuiStyle(themeConfig.SelectedLineBgColor) + GocuiInactiveViewSelectedLineBgColor = GetGocuiStyle(themeConfig.InactiveViewSelectedLineBgColor) OptionsColor = GetGocuiStyle(themeConfig.OptionsTextColor) OptionsFgColor = GetTextStyle(themeConfig.OptionsTextColor, false) diff --git a/schema/config.json b/schema/config.json index 271fd8be6..802069bed 100644 --- a/schema/config.json +++ b/schema/config.json @@ -186,6 +186,18 @@ "blue" ] }, + "inactiveViewSelectedLineBgColor": { + "items": { + "type": "string" + }, + "type": "array", + "minItems": 1, + "uniqueItems": true, + "description": "Background color of selected line when view doesn't have focus.", + "default": [ + "bold" + ] + }, "cherryPickedCommitFgColor": { "items": { "type": "string" diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go index a32519b80..6589c6981 100644 --- a/vendor/github.com/jesseduffield/gocui/view.go +++ b/vendor/github.com/jesseduffield/gocui/view.go @@ -81,6 +81,11 @@ type View struct { // foreground colors of the selected line, when it is highlighted. SelBgColor, SelFgColor Attribute + // InactiveViewSelBgColor is used to configure the background color of the + // selected line, when it is highlighted but the view doesn't have the + // focus. + InactiveViewSelBgColor Attribute + // If Editable is true, keystrokes will be added to the view's internal // buffer at the cursor position. Editable bool @@ -96,6 +101,9 @@ type View struct { // If Highlight is true, Sel{Bg,Fg}Colors will be used // for the line under the cursor position. Highlight bool + // If HighlightInactive is true, InavtiveViewSel{Bg,Fg}Colors will be used + // instead of Sel{Bg,Fg}Colors for highlighting selected lines. + HighlightInactive bool // If Frame is true, a border will be drawn around the view. Frame bool @@ -404,6 +412,7 @@ func newView(name string, x0, y0, x1, y1 int, mode OutputMode) *View { v.FgColor, v.BgColor = ColorDefault, ColorDefault v.SelFgColor, v.SelBgColor = ColorDefault, ColorDefault + v.InactiveViewSelBgColor = ColorDefault v.TitleColor, v.FrameColor = ColorDefault, ColorDefault return v } @@ -506,7 +515,11 @@ func (v *View) setRune(x, y int, ch rune, fgColor, bgColor Attribute) error { fgColor += 8 } fgColor = fgColor | AttrBold - bgColor = bgColor | v.SelBgColor + if v.HighlightInactive { + bgColor = bgColor | v.InactiveViewSelBgColor + } else { + bgColor = bgColor | v.SelBgColor + } } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 62d47eea4..c7d601a93 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -172,7 +172,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem github.com/jesseduffield/go-git/v5/utils/merkletrie/index github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame github.com/jesseduffield/go-git/v5/utils/merkletrie/noder -# github.com/jesseduffield/gocui v0.3.1-0.20240623095254-05e1204c2454 +# github.com/jesseduffield/gocui v0.3.1-0.20240623124136-ce5274be521d ## explicit; go 1.12 github.com/jesseduffield/gocui # github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10