summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2023-07-19 21:16:27 +1000
committerJesse Duffield <jessedduffield@gmail.com>2023-07-19 21:16:27 +1000
commita5ee61c117a7b1e895cced1c131eb52d8c1e5236 (patch)
treecab29f4411ecdc128b4dc7e76a11429c28f9b14f
parentbe02786dad8785abc214cb5bfeee657033761945 (diff)
Properly fix accordion issue
The true issue was that we were focusing the line in the view before it gets resized in the layout function. This meant if the view was squashed in accordion mode, the view wouldn't know how to set the cursor/origin to focus the line. Now we've got a queue of 'after layout' functions i.e. functions to call at the end of the layout function, right before views are drawn. The only caveat is that we can't have an infinite buffer so we're arbitrarily capping it at 1000 and dropping functions if we exceed that limit. But that really should never happen.
-rw-r--r--pkg/gui/context/list_context_trait.go9
-rw-r--r--pkg/gui/gui.go5
-rw-r--r--pkg/gui/gui_common.go9
-rw-r--r--pkg/gui/layout.go18
-rw-r--r--pkg/gui/types/common.go4
5 files changed, 42 insertions, 3 deletions
diff --git a/pkg/gui/context/list_context_trait.go b/pkg/gui/context/list_context_trait.go
index e993719d5..de88d3d3b 100644
--- a/pkg/gui/context/list_context_trait.go
+++ b/pkg/gui/context/list_context_trait.go
@@ -31,7 +31,14 @@ func (self *ListContextTrait) GetList() types.IList {
}
func (self *ListContextTrait) FocusLine() {
- self.GetViewTrait().FocusPoint(self.list.GetSelectedLineIdx())
+ // Doing this at the end of the layout function because we need the view to be
+ // resized before we focus the line, otherwise if we're in accordion mode
+ // the view could be squashed and won't how to adjust the cursor/origin
+ self.c.AfterLayout(func() error {
+ self.GetViewTrait().FocusPoint(self.list.GetSelectedLineIdx())
+ return nil
+ })
+
self.setFooter()
if self.refreshViewportOnChange {
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 1057a85bf..8e8f6e2bd 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -132,6 +132,8 @@ type Gui struct {
helpers *helpers.Helpers
integrationTest integrationTypes.IntegrationTest
+
+ afterLayoutFuncs chan func() error
}
type StateAccessor struct {
@@ -458,7 +460,8 @@ func NewGui(
PopupMutex: &deadlock.Mutex{},
PtyMutex: &deadlock.Mutex{},
},
- InitialDir: initialDir,
+ InitialDir: initialDir,
+ afterLayoutFuncs: make(chan func() error, 1000),
}
gui.WatchFilesForChanges()
diff --git a/pkg/gui/gui_common.go b/pkg/gui/gui_common.go
index c0d7bd460..ee0e51b26 100644
--- a/pkg/gui/gui_common.go
+++ b/pkg/gui/gui_common.go
@@ -168,3 +168,12 @@ func (self *guiCommon) IsAnyModeActive() bool {
func (self *guiCommon) GetInitialKeybindingsWithCustomCommands() ([]*types.Binding, []*gocui.ViewMouseBinding) {
return self.gui.GetInitialKeybindingsWithCustomCommands()
}
+
+func (self *guiCommon) AfterLayout(f func() error) {
+ select {
+ case self.gui.afterLayoutFuncs <- f:
+ default:
+ // hopefully this never happens
+ self.gui.c.Log.Error("afterLayoutFuncs channel is full, skipping function")
+ }
+}
diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go
index 14f79cb5a..ec192527b 100644
--- a/pkg/gui/layout.go
+++ b/pkg/gui/layout.go
@@ -149,7 +149,23 @@ func (gui *Gui) layout(g *gocui.Gui) error {
// if you run `lazygit --logs`
// this will let you see these branches as prettified json
// gui.c.Log.Info(utils.AsJson(gui.State.Model.Branches[0:4]))
- return gui.helpers.Confirmation.ResizeCurrentPopupPanel()
+ if err := gui.helpers.Confirmation.ResizeCurrentPopupPanel(); err != nil {
+ return err
+ }
+
+outer:
+ for {
+ select {
+ case f := <-gui.afterLayoutFuncs:
+ if err := f(); err != nil {
+ return err
+ }
+ default:
+ break outer
+ }
+ }
+
+ return nil
}
func (gui *Gui) prepareView(viewName string) (*gocui.View, error) {
diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go
index 4e5ef627f..02dee3b15 100644
--- a/pkg/gui/types/common.go
+++ b/pkg/gui/types/common.go
@@ -80,6 +80,10 @@ type IGuiCommon interface {
// Runs a function in a goroutine. Use this whenever you want to run a goroutine and keep track of the fact
// that lazygit is still busy. See docs/dev/Busy.md
OnWorker(f func(gocui.Task))
+ // Function to call at the end of our 'layout' function which renders views
+ // For example, you may want a view's line to be focused only after that view is
+ // resized, if in accordion mode.
+ AfterLayout(f func() error)
// returns the gocui Gui struct. There is a good chance you don't actually want to use
// this struct and instead want to use another method above