summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/gui/navigation.go13
1 files changed, 12 insertions, 1 deletions
diff --git a/internal/gui/navigation.go b/internal/gui/navigation.go
index c7e9264..f142f38 100644
--- a/internal/gui/navigation.go
+++ b/internal/gui/navigation.go
@@ -497,7 +497,11 @@ func (a *Application) startFileCheckTicker() {
ticker := time.NewTicker(2 * time.Second)
a.fileCheckTicker = ticker
+ // Track this goroutine in wg so the shutdown handler waits for it to exit.
+ // The ctx.Done() case ensures it exits promptly when the application closes.
+ a.wg.Add(1)
go func() {
+ defer a.wg.Done()
for {
select {
case <-ticker.C:
@@ -800,17 +804,24 @@ func (a *Application) deleteCurrentWord() {
// Start a cleanup goroutine to guard against directory recreation by racing
// in-flight operations. Instead of a fixed sleep, poll hasActiveOperations
// so the cleanup runs as soon as all operations for this word complete.
+ // Tracked in wg and respects ctx.Done() so the app can shut down cleanly.
+ a.wg.Add(1)
go func() {
+ defer a.wg.Done()
ticker := time.NewTicker(50 * time.Millisecond)
defer ticker.Stop()
timeout := time.NewTimer(5 * time.Second)
defer timeout.Stop()
- // Wait until all active operations for this word finish or timeout elapses.
+ // Wait until all active operations for this word finish, timeout elapses,
+ // or the application is shutting down.
for {
select {
case <-timeout.C:
// Proceed even if some operations are still pending.
+ case <-a.ctx.Done():
+ // Application is shutting down — skip the cleanup.
+ return
case <-ticker.C:
if a.hasActiveOperations(deletedWord) {
continue