From 765e21305a4b6c8517559de6b047da63ac8b1008 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Thu, 10 Apr 2025 08:23:43 -0700 Subject: [PATCH] fix goroutine handling for pop-up queue --- main.go | 5 +-- ui/bottompanel.go | 12 ++----- ui/browsing/nowplayingpage.go | 2 +- ui/controller/controller.go | 59 ++++++++++++++--------------------- ui/controller/playlist.go | 13 ++++---- ui/mainwindow.go | 4 +-- ui/util/util.go | 6 ++++ 7 files changed, 44 insertions(+), 57 deletions(-) diff --git a/main.go b/main.go index 7d2b1cc..4cfa1c3 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( "github.com/dweymouth/supersonic/backend" "github.com/dweymouth/supersonic/res" "github.com/dweymouth/supersonic/ui" + "github.com/dweymouth/supersonic/ui/util" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" @@ -79,8 +80,8 @@ func main() { mainWindow := ui.NewMainWindow(fyneApp, res.AppName, res.DisplayName, res.AppVersion, myApp) mainWindow.Window.SetMaster() - myApp.OnReactivate = mainWindow.Show - myApp.OnExit = func() { fyne.Do(mainWindow.Quit) } + myApp.OnReactivate = util.FyneDoFunc(mainWindow.Show) + myApp.OnExit = util.FyneDoFunc(mainWindow.Quit) windowStartupTasks := sync.OnceFunc(func() { defaultServer := myApp.ServerManager.GetDefaultServer() diff --git a/ui/bottompanel.go b/ui/bottompanel.go index cdccac4..60e0ae4 100644 --- a/ui/bottompanel.go +++ b/ui/bottompanel.go @@ -41,15 +41,9 @@ func NewBottomPanel(pm *backend.PlaybackManager, im *backend.ImageManager, contr }) }) - pm.OnPaused(func() { - fyne.Do(func() { bp.Controls.SetPlaying(false) }) - }) - pm.OnPlaying(func() { - fyne.Do(func() { bp.Controls.SetPlaying(true) }) - }) - pm.OnStopped(func() { - fyne.Do(func() { bp.Controls.SetPlaying(false) }) - }) + pm.OnPaused(util.FyneDoFunc(func() { bp.Controls.SetPlaying(false) })) + pm.OnPlaying(util.FyneDoFunc(func() { bp.Controls.SetPlaying(true) })) + pm.OnStopped(util.FyneDoFunc(func() { bp.Controls.SetPlaying(false) })) bp.NowPlaying = widgets.NewNowPlayingCard() bp.NowPlaying.OnCoverTapped = func() { diff --git a/ui/browsing/nowplayingpage.go b/ui/browsing/nowplayingpage.go index bbb0a7f..d74b1e6 100644 --- a/ui/browsing/nowplayingpage.go +++ b/ui/browsing/nowplayingpage.go @@ -102,7 +102,7 @@ func NewNowPlayingPage( a := &NowPlayingPage{nowPlayingPageState: state} a.ExtendBaseWidget(a) - doFmtStatus := func() { fyne.Do(a.formatStatusLine) } + doFmtStatus := util.FyneDoFunc(a.formatStatusLine) pm.OnPaused(doFmtStatus) pm.OnPlaying(doFmtStatus) pm.OnStopped(doFmtStatus) diff --git a/ui/controller/controller.go b/ui/controller/controller.go index 91bd54a..d3eb802 100644 --- a/ui/controller/controller.go +++ b/ui/controller/controller.go @@ -10,7 +10,6 @@ import ( "net/url" "os" "path/filepath" - "sync" "time" fynetooltip "github.com/dweymouth/fyne-tooltip" @@ -56,7 +55,6 @@ type Controller struct { UnselectAllPageFunc func() ToastProvider ToastProvider - popUpQueueMutex sync.Mutex popUpQueue *widget.PopUp popUpQueueList *widgets.PlayQueueList popUpQueueLastUsed int64 @@ -72,49 +70,41 @@ func New(app *backend.App, appVersion string, mainWindow fyne.Window) *Controlle App: app, } c.initVisualizations() - c.App.PlaybackManager.OnQueueChange(func() { - c.popUpQueueMutex.Lock() - defer c.popUpQueueMutex.Unlock() + c.App.PlaybackManager.OnQueueChange(util.FyneDoFunc(func() { if c.popUpQueue != nil { c.popUpQueueList.SetItems(c.App.PlaybackManager.GetPlayQueue()) } - }) + })) c.App.PlaybackManager.OnSongChange(func(track mediaprovider.MediaItem, _ *mediaprovider.Track) { - c.popUpQueueMutex.Lock() - defer c.popUpQueueMutex.Unlock() - if c.popUpQueue == nil { - return - } - if track == nil { - c.popUpQueueList.SetNowPlaying("") - } else { - c.popUpQueueList.SetNowPlaying(track.Metadata().ID) - } + fyne.Do(func() { + if c.popUpQueue == nil { + return + } + if track == nil { + c.popUpQueueList.SetNowPlaying("") + } else { + c.popUpQueueList.SetNowPlaying(track.Metadata().ID) + } + }) }) return c } func (m *Controller) SelectAll() { - m.popUpQueueMutex.Lock() if m.popUpQueue != nil && m.popUpQueue.Visible() { m.popUpQueueList.SelectAll() - m.popUpQueueMutex.Unlock() return } - m.popUpQueueMutex.Unlock() if m.SelectAllPageFunc != nil { m.SelectAllPageFunc() } } func (m *Controller) UnselectAll() { - m.popUpQueueMutex.Lock() if m.popUpQueue != nil && m.popUpQueue.Visible() { m.popUpQueueList.UnselectAll() - m.popUpQueueMutex.Unlock() return } - m.popUpQueueMutex.Unlock() if m.SelectAllPageFunc != nil { m.UnselectAllPageFunc() } @@ -196,7 +186,6 @@ func (m *Controller) ShowCastMenu(onPendingPlayerChange func()) { } func (m *Controller) ShowPopUpPlayQueue() { - m.popUpQueueMutex.Lock() if m.popUpQueue == nil { m.popUpQueueList = widgets.NewPlayQueueList(m.App.ImageManager, false) m.popUpQueueList.Reorderable = true @@ -229,25 +218,23 @@ func (m *Controller) ShowPopUpPlayQueue() { go func() { t := time.NewTicker(1 * time.Minute) for range t.C { - m.popUpQueueMutex.Lock() - now := time.Now().UnixMilli() - if m.popUpQueueLastUsed < now-120_000 /*2 min*/ { - fynetooltip.DestroyPopUpToolTipLayer(m.popUpQueue) - m.popUpQueue = nil - m.popUpQueueList = nil - m.popUpQueueLastUsed = 0 - m.popUpQueueMutex.Unlock() - t.Stop() - return - } - m.popUpQueueMutex.Unlock() + fyne.Do(func() { + now := time.Now().UnixMilli() + if m.popUpQueueLastUsed < now-120_000 /*2 min*/ { + fynetooltip.DestroyPopUpToolTipLayer(m.popUpQueue) + m.popUpQueue = nil + m.popUpQueueList = nil + m.popUpQueueLastUsed = 0 + t.Stop() + return + } + }) } }() } m.popUpQueueLastUsed = time.Now().UnixMilli() popUpQueueList := m.popUpQueueList pop := m.popUpQueue - m.popUpQueueMutex.Unlock() npID := "" if np := m.App.PlaybackManager.NowPlaying(); np != nil { diff --git a/ui/controller/playlist.go b/ui/controller/playlist.go index 1d666f2..eec2698 100644 --- a/ui/controller/playlist.go +++ b/ui/controller/playlist.go @@ -12,6 +12,7 @@ import ( "github.com/dweymouth/supersonic/backend/mediaprovider" "github.com/dweymouth/supersonic/sharedutil" "github.com/dweymouth/supersonic/ui/dialogs" + "github.com/dweymouth/supersonic/ui/util" ) // Show dialog to select playlist. @@ -33,13 +34,11 @@ func (m *Controller) DoAddTracksToPlaylistWorkflow(trackIDs []string) { m.ToastProvider.ShowSuccessToast(msg) }) } - notifyError := func() { - fyne.Do(func() { - m.ToastProvider.ShowErrorToast( - lang.L("An error occurred adding tracks to the playlist"), - ) - }) - } + notifyError := util.FyneDoFunc(func() { + m.ToastProvider.ShowErrorToast( + lang.L("An error occurred adding tracks to the playlist"), + ) + }) pop.Hide() m.App.Config.Application.AddToPlaylistSkipDuplicates = sp.SkipDuplicates if id == "" /* creating new playlist */ { diff --git a/ui/mainwindow.go b/ui/mainwindow.go index 2b999a9..293dad4 100644 --- a/ui/mainwindow.go +++ b/ui/mainwindow.go @@ -300,8 +300,8 @@ func (m *MainWindow) SetupSystemTrayMenu(appName string, fyneApp fyne.App) { m.App.PlaybackManager.SetVolume(vol) }), fyne.NewMenuItemSeparator(), - fyne.NewMenuItem(lang.L("Show"), func() { fyne.Do(m.Window.Show) }), - fyne.NewMenuItem(lang.L("Hide"), func() { fyne.Do(m.Window.Hide) }), + fyne.NewMenuItem(lang.L("Show"), m.Window.Show), + fyne.NewMenuItem(lang.L("Hide"), m.Window.Hide), ) desk.SetSystemTrayMenu(menu) desk.SetSystemTrayIcon(res.ResAppicon256Png) diff --git a/ui/util/util.go b/ui/util/util.go index 1757cdd..e557c0a 100644 --- a/ui/util/util.go +++ b/ui/util/util.go @@ -33,6 +33,12 @@ const ( DateFormatYMD ) +func FyneDoFunc(f func()) func() { + return func() { + fyne.Do(f) + } +} + func dateFormatForLocale(locale string) DateFormat { var region string if i := strings.Index(locale, "-"); i > 0 && len(locale) >= 5 {