diff --git a/DONE.md b/DONE.md index f3ea67b..6d6044c 100644 --- a/DONE.md +++ b/DONE.md @@ -771,6 +771,7 @@ This file tracks completed features, fixes, and milestones. - ✅ Prevented snippet runaway bitrates when using Match Source Format - ✅ History sidebar refreshes when jobs complete (snippet entries now appear) - ✅ Benchmark errors now show non-blocking notifications instead of OK popups +- ✅ Fixed stats bar updates to run on the UI thread to avoid Fyne warnings - ✅ Stabilized video seeking and embedded rendering - ✅ Improved player window positioning - ✅ Fixed clear video functionality diff --git a/TODO.md b/TODO.md index 2171fe0..783bb86 100644 --- a/TODO.md +++ b/TODO.md @@ -45,6 +45,7 @@ This file tracks upcoming features, improvements, and known issues. - Target size unit selector and numeric entry - Snippet history updates in sidebar - Non-blocking benchmark error notifications + - Stats bar updates run on the UI thread ## Priority Features for dev20+ diff --git a/internal/ui/components.go b/internal/ui/components.go index ff634b2..a551c7a 100644 --- a/internal/ui/components.go +++ b/internal/ui/components.go @@ -468,29 +468,44 @@ func NewConversionStatsBar(onTapped func()) *ConversionStatsBar { // UpdateStats updates the stats display func (c *ConversionStatsBar) UpdateStats(running, pending, completed, failed, cancelled int, progress float64, jobTitle string) { - c.running = running - c.pending = pending - c.completed = completed - c.failed = failed - c.cancelled = cancelled - c.progress = progress - c.jobTitle = jobTitle - c.Refresh() + c.updateStats(func() { + c.running = running + c.pending = pending + c.completed = completed + c.failed = failed + c.cancelled = cancelled + c.progress = progress + c.jobTitle = jobTitle + }) } // UpdateStatsWithDetails updates the stats display with detailed conversion info func (c *ConversionStatsBar) UpdateStatsWithDetails(running, pending, completed, failed, cancelled int, progress, fps, speed float64, eta, jobTitle string) { - c.running = running - c.pending = pending - c.completed = completed - c.failed = failed - c.cancelled = cancelled - c.progress = progress - c.fps = fps - c.speed = speed - c.eta = eta - c.jobTitle = jobTitle - c.Refresh() + c.updateStats(func() { + c.running = running + c.pending = pending + c.completed = completed + c.failed = failed + c.cancelled = cancelled + c.progress = progress + c.fps = fps + c.speed = speed + c.eta = eta + c.jobTitle = jobTitle + }) +} + +func (c *ConversionStatsBar) updateStats(update func()) { + app := fyne.CurrentApp() + if app == nil || app.Driver() == nil { + update() + c.Refresh() + return + } + app.Driver().DoFromGoroutine(func() { + update() + c.Refresh() + }, false) } // CreateRenderer creates the renderer for the stats bar