mirror of
https://invent.kde.org/marcoa/shift-shell.git
synced 2026-04-29 15:03:09 +00:00
The eventual goal is to have as few singletons with state as possible in the mobileshell component when it is imported into components such as the lockscreen. This doesn't fully accomplish it, but moves the audio provider singleton to MobileShellState, which will eventually need to be prevented from importing into non plasmashell processes. This also disables the sound feedback when changing volume, since it can be a source of lag when showing the applet.
90 lines
3 KiB
QML
90 lines
3 KiB
QML
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
import QtQuick
|
|
|
|
import org.kde.plasma.private.volume
|
|
|
|
QtObject {
|
|
property SinkModel paSinkModel: SinkModel {}
|
|
|
|
// whether the audio icon should be visible in the status bar
|
|
readonly property bool isVisible: paSinkModel.preferredSink && paSinkModel.preferredSink.muted
|
|
|
|
// the icon that should be displayed in the status bar
|
|
readonly property string icon: paSinkModel.preferredSink && !isDummyOutput(paSinkModel.preferredSink)
|
|
? iconName(paSinkModel.preferredSink.volume, paSinkModel.preferredSink.muted)
|
|
: iconName(0, true)
|
|
|
|
// the name of the audio device when it isn't valid
|
|
readonly property string dummyOutputName: "auto_null"
|
|
|
|
// the maximum volume amount
|
|
readonly property int maxVolumeValue: Math.round(100 * PulseAudio.NormalVolume / 100.0)
|
|
|
|
// step that increments when adjusting the volume
|
|
readonly property int volumeStep: Math.round(5 * PulseAudio.NormalVolume / 100.0)
|
|
|
|
function isDummyOutput(output) {
|
|
return output && output.name === dummyOutputName;
|
|
}
|
|
|
|
function boundVolume(volume) {
|
|
return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue));
|
|
}
|
|
|
|
function volumePercent(volume, max){
|
|
if (!max) {
|
|
max = PulseAudio.NormalVolume;
|
|
}
|
|
return Math.round(volume / max * 100.0);
|
|
}
|
|
|
|
function increaseVolume() {
|
|
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
|
return;
|
|
}
|
|
|
|
var volume = boundVolume(paSinkModel.preferredSink.volume + volumeStep);
|
|
var percent = volumePercent(volume, maxVolumeValue);
|
|
paSinkModel.preferredSink.muted = percent == 0;
|
|
paSinkModel.preferredSink.volume = volume;
|
|
}
|
|
|
|
function decreaseVolume() {
|
|
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
|
return;
|
|
}
|
|
|
|
var volume = boundVolume(paSinkModel.preferredSink.volume - volumeStep);
|
|
var percent = volumePercent(volume, maxVolumeValue);
|
|
paSinkModel.preferredSink.muted = percent == 0;
|
|
paSinkModel.preferredSink.volume = volume;
|
|
}
|
|
|
|
function muteVolume() {
|
|
if (!paSinkModel.preferredSink || isDummyOutput(paSinkModel.preferredSink)) {
|
|
return;
|
|
}
|
|
|
|
paSinkModel.preferredSink.muted = !paSinkModel.preferredSink.muted;
|
|
}
|
|
|
|
function iconName(volume, muted, prefix) {
|
|
if (!prefix) {
|
|
prefix = "audio-volume";
|
|
}
|
|
var icon = null;
|
|
var percent = volume / maxVolumeValue;
|
|
if (percent <= 0.0 || muted) {
|
|
icon = prefix + "-muted";
|
|
} else if (percent <= 0.25) {
|
|
icon = prefix + "-low";
|
|
} else if (percent <= 0.75) {
|
|
icon = prefix + "-medium";
|
|
} else {
|
|
icon = prefix + "-high";
|
|
}
|
|
return icon;
|
|
}
|
|
}
|