diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-29 12:55:16 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-29 12:55:16 +0200 |
| commit | 700f4be432e2c0f54fd6708b6a085b1fb9dd6108 (patch) | |
| tree | cc58fc6caaf5c779c0b61094f6369a0eae2141d0 /desktop/modules/sound/Osd.qml | |
| parent | 401cacb17fa2a5c756340be90d9a0b2c9c2e4a63 (diff) | |
| download | quickshell-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.qml | 50 |
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 } |
