1
0
Fork 0

volume-osd: add example

This commit is contained in:
outfoxxed 2025-05-14 02:38:31 -07:00
parent 0cf5fff6ea
commit 955bd1f8c1
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
3 changed files with 99 additions and 0 deletions

7
volume-osd/README.md Normal file
View file

@ -0,0 +1,7 @@
# Volume OSD
This is a simple overlay that shows the system volume when it changes using pipewire.
You can run the overlay with `qs -p shell.qml`.
![](./image.png)

BIN
volume-osd/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

92
volume-osd/shell.qml Normal file
View file

@ -0,0 +1,92 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.Pipewire
import Quickshell.Widgets
Scope {
id: root
// Bind the pipewire node so its volume will be tracked
PwObjectTracker {
objects: [ Pipewire.defaultAudioSink ]
}
Connections {
target: Pipewire.defaultAudioSink?.audio
function onVolumeChanged() {
root.shouldShowOsd = true;
hideTimer.restart();
}
}
property bool shouldShowOsd: false
Timer {
id: hideTimer
interval: 1000
onTriggered: root.shouldShowOsd = false
}
// The OSD window will be created and destroyed based on shouldShowOsd.
// PanelWindow.visible could be set instead of using a loader, but using
// a loader will reduce the memory overhead when the window isn't open.
LazyLoader {
active: root.shouldShowOsd
PanelWindow {
// Since the panel's screen is unset, it will be picked by the compositor
// when the window is created. Most compositors pick the current active monitor.
anchors.bottom: true
margins.bottom: screen.height / 5
implicitWidth: 400
implicitHeight: 50
color: "transparent"
// An empty click mask prevents the window from blocking mouse events.
mask: Region {}
Rectangle {
anchors.fill: parent
radius: height / 2
color: "#80000000"
RowLayout {
anchors {
fill: parent
leftMargin: 10
rightMargin: 15
}
IconImage {
implicitSize: 30
source: Quickshell.iconPath("audio-volume-high-symbolic")
}
Rectangle {
// Stretches to fill all left-over space
Layout.fillWidth: true
implicitHeight: 10
radius: 20
color: "#50ffffff"
Rectangle {
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
}
implicitWidth: parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0)
radius: parent.radius
}
}
}
}
}
}
}