diff --git a/pkg/gui/controllers/helpers/app_status_helper.go b/pkg/gui/controllers/helpers/app_status_helper.go index 2a09ee594f93..ff8505f92542 100644 --- a/pkg/gui/controllers/helpers/app_status_helper.go +++ b/pkg/gui/controllers/helpers/app_status_helper.go @@ -82,13 +82,16 @@ func (self *AppStatusHelper) renderAppStatus() { func (self *AppStatusHelper) renderAppStatusSync(stop chan struct{}) { ticker := time.NewTicker(time.Millisecond * 50) go func() { + self.c.SetFreezeInformationView(true) + defer func() { self.c.SetFreezeInformationView(false) }() + outer: for { select { case <-ticker.C: appStatus := self.statusMgr().GetStatusString() self.c.SetViewContent(self.c.Views().AppStatus, " "+appStatus) - _ = self.c.GocuiGui().ForceRedrawView(self.c.Views().AppStatus) + _ = self.c.GocuiGui().ForceRedrawViews(self.c.Views().AppStatus, self.c.Views().Options) case <-stop: break outer } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 7c3f51000ccc..c4b8ffd0ea48 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -129,6 +129,10 @@ type Gui struct { c *helpers.HelperCommon helpers *helpers.Helpers + // freeze what's displayed in the Information view to this string. Empty + // when not frozen + frozenInformationStr string + integrationTest integrationTypes.IntegrationTest afterLayoutFuncs chan func() error diff --git a/pkg/gui/gui_common.go b/pkg/gui/gui_common.go index 72662f1c193e..26cb412913e5 100644 --- a/pkg/gui/gui_common.go +++ b/pkg/gui/gui_common.go @@ -157,6 +157,14 @@ func (self *guiCommon) MainViewPairs() types.MainViewPairs { } } +func (self *guiCommon) SetFreezeInformationView(freeze bool) { + if freeze { + self.gui.frozenInformationStr = self.gui.informationStr() + } else { + self.gui.frozenInformationStr = "" + } +} + func (self *guiCommon) State() types.IStateAccessor { return self.gui.stateAccessor } diff --git a/pkg/gui/information_panel.go b/pkg/gui/information_panel.go index 00867fb9254f..1f7ee0b9a0b7 100644 --- a/pkg/gui/information_panel.go +++ b/pkg/gui/information_panel.go @@ -10,6 +10,10 @@ import ( ) func (gui *Gui) informationStr() string { + if gui.frozenInformationStr != "" { + return gui.frozenInformationStr + } + if activeMode, ok := gui.helpers.Mode.GetActiveMode(); ok { return activeMode.Description() } diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index a3e0ca4c1ed1..fcb9cbeb4272 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -49,6 +49,11 @@ type IGuiCommon interface { // used purely for the sake of RenderToMainViews to provide the pair of main views we want to render to MainViewPairs() MainViewPairs + // set the information view (right side of the status bar) to frozen so that + // it doesn't change when modes change. Useful during blocking operations + // that want to redraw the status view (WithWaitingStatusSync) to avoid flicker. + SetFreezeInformationView(freeze bool) + // returns true if command completed successfully RunSubprocess(cmdObj oscommands.ICmdObj) (bool, error) RunSubprocessAndRefresh(oscommands.ICmdObj) error diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go index 8b9901cfb20c..a8d93c52f328 100644 --- a/vendor/github.com/jesseduffield/gocui/gui.go +++ b/vendor/github.com/jesseduffield/gocui/gui.go @@ -1152,17 +1152,19 @@ func (g *Gui) flush() error { return nil } -// force redawing a view outside of the normal main loop. Useful during longer +// force redawing one or more views outside of the normal main loop. Useful during longer // operations that block the main thread, to update a spinner in a status view. -func (g *Gui) ForceRedrawView(v *View) error { +func (g *Gui) ForceRedrawViews(views ...*View) error { for _, m := range g.managers { if err := m.Layout(g); err != nil { return err } } - if err := v.draw(); err != nil { - return err + for _, v := range views { + if err := v.draw(); err != nil { + return err + } } Screen.Show()