From 0ba248af4e5d067a46a0de4ee5272d5b3b8db280 Mon Sep 17 00:00:00 2001 From: Stu Date: Wed, 10 Dec 2025 05:31:48 -0500 Subject: [PATCH] Coalesce player view renders and schedule once --- main.go | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/main.go b/main.go index 29f43b7..ec98fb5 100644 --- a/main.go +++ b/main.go @@ -162,6 +162,21 @@ func (c convertConfig) CoverLabel() string { return filepath.Base(c.CoverArtPath) } +// requestPlayerView schedules a single player view render, coalescing rapid requests. +func (s *appState) requestPlayerView() { + s.playerViewPendingMu.Lock() + if s.playerViewPending { + s.playerViewPendingMu.Unlock() + return + } + s.playerViewPending = true + s.playerViewRefreshNeeded = true + s.playerViewPendingMu.Unlock() + fyne.Do(func() { + s.showPlayerView() + }) +} + type appState struct { window fyne.Window active string @@ -187,6 +202,8 @@ type appState struct { renderingPlayerView bool playerViewRefreshNeeded bool lastPlayerViewRender time.Time + playerViewPendingMu sync.Mutex + playerViewPending bool progressQuit chan struct{} convertCancel context.CancelFunc playerSurf *playerSurface @@ -421,8 +438,7 @@ func (s *appState) showErrorWithCopy(title string, err error) { func (s *appState) showMainMenu() { fmt.Printf("🎬 showMainMenu called - going to player view\n") // Minimal entry point: go straight to the player view. - s.playerViewRefreshNeeded = true - s.showPlayerView() + s.requestPlayerView() } func (s *appState) onClose() { @@ -583,6 +599,9 @@ func (s *appState) buildComparePane(src *videoSource, onStop func(), setSess fun // showPlayerView renders the player-focused UI with a lightweight playlist. func (s *appState) showPlayerView() { fmt.Printf("🎬 showPlayerView called\n") + s.playerViewPendingMu.Lock() + s.playerViewPending = false + s.playerViewPendingMu.Unlock() if s.renderingPlayerView { fmt.Printf("⏳ player view render already in progress, skipping\n") return @@ -596,7 +615,6 @@ func (s *appState) showPlayerView() { fmt.Printf("⏳ throttle: rendered recently for %s\n", currentPath) return } - s.renderingPlayerView = true defer func() { s.renderingPlayerView = false }() @@ -1429,7 +1447,7 @@ func (s *appState) batchAddToQueue(paths []string) { } } s.loadVideos(combined) - s.showPlayerView() + s.requestPlayerView() } }, false) } @@ -4045,8 +4063,10 @@ func (s *appState) handleDropPlayer(items []fyne.URI) { if len(videoPaths) > 1 { go s.loadVideos(videoPaths) + s.requestPlayerView() } else { go s.loadVideo(videoPaths[0]) + s.requestPlayerView() } } @@ -4222,13 +4242,8 @@ func (s *appState) loadVideo(path string) { logging.Debug(logging.CatModule, "video loaded %+v", src) fmt.Printf("🔄 Switching to player view...\n") fyne.CurrentApp().Driver().DoFromGoroutine(func() { - s.playerViewRefreshNeeded = true s.switchToVideo(s.currentIndex) - // Avoid immediate re-render storm; defer minimal trigger. - time.AfterFunc(10*time.Millisecond, func() { - s.playerViewRefreshNeeded = true - s.showPlayerView() - }) + s.requestPlayerView() }, false) } @@ -4249,7 +4264,7 @@ func (s *appState) clearVideo() { s.playerViewSource = "" s.playerViewRefreshNeeded = true fyne.CurrentApp().Driver().DoFromGoroutine(func() { - s.showPlayerView() + s.requestPlayerView() }, false) } @@ -4355,10 +4370,7 @@ func (s *appState) loadVideos(paths []string) { fyne.Do(func() { s.playerViewRefreshNeeded = true s.switchToVideo(0) - time.AfterFunc(10*time.Millisecond, func() { - s.playerViewRefreshNeeded = true - s.showPlayerView() - }) + s.requestPlayerView() }) }() }