volume-osd: add example
This commit is contained in:
parent
0cf5fff6ea
commit
955bd1f8c1
3 changed files with 99 additions and 0 deletions
7
volume-osd/README.md
Normal file
7
volume-osd/README.md
Normal 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`.
|
||||||
|
|
||||||
|

|
BIN
volume-osd/image.png
Normal file
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
92
volume-osd/shell.qml
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue