refactor(src/window/controlcenter): centralize fallback artwork path and streamline UI updates

Replaced get_relative_path with PLAYER_FALLBACK_ART and simplified image handling via apply_player_art.
This commit is contained in:
sankalp committed 2026-06-17 03:33:45 +05:45
1 parent bd78ed9aab
commit 7a5d90829a
2 files changed
+55 -113

No files matched your search

+20 -70
View File
@@ -1,10 +1,7 @@
import weakref
from fabric.utils import (
GLib,
bulk_connect,
get_relative_path,
os,
)
from fabric.widgets.box import Box
from fabric.widgets.button import Button
@@ -15,20 +12,13 @@ from fabric.widgets.scale import Scale
from fabric.widgets.stack import Stack
from fabric.widgets.wayland import WaylandWindow as Window
import shared.data as data
from services.mpris import PlayerManager, PlayerService
from utils.utils import svg_file
CACHE_DIR = f"{data.CACHE_DIR}/media"
_shared_mpris_manager = None
_artwork_cache = {}
def get_shared_mpris_manager():
global _shared_mpris_manager
if _shared_mpris_manager is None:
_shared_mpris_manager = PlayerManager()
return _shared_mpris_manager
from window.controlcenter.player import (
apply_player_art,
get_shared_mpris_manager,
PLAYER_FALLBACK_ART,
)
class EmbeddedExpandedPlayer(Box):
@@ -97,8 +87,8 @@ class PlayerBoxStack(Box):
super().destroy()
def _create_no_media_box(self):
fallback_cover_path = get_relative_path("../../assets/icons/music.svg")
album_cover = Box(name="macos-album-image-no")
fallback_cover_path = PLAYER_FALLBACK_ART
album_cover = Box(style_classes="album-image-c")
album_cover.set_style(f"background-image:url('{fallback_cover_path}')")
track_title = Label(
@@ -284,7 +274,7 @@ class PlayerBox(Box):
super().__init__(h_align="center", name="player-box", h_expand=True, **kwargs)
self.player = player
self.player_stack = player_stack
self.fallback_cover_path = get_relative_path("../../assets/icons/music.svg")
self.fallback_cover_path = PLAYER_FALLBACK_ART
self.cover_path = self.fallback_cover_path
self.exit = False
self._user_seeking = False
@@ -292,7 +282,7 @@ class PlayerBox(Box):
self._property_bindings = []
self._seekbar_signal_ids = []
self.album_cover = Box(name="macos-album-image")
self.album_cover = Box(style_classes="album-image-c")
self.album_cover.set_style(
f"background-image:url('{self.fallback_cover_path}')"
)
@@ -505,11 +495,9 @@ class PlayerBox(Box):
self.seek_bar.connect("realize", self._on_seek_bar_realized)
initial_art = self.player.get_artwork()
if initial_art:
self.album_cover.set_style(f"background-image:url('{initial_art}')")
else:
self.set_image()
result = apply_player_art(self.album_cover, self.player)
if result:
self.cover_path = result
def update_buttons(self, player_buttons, show_buttons):
self.stack_buttons_box.children = []
@@ -612,56 +600,18 @@ class PlayerBox(Box):
self.player_stack.on_player_playback_changed(self, status)
def _on_artwork_change(self, service, local_path, *_):
if not self.exit and local_path:
GLib.idle_add(
lambda: (
self.album_cover.set_style(f"background-image:url('{local_path}')")
if os.path.isfile(local_path)
else None
)
)
if self.exit:
return
result = apply_player_art(self.album_cover, self.player, service, local_path)
if result:
self.cover_path = result
def set_image(self, service=None, path=None, *_):
if self.exit or self.player is None:
return
if path:
self.cover_path = path
self.album_cover.set_style(f"background-image:url('{self.cover_path}')")
return
url = self.player.arturl
if url:
new_cover_path = (
(
CACHE_DIR
+ "/"
+ GLib.compute_checksum_for_string(GLib.ChecksumType.SHA1, url, -1)
)
if "file://" != url[0:7]
else url[7:]
)
if new_cover_path != self.cover_path:
self.cover_path = new_cover_path
if os.path.exists(self.cover_path):
self.album_cover.set_style(
f"background-image:url('{self.cover_path}')"
)
return
from fabric.utils import Gio
Gio.File.new_for_uri(uri=url).copy_async(
Gio.File.new_for_path(self.cover_path),
Gio.FileCopyFlags.OVERWRITE,
GLib.PRIORITY_DEFAULT,
None,
None,
lambda src, res, *_: (
self.album_cover.set_style(
f"background-image:url('{self.cover_path}')"
)
if not self.exit and os.path.isfile(self.cover_path)
else None
),
)
result = apply_player_art(self.album_cover, self.player, service, path)
if result:
self.cover_path = result
def _on_track_position(self, service, pos: float, dur: float):
if self.exit or self._user_seeking:
+35 -43
View File
@@ -1,4 +1,4 @@
from fabric.utils import Gio, GLib, bulk_connect, get_relative_path, logger, os
from fabric.utils import bulk_connect, get_relative_path, logger, os
from fabric.widgets.box import Box
from fabric.widgets.button import Button
from fabric.widgets.centerbox import CenterBox
@@ -12,7 +12,7 @@ from services.mpris import PlayerManager, PlayerService
from utils.utils import svg_file
CACHE_DIR = f"{data.CACHE_DIR}/media"
MEDIA_CACHE = CACHE_DIR
PLAYER_FALLBACK_ART = get_relative_path("../../assets/icons/music.svg")
if not os.path.exists(CACHE_DIR):
os.makedirs(CACHE_DIR)
@@ -36,6 +36,31 @@ def cleanup_shared_mpris_manager():
_shared_mpris_manager = None
def apply_player_art(album_cover_widget, player, service=None, path=None):
"""
Single source of truth for applying album art to any player widget.
Call patterns:
- On init / metadata change: apply_player_art(widget, player)
- From artwork-change signal: apply_player_art(widget, player, service_obj, local_path)
Returns the applied path, or None if no art is available yet (backend will
emit artwork-change when the async download completes).
"""
# artwork-change signal emits (service_obj, local_path_str)
if path and isinstance(path, str) and os.path.exists(path):
album_cover_widget.set_style(f"background-image:url('{path}')")
return path
# Check if backend already has it cached from a previous download
if player:
cached = player.get_artwork()
if cached and os.path.exists(cached):
album_cover_widget.set_style(f"background-image:url('{cached}')")
return cached
# Nothing yet — backend will emit artwork-change when download finishes
return None
class PlayerBoxStack(Box):
def __init__(
self, mpris_manager: PlayerManager = None, control_center=None, **kwargs
@@ -275,7 +300,7 @@ class PlayerBox(Box):
self.player = player
self.player_stack = player_stack
self.control_center = control_center
self.cover_path = get_relative_path("../../assets/icons/music.svg")
self.cover_path = PLAYER_FALLBACK_ART
self.exit = False
self._signal_connections = []
@@ -394,15 +419,15 @@ class PlayerBox(Box):
"play": self._on_playback_change,
"pause": self._on_playback_change,
"meta-change": self._on_metadata,
"artwork-change": self.set_image,
},
)
for handler_id in connections:
self._signal_connections.append((self.player, handler_id))
initial_art = self.player.get_artwork()
if initial_art:
self.cover_path = initial_art
self.album_cover.set_style(f"background-image:url('{self.cover_path}')")
result = apply_player_art(self.album_cover, self.player)
if result:
self.cover_path = result
def _on_outer_box_clicked(self, *_):
if self.control_center and hasattr(self.control_center, "open_expanded_player"):
@@ -442,42 +467,9 @@ class PlayerBox(Box):
def set_image(self, service=None, path=None, *_):
if self.exit or self.player is None:
return
if path:
self.cover_path = path
self.album_cover.set_style(f"background-image:url('{self.cover_path}')")
return
url = self.player.arturl
if url:
new_cover_path = (
(
MEDIA_CACHE
+ "/"
+ GLib.compute_checksum_for_string(GLib.ChecksumType.SHA1, url, -1)
)
if "file://" != url[0:7]
else url[7:]
)
if new_cover_path != self.cover_path:
self.cover_path = new_cover_path
if os.path.exists(self.cover_path):
self.album_cover.set_style(
f"background-image:url('{self.cover_path}')"
)
return
Gio.File.new_for_uri(uri=url).copy_async(
Gio.File.new_for_path(self.cover_path),
Gio.FileCopyFlags.OVERWRITE,
GLib.PRIORITY_DEFAULT,
None,
None,
lambda src, res, *_: (
self.album_cover.set_style(
f"background-image:url('{self.cover_path}')"
)
if not self.exit and os.path.isfile(self.cover_path)
else None
),
)
result = apply_player_art(self.album_cover, self.player, service, path)
if result:
self.cover_path = result
def suspend(self):
self.exit = True