Files
quickshell-config/osd/VolumeDisplay.qml

109 lines
3.5 KiB
QML

import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.Pipewire
import Quickshell.Widgets
import qs
import qs.common
import qs.common.widgets
Scope {
id: root
// communicate when the volume display should show or not
property bool showVolumeDisplay: false
// Bind to pipewire's default output node
// https://quickshell.org/docs/v0.2.0/types/Quickshell.Services.Pipewire/PwObjectTracker/
PwObjectTracker {
objects: [Pipewire.defaultAudioSink]
}
// Setup a connection to when the volume is changed
// https://doc.qt.io/qt-6/qml-qtqml-connections.html
Connections {
target: Pipewire.defaultAudioSink?.audio
function onVolumeChanged() {
GlobalStates.osdVolumeOpen = true;
hideTimer.restart();
}
}
// timer after 1 second hide the volume display
// https://doc.qt.io/qt-6/qml-qtqml-timer.html
Timer {
id: hideTimer
interval: Config.options.osd.timeout
onTriggered: GlobalStates.osdVolumeOpen = false
}
// loader to create and destroy volume display
LazyLoader {
active: GlobalStates.osdVolumeOpen
// according to documentation in Quickshell, PanelWindow is not an uncreatable-type, despite the qmlls language server's warning
// I assume that the yelling is because there is a discrepancy between implementation and language server
PanelWindow {
// it seems you can use {} if you want multiple under a category
// the example for that is in Bar.qml
anchors.bottom: true
// similar discrepancy it seems
margins.bottom: screen.height / 5
exclusiveZone: 0
implicitHeight: 50
implicitWidth: 400
color: "transparent"
// prevents clicking on volume display
mask: Region {}
Rectangle {
anchors.fill: parent
radius: height / 2
color: Appearance?.colors.colLayer1
// requires QtQuick.Layouts
RowLayout {
anchors {
fill: parent
leftMargin: 10
rightMargin: 15
}
MaterialSymbol {
iconSize: 30
visible: true
fill: 1
// comes from Quickshell.Widgets
text: "volume_up"
color: Appearance.m3colors.m3onSecondaryContainer
}
Rectangle {
Layout.fillWidth: true
implicitHeight: 20
radius: height / 2
color: Appearance?.m3colors.m3secondaryContainer
Rectangle {
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
}
color: Appearance.colors.colPrimary
// What I presume is that the first ? is to check if defaultAudioSink is there, and if not, the ?? marks the returning value in place
implicitWidth: parent.width * (Pipewire.defaultAudioSink?.audio.volume ?? 0)
radius: parent.radius
}
}
}
}
}
}
}