aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/sound/Osd.qml
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-29 12:55:16 +0200
committerDanilo M. <danix@danix.xyz>2026-09-29 12:55:16 +0200
commit700f4be432e2c0f54fd6708b6a085b1fb9dd6108 (patch)
treecc58fc6caaf5c779c0b61094f6369a0eae2141d0 /desktop/modules/sound/Osd.qml
parent401cacb17fa2a5c756340be90d9a0b2c9c2e4a63 (diff)
downloadquickshell-700f4be432e2c0f54fd6708b6a085b1fb9dd6108.tar.gz
quickshell-700f4be432e2c0f54fd6708b6a085b1fb9dd6108.zip
feat(sound): album art as the OSD background
When the current track has art, the volume OSD now draws it across the whole panel, blurred (MultiEffect blur 0.5, default blurMax) and masked to the panel's rounded corners, since clip only cuts to the bounding box. The thumbnail in the track row stays sharp on top. A dark scrim (Theme.base at 0.82) sits over the art. The palette is dark and the text light, so a light cover made the panel unreadable, and more blur did not fix that; only darkening did. The scrim is a sibling of the MultiEffect, not a child: nested inside it, it did not paint at all, which is why raising its alpha first appeared to change nothing. Without art the panel keeps its translucent, compositor-frosted look. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules/sound/Osd.qml')
-rw-r--r--desktop/modules/sound/Osd.qml50
1 files changed, 50 insertions, 0 deletions
diff --git a/desktop/modules/sound/Osd.qml b/desktop/modules/sound/Osd.qml
index 4a5e4a2..2894d35 100644
--- a/desktop/modules/sound/Osd.qml
+++ b/desktop/modules/sound/Osd.qml
@@ -13,6 +13,7 @@ import Quickshell
import Quickshell.Wayland
import Quickshell.Services.Pipewire
import QtQuick
+import QtQuick.Effects
import "../.."
// The transient on-screen display. Unchanged in behaviour from volume-osd,
@@ -82,6 +83,55 @@ Scope {
border.width: 1
border.color: Qt.alpha(Theme.text, 0.12)
+ // Album art as the whole background, lightly blurred, when the
+ // player has any. It is opaque, so it hides the compositor's
+ // frosting; without art the panel keeps the translucent look.
+ // Inset by the border width so the border stays visible.
+ Image {
+ id: bgArt
+ anchors.fill: parent
+ anchors.margins: 1
+ source: Player.active ? Player.artUrl : ""
+ cache: false
+ asynchronous: true
+ fillMode: Image.PreserveAspectCrop
+ visible: false
+ }
+
+ // clip only cuts to the bounding box, so the corners come from a
+ // mask the size of the art with the panel's radius.
+ Rectangle {
+ id: bgMask
+ anchors.fill: bgArt
+ radius: parent.radius - 1
+ layer.enabled: true
+ visible: false
+ }
+
+ MultiEffect {
+ id: bgEffect
+ anchors.fill: bgArt
+ visible: bgArt.status === Image.Ready && bgArt.source != ""
+ source: bgArt
+ autoPaddingEnabled: false
+ blurEnabled: true
+ blur: 0.5
+ maskEnabled: true
+ maskSource: bgMask
+ maskThresholdMin: 0.5
+ maskSpreadAtMin: 1.0
+ }
+
+ // Keeps text and the accent bar legible on a bright cover. A
+ // sibling, not a child: nested inside the MultiEffect it did not
+ // paint, and a light cover showed through at full brightness.
+ Rectangle {
+ anchors.fill: bgArt
+ visible: bgEffect.visible
+ radius: bgMask.radius
+ color: Qt.alpha(Theme.base, 0.82)
+ }
+
HoverHandler {
onHoveredChanged: root.hovered = hovered
}