From 787a309b3ab72a5d6892c95126435c83c7fcbe00 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 13 Oct 2026 09:13:15 +0200 Subject: [PATCH] Begin blocking input after capturing the refresh's baseline The next commit makes performRefresh return early right after the capture, and it must not leave the input blocked when it does. This doesn't let any keypress slip through before the block begins. Only refreshes on the UI thread block input, and there the capture runs synchronously. Co-Authored-By: Claude Opus 5.5 (1M context) --- pkg/gui/controllers/helpers/refresh_helper.go | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index 605319a8e..1f27221d8 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -203,17 +203,6 @@ func (self *RefreshHelper) performRefresh(options types.RefreshOptions, calledFr panic("a refresh with a Then callback must not set DontBlockRepoSwitch") } - // A RefreshBlockingInput caller wants keyboard input withheld until the - // refreshed state is in place (see IGuiCommon.RefreshBlockingInput). Begin - // the block synchronously here in the calling handler, so that no keypress - // can slip through before it; the finishing step ends it from a callback - // queued behind the refresh's own updates (see waitAndFinalize). Demos - // take the blocking inline path below and need none of this. - blockInputUntilDone := blockInput && !self.c.InDemo() - if blockInputUntilDone { - self.c.GocuiGui().BeginBlockingEvents() - } - // Capture the refresh's baseline once, here at the start: the repo // generation that every scope's bounce is guarded against, and the git // command instance the scopes run their commands through. The two are @@ -236,6 +225,18 @@ func (self *RefreshHelper) performRefresh(options types.RefreshOptions, calledFr }) { return } + + // A RefreshBlockingInput caller wants keyboard input withheld until the + // refreshed state is in place (see IGuiCommon.RefreshBlockingInput). Begin + // the block synchronously here in the calling handler, so that no keypress + // can slip through before it; the finishing step ends it from a callback + // queued behind the refresh's own updates (see waitAndFinalize). Demos + // take the blocking inline path below and need none of this. + blockInputUntilDone := blockInput && !self.c.InDemo() + if blockInputUntilDone { + self.c.GocuiGui().BeginBlockingEvents() + } + if options.BatchUIUpdates { env.batch = &refreshBounceBatch{} }