Add volume indicator

This commit is contained in:
Sem
2026-05-31 20:37:30 +02:00
parent 5be218807c
commit 8dd32e2632
6 changed files with 175 additions and 46 deletions

View File

@@ -0,0 +1,52 @@
import QtQuick
import Quickshell.Io
// service to get the current volume and handle volume changes
Item {
id: root
signal volumeChanged(int volume)
// process to get the volume level: first active playback stream, falling back to the sink
Process {
id: audioVolumeProcess
command: ["sh", "-c", "pactl list sink-inputs | grep -m1 'Volume:' | grep -oP '\\d+(?=%)' | head -1 || wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{printf \"%d\", $2 * 100}'"]
stdout: StdioCollector {
onStreamFinished: {
if (this.text) {
const volume = parseInt(this.text.trim());
root.volumeChanged(volume);
}
}
}
}
Process {
id: volumeUpProcess
command: ["sh", "-c", "pactl list sink-inputs | awk '/^Sink Input #/{sub(/^Sink Input #/,x);id=$1;got=0} /^[[:space:]]+Volume:/ && id && !got{match($0,/[0-9]+%/);if(substr($0,RSTART,RLENGTH-1)+0<100)print id;got=1}' | xargs -r -I{} pactl set-sink-input-volume {} +1%"]
}
Process {
id: volumeDownProcess
command: ["sh", "-c", "pactl list short sink-inputs | awk '{print $1}' | xargs -r -I{} pactl set-sink-input-volume {} -1%"]
}
function volumeUp() {
volumeUpProcess.running = true;
audioVolumeProcess.running = true;
}
function volumeDown() {
volumeDownProcess.running = true;
audioVolumeProcess.running = true;
}
// timer to periodically check the volume level
Timer {
interval: 5000
running: true
repeat: true
onTriggered: audioVolumeProcess.running = true
}
Component.onCompleted: audioVolumeProcess.running = true
}

View File

@@ -0,0 +1,53 @@
import Quickshell
import Quickshell.Io
import QtQuick
import QtQuick.Layouts
import "../constants"
import "../services"
Text {
id: root
required property TopBar parentWindow
property string lowVolumeIconGlyph: "\uf027"
property string highVolumeIconGlyph: "\uf028"
property string iconGlyph: lowVolumeIconGlyph
property string volumeText: ""
property list<string> volumeDudes: ["⸝(°-°)⸜","ヽ(°∘°)ノ","ヽ(°o°)ノ","ヽ(°O°)ノ","ヽ(°ᗜ°)ノ","ヽ(°〇°)ノ","ᕙ( ᗒᗣᗕ )ᕗ"]
property int volumeDudeIndex: 0
property int dudeStep: 100 / volumeDudes.length
property AudioService audioService: AudioService {
onVolumeChanged: function (volume) {
var dudeIndex = Math.min(Math.floor(volume / root.dudeStep), root.volumeDudes.length - 1);
root.text = volume + "% " + root.volumeDudes[dudeIndex];
}
}
text: iconGlyph
color: Colors.md3.on_primary_fixed
font {
family: Constants.fontFamily
pixelSize: Constants.fontSize
bold: false
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
// TODO open volume control panel
}
onWheel: function (wheel) {
if (wheel.angleDelta.y > 0) {
root.audioService.volumeUp();
} else {
root.audioService.volumeDown();
}
}
}
}

View File

@@ -67,6 +67,12 @@ Item {
parentWindow: root
}
LineSeparator {}
AudioIcon {
parentWindow: root
}
LineSeparator {}
BarText {