From 5bc855415a47b8d6d25d8c4820483c8caed2e525 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Wed, 14 Oct 2026 14:15:25 +0200 Subject: [PATCH] Add a test for clicks that wait in the event queue If the main loop is busy, clicks wait in the event queue and are then handled right after each other. gocui decides whether two clicks form a double click by the time it handles them, so two clicks read more than 500ms apart count as a double click. Co-Authored-By: Claude Opus 5.5 (1M context) --- pkg/gocui/double_click_test.go | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pkg/gocui/double_click_test.go b/pkg/gocui/double_click_test.go index f6a14f620..ec8cb26d3 100644 --- a/pkg/gocui/double_click_test.go +++ b/pkg/gocui/double_click_test.go @@ -2,6 +2,7 @@ package gocui import ( "testing" + "time" "github.com/gdamore/tcell/v3" "github.com/stretchr/testify/assert" @@ -66,3 +67,42 @@ func TestASwallowedClickIsNoHalfOfADoubleClick(t *testing.T) { assert.Equal(t, []bool{false}, doubleClicks) } + +func TestDoubleClicksAreTimedByWhenTheClicksWereRead(t *testing.T) { + t.Cleanup(resetMouseState) + resetMouseState() + g := newTestGui(t) + view, _ := g.SetView("list", 0, 0, 20, 10, 0) + doubleClicks := []bool{} + g.SetViewClickBinding(&ViewMouseBinding{ + ViewName: "list", + Key: MouseLeft, + Handler: func(opts ViewMouseBindingOpts) error { + doubleClicks = append(doubleClicks, opts.IsDoubleClick) + return nil + }, + }) + + click := func(readAt time.Time) { + for _, buttons := range []tcell.ButtonMask{tcell.ButtonPrimary, tcell.ButtonNone} { + tev := tcell.NewEventMouse(view.x0+1, view.y0+1, buttons, tcell.ModNone) + tev.SetEventTime(readAt) + event := gocuiEventFromTcellEvent(tev) + assert.NoError(t, g.onKey(&event)) + } + } + + // The clicks are handled right after each other, long after they were read, + // as they are when they wait in the queue while the main loop is busy. + readAt := time.Now().Add(-time.Minute) + click(readAt) + click(readAt.Add(DOUBLE_CLICK_THRESHOLD + time.Millisecond)) + click(readAt.Add(DOUBLE_CLICK_THRESHOLD + 100*time.Millisecond)) + + assert.Equal(t, + /* EXPECTED: + []bool{false, false, true}, + ACTUAL: */ + []bool{false, true, true}, + doubleClicks) +}