Demonstrate stale focus refresh overwriting a click

When clicking in the commits view of lazygit running in an unfocused VS
Code window, VS Code first sends us the focus-in event and then the
mouse-click. The focus-in refresh captures the selection when it starts,
then we handle the mouse click and you briefly see the clicked row
getting selected, but then the selection flashes back to the original
row as the refresh restores it when done.
This commit is contained in:
Stefan Haller 2026-07-24 08:45:45 +02:00
parent a5b4477a20
commit 5aa003612c
7 changed files with 70 additions and 0 deletions

View file

@ -77,6 +77,25 @@ func (self *GuiDriver) FocusIn() {
self.waitTillIdle()
}
func (self *GuiDriver) FocusInAndClick(x, y int) {
self.CheckAllToastsAcknowledged()
self.gui.g.ReplayFocusEvent(gocui.NewTcellFocusEventWrapper(
tcell.NewEventFocus(true),
0,
))
self.gui.g.ReplayMouseEvent(gocui.NewTcellMouseEventWrapper(
tcell.NewEventMouse(x, y, tcell.ButtonPrimary, 0),
0,
))
self.waitTillIdle()
self.gui.g.ReplayMouseEvent(gocui.NewTcellMouseEventWrapper(
tcell.NewEventMouse(x, y, tcell.ButtonNone, 0),
0,
))
self.waitTillIdle()
}
func (self *GuiDriver) PretendMergeOrRebaseStartedInLazygit() {
self.gui.onUIThread(func() error {
self.gui.State.SetMergeOrRebaseStartedInLazygit(true)

View file

@ -73,6 +73,12 @@ func (self *TestDriver) FocusIn() {
self.Wait(self.inputDelay)
}
func (self *TestDriver) focusInAndClick(x, y int) {
self.SetCaption(fmt.Sprintf("Focusing window and clicking %d, %d", x, y))
self.gui.FocusInAndClick(x, y)
self.Wait(self.inputDelay)
}
func (self *TestDriver) typeContent(content string) {
for _, char := range content {
self.pressFast(string(char))

View file

@ -41,6 +41,10 @@ func (self *fakeGuiDriver) Click(x, y int) {
func (self *fakeGuiDriver) FocusIn() {
}
func (self *fakeGuiDriver) FocusInAndClick(x, y int) {
self.clickedCoordinates = append(self.clickedCoordinates, coordinate{x: x, y: y})
}
func (self *fakeGuiDriver) Keys() config.KeybindingConfig {
return config.KeybindingConfig{}
}

View file

@ -475,6 +475,14 @@ func (self *ViewDriver) Click(x, y int) *ViewDriver {
return self
}
func (self *ViewDriver) FocusInAndClick(x, y int) *ViewDriver {
offsetX, offsetY, _, _ := self.getView().Dimensions()
self.t.focusInAndClick(offsetX+1+x, offsetY+1+y)
return self
}
// i.e. pressing down arrow
func (self *ViewDriver) SelectNextItem() *ViewDriver {
return self.PressFast(self.t.keys.Universal.NextItem)

View file

@ -0,0 +1,29 @@
package commit
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var KeepClickedCommitSelectedAfterFocusIn = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Keep a clicked commit selected when focus-in immediately precedes the click",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.CreateNCommits(2)
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().
Focus().
Lines(
Contains("commit-02").IsSelected(),
Contains("commit-01"),
).
FocusInAndClick(1, 1).
/* EXPECTED:
SelectedLine(Contains("commit-01"))
ACTUAL: */
SelectedLine(Contains("commit-02"))
},
})

View file

@ -140,6 +140,7 @@ var tests = []*components.IntegrationTest{
commit.Highlight,
commit.History,
commit.HistoryComplex,
commit.KeepClickedCommitSelectedAfterFocusIn,
commit.KeepSelectedCommitAfterExternalCommit,
commit.NewBranch,
commit.PasteCommitMessage,

View file

@ -31,6 +31,9 @@ type GuiDriver interface {
// Simulate the terminal window regaining focus (which triggers a reload of
// changed config files)
FocusIn()
// Simulate a terminal dispatching focus-in immediately followed by a click,
// without waiting for the focus refresh to finish in between.
FocusInAndClick(int, int)
Keys() config.KeybindingConfig
CurrentContext() types.Context
ContextForView(viewName string) types.Context