From ff78a79906095f232f456bda2caf2f3a371d2248 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Sun, 12 Jan 2025 14:57:59 -0800 Subject: [PATCH] more fyne.Do updates --- main.go | 8 ++--- ui/browsing/albumpage.go | 15 +++++---- ui/browsing/browsingpane.go | 2 +- ui/browsing/playlistpage.go | 12 ++++--- ui/mainwindow.go | 6 ++-- ui/widgets/tracklist.go | 60 +++-------------------------------- ui/widgets/tracklistloader.go | 7 ++-- 7 files changed, 34 insertions(+), 76 deletions(-) diff --git a/main.go b/main.go index edf295a..d5c2137 100644 --- a/main.go +++ b/main.go @@ -75,17 +75,17 @@ func main() { fyneApp.SetIcon(res.ResAppicon256Png) mainWindow := ui.NewMainWindow(fyneApp, res.AppName, res.DisplayName, res.AppVersion, myApp) + mainWindow.Window.SetMaster() myApp.OnReactivate = mainWindow.Show myApp.OnExit = mainWindow.Quit - go func() { + fyneApp.Lifecycle().SetOnEnteredForeground(sync.OnceFunc(func() { defaultServer := myApp.ServerManager.GetDefaultServer() if defaultServer == nil { - fyne.Do(mainWindow.Controller.PromptForFirstServer) + mainWindow.Controller.PromptForFirstServer() } else { - fyne.Do(func() { mainWindow.Controller.DoConnectToServerWorkflow(defaultServer) }) + mainWindow.Controller.DoConnectToServerWorkflow(defaultServer) } - }() startupOnceTasks := sync.OnceFunc(func() { mainWindow.Window.(driver.NativeWindow).RunNative(func(ctx any) { diff --git a/ui/browsing/albumpage.go b/ui/browsing/albumpage.go index 182ca98..453128d 100644 --- a/ui/browsing/albumpage.go +++ b/ui/browsing/albumpage.go @@ -168,11 +168,13 @@ func (a *AlbumPage) load() { if a.disposed { return } - a.header.Update(album, a.im) - a.tracklist.Options.ShowDiscNumber = len(album.Tracks) > 0 && album.Tracks[0].DiscNumber != album.Tracks[len(album.Tracks)-1].DiscNumber - a.tracks = album.Tracks - a.tracklist.SetTracks(album.Tracks) - a.tracklist.SetNowPlaying(a.nowPlayingID) + fyne.Do(func() { + a.header.Update(album, a.im) + a.tracklist.Options.ShowDiscNumber = len(album.Tracks) > 0 && album.Tracks[0].DiscNumber != album.Tracks[len(album.Tracks)-1].DiscNumber + a.tracks = album.Tracks + a.tracklist.SetTracks(album.Tracks) + a.tracklist.SetNowPlaying(a.nowPlayingID) + }) } type AlbumPageHeader struct { @@ -344,6 +346,7 @@ func (a *AlbumPageHeader) toggleFavorited() { a.page.mp.SetFavorite(params, a.toggleFavButton.IsFavorited) } +// should be called asynchronously func (a *AlbumPageHeader) showPopUpCover() { if a.fullSizeCoverFetching { return @@ -356,7 +359,7 @@ func (a *AlbumPageHeader) showPopUpCover() { return } if a.page != nil { - a.page.contr.ShowPopUpImage(cover) + fyne.Do(func() { a.page.contr.ShowPopUpImage(cover) }) } } diff --git a/ui/browsing/browsingpane.go b/ui/browsing/browsingpane.go index 4c4557a..e92b753 100644 --- a/ui/browsing/browsingpane.go +++ b/ui/browsing/browsingpane.go @@ -259,7 +259,7 @@ func (b *BrowsingPane) onSongChange(song mediaprovider.MediaItem, lastScrobbledI return } if p, ok := b.curPage.(CanShowNowPlaying); ok { - p.OnSongChange(song, lastScrobbledIfAny) + fyne.Do(func() { p.OnSongChange(song, lastScrobbledIfAny) }) } } diff --git a/ui/browsing/playlistpage.go b/ui/browsing/playlistpage.go index 5a7c378..f930070 100644 --- a/ui/browsing/playlistpage.go +++ b/ui/browsing/playlistpage.go @@ -166,10 +166,12 @@ func (a *PlaylistPage) load() { return } renumberTracks(playlist.Tracks) - a.tracks = playlist.Tracks - a.tracklist.SetTracks(playlist.Tracks) - a.tracklist.SetNowPlaying(a.nowPlayingID) - a.header.Update(playlist) + fyne.Do(func() { + a.tracks = playlist.Tracks + a.tracklist.SetTracks(playlist.Tracks) + a.tracklist.SetNowPlaying(a.nowPlayingID) + a.header.Update(playlist) + }) } func renumberTracks(tracks []*mediaprovider.Track) { @@ -205,8 +207,8 @@ func (a *PlaylistPage) doSetNewTrackOrder(ids []string, newPos int) { ) }) } else { + renumberTracks(newTracks) fyne.Do(func() { - renumberTracks(newTracks) // force-switch back to unsorted view to show new track order a.tracklist.SetSorting(widgets.TracklistSort{}) a.tracklist.SetTracks(newTracks) diff --git a/ui/mainwindow.go b/ui/mainwindow.go index 1c18707..d90e5e9 100644 --- a/ui/mainwindow.go +++ b/ui/mainwindow.go @@ -152,7 +152,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string, if app.Config.Application.CloseToSystemTray && m.HaveSystemTray() { m.Window.Hide() } else { - fyneApp.Quit() + m.Window.Close() } }) @@ -314,8 +314,8 @@ func (m *MainWindow) SetupSystemTrayMenu(appName string, fyneApp fyne.App) { m.App.PlaybackManager.SetVolume(vol) }), fyne.NewMenuItemSeparator(), - fyne.NewMenuItem(lang.L("Show"), m.Window.Show), - fyne.NewMenuItem(lang.L("Hide"), m.Window.Hide), + fyne.NewMenuItem(lang.L("Show"), func() { fyne.Do(m.Window.Show) }), + fyne.NewMenuItem(lang.L("Hide"), func() { fyne.Do(m.Window.Hide) }), ) desk.SetSystemTrayMenu(menu) desk.SetSystemTrayIcon(res.ResAppicon256Png) diff --git a/ui/widgets/tracklist.go b/ui/widgets/tracklist.go index 9cc4145..1962a80 100644 --- a/ui/widgets/tracklist.go +++ b/ui/widgets/tracklist.go @@ -5,7 +5,6 @@ import ( "slices" "sort" "strings" - "sync" "fyne.io/fyne/v2/lang" @@ -91,7 +90,6 @@ type Tracklist struct { visibleColumns []bool sorting TracklistSort - tracksMutex sync.RWMutex tracks []*util.TrackListModel tracksOrigOrder []*util.TrackListModel @@ -148,7 +146,7 @@ func NewTracklist(tracks []*mediaprovider.Track, im *backend.ImageManager, useCo } t.list = NewFocusList( - t.lenTracks, + func() int { return len(t.tracks) }, func() fyne.CanvasObject { var tr TracklistRow if t.compactRows { @@ -169,16 +167,13 @@ func NewTracklist(tracks []*mediaprovider.Track, im *backend.ImageManager, useCo return tr }, func(itemID widget.ListItemID, item fyne.CanvasObject) { - t.tracksMutex.RLock() // we could have removed tracks from the list in between // Fyne calling the length callback and this update callback // so the itemID may be out of bounds. if so, do nothing. if itemID >= len(t.tracks) { - t.tracksMutex.RUnlock() return } model := t.tracks[itemID] - t.tracksMutex.RUnlock() tr := item.(TracklistRow) if tr.TrackID() != model.Item.Metadata().ID || tr.ItemID() != itemID { @@ -219,10 +214,8 @@ func (t *Tracklist) Scroll(amount float32) { t.list.ScrollToOffset(t.list.GetScrollOffset() + amount) } -// Gets the track at the given index. Thread-safe. +// Gets the track at the given index. func (t *Tracklist) TrackAt(idx int) *mediaprovider.Track { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() if idx >= len(t.tracks) { log.Println("error: Tracklist.TrackAt: index out of range") return nil @@ -291,10 +284,8 @@ func (t *Tracklist) SetSorting(sorting TracklistSort) { // Sets the currently playing track ID and updates the list rendering func (t *Tracklist) SetNowPlaying(trackID string) { prevNowPlaying := t.nowPlayingID - t.tracksMutex.RLock() trPrev, idxPrev := util.FindItemByID(t.tracks, prevNowPlaying) tr, idx := util.FindItemByID(t.tracks, trackID) - t.tracksMutex.RUnlock() t.nowPlayingID = trackID if trPrev != nil { t.list.RefreshItem(idxPrev) @@ -306,58 +297,46 @@ func (t *Tracklist) SetNowPlaying(trackID string) { // Increments the play count of the given track and updates the list rendering func (t *Tracklist) IncrementPlayCount(trackID string) { - t.tracksMutex.RLock() tr, idx := util.FindItemByID(t.tracks, trackID) - t.tracksMutex.RUnlock() if tr != nil { tr.(*mediaprovider.Track).PlayCount += 1 t.list.RefreshItem(idx) } } -// Remove all tracks from the tracklist. Does not issue Refresh call. Thread-safe. +// Remove all tracks from the tracklist. Does not issue Refresh call. func (t *Tracklist) Clear() { - t.tracksMutex.Lock() - defer t.tracksMutex.Unlock() t.tracks = nil t.tracksOrigOrder = nil } -// Sets the tracks in the tracklist. Thread-safe. +// Sets the tracks in the tracklist. func (t *Tracklist) SetTracks(trs []*mediaprovider.Track) { t._setTracks(trs) t.Refresh() } func (t *Tracklist) _setTracks(trs []*mediaprovider.Track) { - t.tracksMutex.Lock() - defer t.tracksMutex.Unlock() t.tracksOrigOrder = util.ToTrackListModels(trs) t.doSortTracks() } // Returns the tracks in the tracklist in the current display order. func (t *Tracklist) GetTracks() []*mediaprovider.Track { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() return sharedutil.MapSlice(t.tracks, func(tm *util.TrackListModel) *mediaprovider.Track { return tm.Track() }) } -// Append more tracks to the tracklist. Thread-safe. +// Append more tracks to the tracklist. func (t *Tracklist) AppendTracks(trs []*mediaprovider.Track) { - t.tracksMutex.Lock() t.tracksOrigOrder = append(t.tracks, util.ToTrackListModels(trs)...) t.doSortTracks() - t.tracksMutex.Unlock() t.list.Refresh() } func (t *Tracklist) SelectAll() { - t.tracksMutex.RLock() util.SelectAllItems(t.tracks) - t.tracksMutex.RUnlock() t.list.Refresh() } @@ -367,13 +346,10 @@ func (t *Tracklist) UnselectAll() { } func (t *Tracklist) unselectAll() { - t.tracksMutex.RLock() util.UnselectAllItems(t.tracks) - t.tracksMutex.RUnlock() } func (t *Tracklist) SelectAndScrollToTrack(trackID string) { - t.tracksMutex.RLock() idx := -1 for i, tr := range t.tracks { if tr.Item.Metadata().ID == trackID { @@ -383,7 +359,6 @@ func (t *Tracklist) SelectAndScrollToTrack(trackID string) { tr.Selected = false } } - t.tracksMutex.RUnlock() if idx >= 0 { t.list.ScrollTo(idx) } @@ -474,9 +449,7 @@ func (t *Tracklist) doSortTracks() { func (t *Tracklist) onSorted(sort ListHeaderSort) { t.sorting = TracklistSort{ColumnName: t.colName(sort.ColNumber), SortOrder: sort.Type} - t.tracksMutex.Lock() t.doSortTracks() - t.tracksMutex.Unlock() t.Refresh() } @@ -503,20 +476,14 @@ func (t *Tracklist) onSelectTrack(idx int) { } func (t *Tracklist) selectAddOrRemove(idx int) { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() t.tracks[idx].Selected = !t.tracks[idx].Selected } func (t *Tracklist) selectTrack(idx int) { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() util.SelectItem(t.tracks, idx) } func (t *Tracklist) selectRange(idx int) { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() util.SelectItemRange(t.tracks, idx) } @@ -606,9 +573,7 @@ func (t *Tracklist) onShowContextMenu(e *fyne.PointEvent, trackIdx int) { } func (t *Tracklist) onSetFavorite(trackID string, fav bool) { - t.tracksMutex.RLock() item, _ := util.FindItemByID(t.tracks, trackID) - t.tracksMutex.RUnlock() t.onSetFavorites([]*mediaprovider.Track{item.(*mediaprovider.Track)}, fav, false) } @@ -627,9 +592,7 @@ func (t *Tracklist) onSetFavorites(tracks []*mediaprovider.Track, fav bool, need func (t *Tracklist) onSetRating(trackID string, rating int) { // update our own track model - t.tracksMutex.RLock() item, _ := util.FindItemByID(t.tracks, trackID) - t.tracksMutex.RUnlock() t.onSetRatings([]*mediaprovider.Track{item.(*mediaprovider.Track)}, rating, false) } @@ -681,14 +644,10 @@ func (t *Tracklist) onPlaySongRadio(tracks []*mediaprovider.Track) { } func (t *Tracklist) selectedTracks() []*mediaprovider.Track { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() return util.SelectedTracks(t.tracks) } func (t *Tracklist) SelectedTrackIDs() []string { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() return util.SelectedItemIDs(t.tracks) } @@ -696,9 +655,6 @@ func (t *Tracklist) SelectedTrackIDs() []string { // original sort order (ie if tracklist is sorted by some column), the indexes // returned will correspond to the order of tracks when the list was initialized. func (t *Tracklist) SelectedTrackIndexes() []int { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() - idx := -1 return sharedutil.FilterMapSlice(t.tracksOrigOrder, func(t *util.TrackListModel) (int, bool) { idx++ @@ -706,12 +662,6 @@ func (t *Tracklist) SelectedTrackIndexes() []int { }) } -func (t *Tracklist) lenTracks() int { - t.tracksMutex.RLock() - defer t.tracksMutex.RUnlock() - return len(t.tracks) -} - func (t *Tracklist) ColNumber(colName string) int { i := slices.IndexFunc(t.columns, func(c TracklistColumn) bool { return c.Name == colName diff --git a/ui/widgets/tracklistloader.go b/ui/widgets/tracklistloader.go index 6cd035c..fddf16d 100644 --- a/ui/widgets/tracklistloader.go +++ b/ui/widgets/tracklistloader.go @@ -3,6 +3,7 @@ package widgets import ( "sync/atomic" + "fyne.io/fyne/v2" "github.com/dweymouth/supersonic/backend/mediaprovider" ) @@ -69,8 +70,10 @@ func (t *TracklistLoader) loadMoreTracks(num int) { if t.disposed.Load() { return } - t.tracklist.AppendTracks(t.trackBuffer) - t.len += len(t.trackBuffer) + fyne.Do(func() { + t.tracklist.AppendTracks(t.trackBuffer) + t.len += len(t.trackBuffer) + }) } if t.done { t.trackBuffer = nil