From cfc7bb7bcf141b3d85ddcd597b4e71fc151ccc3f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 8 Apr 2026 10:02:57 +0300 Subject: fix(gui): avoid tooltip init race after window close Use time.NewTimer with defer Stop in the delayed tooltip goroutine so the timer is not left pending when ctx wins the select. After the delay, check ctx before and inside fyne.Do so SetToolTip never runs after shutdown cancels the application context. Made-with: Cursor --- internal/gui/app.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'internal/gui') diff --git a/internal/gui/app.go b/internal/gui/app.go index 0c821d4..edb62ba 100644 --- a/internal/gui/app.go +++ b/internal/gui/app.go @@ -422,15 +422,27 @@ func (a *Application) setupUI() { // Secondary toolbar button tooltips need a short delay to initialise. // Tracked via WaitGroup and respects ctx.Done() so the callback never // writes to freed widgets after the window is closed (Go Mistake #62). + // NewTimer (not time.After) avoids leaking a pending timer when ctx wins + // the select. After the delay, ctx is checked again before and inside + // fyne.Do: the timer can fire just before onWindowClosed cancels ctx, so + // the UI-thread callback must no-op if shutdown already started. a.wg.Add(1) go func() { defer a.wg.Done() + t := time.NewTimer(500 * time.Millisecond) + defer t.Stop() select { case <-a.ctx.Done(): return - case <-time.After(500 * time.Millisecond): + case <-t.C: + } + if a.ctx.Err() != nil { + return } fyne.Do(func() { + if a.ctx.Err() != nil { + return + } if exportButton != nil { exportButton.SetToolTip("Export to Anki (x)") } -- cgit v1.2.3