2025-12-21 20:59:33 +01:00
|
|
|
import QtQuick
|
|
|
|
|
import Quickshell.Services.Pipewire
|
|
|
|
|
import Quickshell.Widgets
|
2025-12-21 21:24:03 +01:00
|
|
|
import Quickshell.Io
|
2025-12-24 15:41:03 +01:00
|
|
|
import qs
|
2025-12-21 20:59:33 +01:00
|
|
|
|
|
|
|
|
Item {
|
|
|
|
|
id: root
|
|
|
|
|
implicitWidth: volRow.implicitWidth + 10
|
|
|
|
|
implicitHeight: volRow.implicitHeight
|
|
|
|
|
// grab the default speaker (Sink)
|
|
|
|
|
property var sink: Pipewire.defaultAudioSink
|
2025-12-21 21:24:03 +01:00
|
|
|
Process {
|
|
|
|
|
id: pavu
|
|
|
|
|
command: ["pavucontrol"] // The command and args list
|
2025-12-21 20:59:33 +01:00
|
|
|
|
2025-12-21 21:24:03 +01:00
|
|
|
}
|
|
|
|
|
MouseArea {
|
|
|
|
|
cursorShape: Qt.OpenHandCursor
|
|
|
|
|
onClicked: mouse => {
|
|
|
|
|
if (mouse.button === Qt.LeftButton) {
|
|
|
|
|
// Left Click: Summon the Mixer!
|
|
|
|
|
console.log("Summoning Pavucontrol... Nya!");
|
|
|
|
|
pavu.startDetached();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
anchors.fill: parent
|
|
|
|
|
// Scroll to change volume (The fancy stuff!)
|
|
|
|
|
}
|
2025-12-21 20:59:33 +01:00
|
|
|
// Logic to pick the correct icon name
|
|
|
|
|
function getVolumeIcon() {
|
|
|
|
|
// Safety check: if Pipewire is dead or sink is missing
|
|
|
|
|
if (!sink)
|
|
|
|
|
return "audio-volume-muted-blocking";
|
|
|
|
|
|
|
|
|
|
// If muted, show the hush icon
|
|
|
|
|
if (sink.audio.muted)
|
|
|
|
|
return "audio-volume-muted";
|
|
|
|
|
|
|
|
|
|
// Volume is usually 0.0 to 1.0 (0% to 100%)
|
|
|
|
|
const vol = sink.audio.volume;
|
|
|
|
|
|
|
|
|
|
if (vol <= 0.0)
|
|
|
|
|
return "audio-volume-low";
|
|
|
|
|
if (vol < 0.33)
|
|
|
|
|
return "audio-volume-low";
|
|
|
|
|
if (vol < 0.66)
|
|
|
|
|
return "audio-volume-medium";
|
|
|
|
|
|
|
|
|
|
// If it's loud, prepare the ears!
|
|
|
|
|
return "audio-volume-high";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Row {
|
|
|
|
|
id: volRow
|
|
|
|
|
anchors.centerIn: parent
|
|
|
|
|
spacing: 5
|
|
|
|
|
|
|
|
|
|
IconImage {
|
2025-12-23 00:06:06 +01:00
|
|
|
anchors.verticalCenter: parent.verticalCenter
|
2025-12-24 23:00:08 +01:00
|
|
|
width: 12
|
|
|
|
|
height: 12
|
2025-12-21 20:59:33 +01:00
|
|
|
|
|
|
|
|
// The magic: 'image://theme/' pulls from your system icon theme (Papirus, Adwaita, etc.)
|
|
|
|
|
source: "root:/icons/" + root.getVolumeIcon() + "-symbolic.svg"
|
|
|
|
|
|
|
|
|
|
// Optional: Tint the icon if your theme needs it
|
|
|
|
|
// sourceSize: Qt.size(24, 24)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Text {
|
|
|
|
|
PwObjectTracker {
|
2025-12-24 23:00:08 +01:00
|
|
|
|
2025-12-21 20:59:33 +01:00
|
|
|
objects: Pipewire.defaultAudioSink
|
|
|
|
|
}
|
2025-12-22 13:55:00 +01:00
|
|
|
font.weight: 900
|
2025-12-21 20:59:33 +01:00
|
|
|
color: Colors.foreground
|
|
|
|
|
font.family: Appearance.font
|
|
|
|
|
font.pixelSize: Appearance.fontSize
|
|
|
|
|
text: Math.round(Pipewire.defaultAudioSink.audio.volume * 100) + "%"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Click to toggle mute! (Bonus feature)
|
|
|
|
|
}
|
|
|
|
|
}
|