mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-08 08:19:26 -05:00
78 lines
2.6 KiB
QML
78 lines
2.6 KiB
QML
import qs.modules.common
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Services.Pipewire
|
|
pragma Singleton
|
|
pragma ComponentBehavior: Bound
|
|
|
|
/**
|
|
* A nice wrapper for default Pipewire audio sink and source.
|
|
*/
|
|
Singleton {
|
|
id: root
|
|
|
|
property bool ready: Pipewire.defaultAudioSink?.ready ?? false
|
|
property PwNode sink: Pipewire.defaultAudioSink
|
|
property PwNode source: Pipewire.defaultAudioSource
|
|
readonly property real hardMaxValue: 2.00 // People keep joking about setting volume to 5172% so...
|
|
property string audioTheme: Config.options.sounds.theme
|
|
|
|
signal sinkProtectionTriggered(string reason);
|
|
|
|
PwObjectTracker {
|
|
objects: [sink, source]
|
|
}
|
|
|
|
Connections { // Protection against sudden volume changes
|
|
target: sink?.audio ?? null
|
|
property bool lastReady: false
|
|
property real lastVolume: 0
|
|
function onVolumeChanged() {
|
|
if (!Config.options.audio.protection.enable) return;
|
|
if (!lastReady) {
|
|
lastVolume = sink.audio.volume;
|
|
lastReady = true;
|
|
return;
|
|
}
|
|
const newVolume = sink.audio.volume;
|
|
const maxAllowedIncrease = Config.options.audio.protection.maxAllowedIncrease / 100;
|
|
const maxAllowed = Config.options.audio.protection.maxAllowed / 100;
|
|
|
|
if (newVolume - lastVolume > maxAllowedIncrease) {
|
|
sink.audio.volume = lastVolume;
|
|
root.sinkProtectionTriggered(Translation.tr("Illegal increment"));
|
|
} else if (newVolume > maxAllowed || newVolume > root.hardMaxValue) {
|
|
root.sinkProtectionTriggered(Translation.tr("Exceeded max allowed"));
|
|
sink.audio.volume = Math.min(lastVolume, maxAllowed);
|
|
}
|
|
if (sink.ready && (isNaN(sink.audio.volume) || sink.audio.volume === undefined || sink.audio.volume === null)) {
|
|
sink.audio.volume = 0;
|
|
}
|
|
lastVolume = sink.audio.volume;
|
|
}
|
|
}
|
|
|
|
function playSystemSound(soundName) {
|
|
const ogaPath = `/usr/share/sounds/${root.audioTheme}/stereo/${soundName}.oga`;
|
|
const oggPath = `/usr/share/sounds/${root.audioTheme}/stereo/${soundName}.ogg`;
|
|
|
|
// Try playing .oga first
|
|
let command = [
|
|
"ffplay",
|
|
"-nodisp",
|
|
"-autoexit",
|
|
ogaPath
|
|
];
|
|
Quickshell.execDetached(command);
|
|
|
|
// Also try playing .ogg (ffplay will just fail silently if file doesn't exist)
|
|
command = [
|
|
"ffplay",
|
|
"-nodisp",
|
|
"-autoexit",
|
|
oggPath
|
|
];
|
|
Quickshell.execDetached(command);
|
|
}
|
|
}
|