104 lines
2.9 KiB
QML
104 lines
2.9 KiB
QML
import QtQuick
|
|
import QtQuick.Layouts
|
|
import Quickshell
|
|
import Quickshell.Services.Pipewire
|
|
import Quickshell.Widgets
|
|
import qs
|
|
import qs.common
|
|
|
|
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
|
|
}
|
|
|
|
IconImage {
|
|
implicitSize: 30
|
|
// comes from Quickshell.Widgets
|
|
source: Quickshell.iconPath("audio-volume-high-symbolic")
|
|
}
|
|
|
|
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |