From 1447e1478f0d29108e0255d452a697e130ed9db1 Mon Sep 17 00:00:00 2001 From: Stu Leak Date: Sat, 13 Dec 2025 13:33:18 -0500 Subject: [PATCH] Fix Fyne threading errors in benchmark progress updates MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All UI updates from the benchmark goroutine were causing threading errors because they weren't wrapped in DoFromGoroutine. Fixed: - UpdateProgress: progress bar and label updates - AddResult: adding result cards to the display - SetComplete: final status updates These methods are called from background goroutines running the benchmark tests, so all UI updates must be dispatched to the main thread using fyne.CurrentApp().Driver().DoFromGoroutine(). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- internal/ui/benchmarkview.go | 38 +++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/internal/ui/benchmarkview.go b/internal/ui/benchmarkview.go index 1983025..06eb6ff 100644 --- a/internal/ui/benchmarkview.go +++ b/internal/ui/benchmarkview.go @@ -113,12 +113,14 @@ func (v *BenchmarkProgressView) GetContainer() *fyne.Container { // UpdateProgress updates the progress bar and labels func (v *BenchmarkProgressView) UpdateProgress(current, total int, encoder, preset string) { pct := float64(current) / float64(total) - v.progressBar.SetValue(pct) - v.statusLabel.SetText(fmt.Sprintf("Testing encoder %d of %d", current, total)) - v.currentLabel.SetText(fmt.Sprintf("Testing: %s (preset: %s)", encoder, preset)) - v.progressBar.Refresh() - v.statusLabel.Refresh() - v.currentLabel.Refresh() + fyne.CurrentApp().Driver().DoFromGoroutine(func() { + v.progressBar.SetValue(pct) + v.statusLabel.SetText(fmt.Sprintf("Testing encoder %d of %d", current, total)) + v.currentLabel.SetText(fmt.Sprintf("Testing: %s (preset: %s)", encoder, preset)) + v.progressBar.Refresh() + v.statusLabel.Refresh() + v.currentLabel.Refresh() + }, false) } // AddResult adds a completed test result to the display @@ -162,20 +164,24 @@ func (v *BenchmarkProgressView) AddResult(result benchmark.Result) { container.NewMax(card, content), ) - v.resultsBox.Add(item) - v.resultsBox.Refresh() + fyne.CurrentApp().Driver().DoFromGoroutine(func() { + v.resultsBox.Add(item) + v.resultsBox.Refresh() + }, false) } // SetComplete marks the benchmark as complete func (v *BenchmarkProgressView) SetComplete() { - v.statusLabel.SetText("Benchmark complete!") - v.progressBar.SetValue(1.0) - v.currentLabel.SetText("") - v.cancelBtn.SetText("Close") - v.statusLabel.Refresh() - v.progressBar.Refresh() - v.currentLabel.Refresh() - v.cancelBtn.Refresh() + fyne.CurrentApp().Driver().DoFromGoroutine(func() { + v.statusLabel.SetText("Benchmark complete!") + v.progressBar.SetValue(1.0) + v.currentLabel.SetText("") + v.cancelBtn.SetText("Close") + v.statusLabel.Refresh() + v.progressBar.Refresh() + v.currentLabel.Refresh() + v.cancelBtn.Refresh() + }, false) } // BuildBenchmarkResultsView creates the final results/recommendation UI