diff --git a/pkg/gui/context/simple_context.go b/pkg/gui/context/simple_context.go index 83d201f3a..626d5dfcf 100644 --- a/pkg/gui/context/simple_context.go +++ b/pkg/gui/context/simple_context.go @@ -41,7 +41,7 @@ func (self *SimpleContext) HandleFocus(opts types.OnFocusOpts) { fn(opts) } - if self.onRenderToMainFn != nil { + if self.onRenderToMainFn != nil && !opts.SkipMainViewUpdate { self.onRenderToMainFn() } } diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index 5eb699da2..730ed9a24 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -119,6 +119,9 @@ type refreshEnv struct { // reload state (see RefreshOptions.DontBlockRepoSwitch). keepScrollPosition bool + // Whether refreshing a side context should leave the main view unchanged. + skipMainViewUpdate bool + // the repo generation captured when the refresh started generation int @@ -231,6 +234,7 @@ func (self *RefreshHelper) performRefresh(options types.RefreshOptions, calledFr background: options.Background || options.DontBlockRepoSwitch, backgroundRoutine: options.Background, keepScrollPosition: options.Background || options.DontBlockRepoSwitch, + skipMainViewUpdate: options.SkipMainViewUpdate, } if !self.captureOnUIThread(calledFromWorker, env.background, func() { env.generation = self.c.State().GetRepoGeneration() @@ -1672,6 +1676,7 @@ func (self *RefreshHelper) refreshView(context types.Context, env refreshEnv) { self.c.PostRefreshUpdateWithOptions(context, types.OnFocusOpts{ KeepScrollPosition: env.keepScrollPosition, + SkipMainViewUpdate: env.skipMainViewUpdate, }) self.c.AfterLayout(func() error { diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index b1f89baa9..884cbc941 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -345,7 +345,9 @@ func (self *LocalCommitsController) startMovingCommitsIndicator(insertionIndex i func (self *LocalCommitsController) stopMovingCommitsIndicator() { self.stopMovingCommitsIndicatorTicker() self.context().ClearDropInsertionIndex() - self.c.PostRefreshUpdate(self.context()) + self.c.PostRefreshUpdateWithOptions( + self.context(), types.OnFocusOpts{SkipMainViewUpdate: true}, + ) } func (self *LocalCommitsController) stopMovingCommitsIndicatorTicker() { @@ -1171,15 +1173,21 @@ func (self *LocalCommitsController) move( if err := self.c.Git().Rebase.MoveTodos(selectedCommits, offset); err != nil { return err } - self.context().MoveSelection(offset) - self.context().HandleFocus(types.OnFocusOpts{}) // Block input until the refresh has landed: a quick second press must // read the moved todo from the refreshed model, not grab whatever the // advanced selection index points at in the stale one. self.c.RefreshBlockingInput(types.RefreshOptions{ - Scope: []types.RefreshableView{types.REBASE_COMMITS}, - Then: onComplete, + Scope: []types.RefreshableView{types.REBASE_COMMITS}, + SkipMainViewUpdate: true, + Then: func() error { + self.context().MoveSelection(offset) + self.context().FocusLine(true) + if onComplete != nil { + return onComplete() + } + return nil + }, }) return nil } diff --git a/pkg/gui/types/context.go b/pkg/gui/types/context.go index 35662d86c..128c4f08f 100644 --- a/pkg/gui/types/context.go +++ b/pkg/gui/types/context.go @@ -234,6 +234,10 @@ type OnFocusOpts struct { // the view's scroll position alone instead; only for callers that maintain // it themselves, e.g. by keeping the selection at the edge of the viewport. KeepScrollPosition bool + + // Set this when the focused item hasn't changed and the main view's current + // content is still valid. + SkipMainViewUpdate bool } type OnFocusLostOpts struct { diff --git a/pkg/gui/types/refresh.go b/pkg/gui/types/refresh.go index c733e589e..d40a1bec5 100644 --- a/pkg/gui/types/refresh.go +++ b/pkg/gui/types/refresh.go @@ -72,6 +72,10 @@ type RefreshOptions struct { // letting each scope update the UI as soon as it's done. BatchUIUpdates bool + // Set this when the refresh doesn't invalidate the main view's current + // content, so refreshing the side context needn't render it again. + SkipMainViewUpdate bool + // Controls which local branch is selected after the refresh. Defaults to // KeepBranchSelectionByName. BranchSelection BranchSelectionBehavior diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index fabbe1edb..4e14e6c48 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -149,6 +149,9 @@ func (gui *Gui) postRefreshUpdate(c types.Context, opts types.OnFocusOpts) { // correctly, and that integration tests see the up to date selection // state. c.FocusLine(!opts.KeepScrollPosition) + if opts.SkipMainViewUpdate { + return + } currentCtx := gui.State.ContextMgr.Current() if currentCtx.GetKey() == context.NORMAL_MAIN_CONTEXT_KEY || currentCtx.GetKey() == context.NORMAL_SECONDARY_CONTEXT_KEY {