diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-08 10:02:57 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-08 10:02:57 +0300 |
| commit | cfc7bb7bcf141b3d85ddcd597b4e71fc151ccc3f (patch) | |
| tree | a540ddb5d8261cb4f0214e6bc4e459d9316f1f5d /internal/gui | |
| parent | 08d7d36ac6d49d7d5efd39a837bc08c9c52b6eb8 (diff) | |
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
Diffstat (limited to 'internal/gui')
| -rw-r--r-- | internal/gui/app.go | 14 |
1 files changed, 13 insertions, 1 deletions
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)") } |
