Warning, /plasma/latte-dock/plasmoid/package/contents/ui/PulseAudio.qml is written in an unsupported language. File is not indexed.

0001 /*
0002     SPDX-FileCopyrightText: 2017 Kai Uwe Broulik <kde@privat.broulik.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 import QtQuick 2.2
0008 
0009 import org.kde.plasma.private.volume 0.1
0010 
0011 QtObject {
0012     id: pulseAudio
0013 
0014     signal streamsChanged
0015 
0016     // It's a JS object so we can do key lookup and don't need to take care of filtering duplicates.
0017     property var pidMatches: ({})
0018 
0019     property int maxVolumePercent: 125
0020     property int maxVolumeValue: Math.round(maxVolumePercent * PulseAudio.NormalVolume / 100.0)
0021     property int volumeStep: Math.round(5 * PulseAudio.NormalVolume / 100.0)
0022 
0023     function boundVolume(volume) {
0024         return Math.max(PulseAudio.MinimalVolume, Math.min(volume, maxVolumeValue));
0025     }
0026 
0027     // TODO Evict cache at some point, preferably if all instances of an application closed.
0028     function registerPidMatch(appName) {
0029         if (!hasPidMatch(appName)) {
0030             pidMatches[appName] = true;
0031 
0032             // In case this match is new, notify that streams might have changed.
0033             // This way we also catch the case when the non-playing instance
0034             // shows up first.
0035             // Only notify if we changed to avoid infinite recursion.
0036             streamsChanged();
0037         }
0038     }
0039 
0040     function hasPidMatch(appName) {
0041         return pidMatches[appName] === true;
0042     }
0043 
0044     function findStreams(key, value) {
0045         var streams = []
0046         for (var i = 0, length = instantiator.count; i < length; ++i) {
0047             var stream = instantiator.objectAt(i);
0048             if (stream[key] === value || (key==="appName" && stream[key].toLowerCase() === value.toLowerCase())) {
0049                 streams.push(stream);
0050             }
0051         }
0052         return streams
0053     }
0054 
0055     function streamsForAppName(appName) {
0056         return findStreams("appName", appName);
0057     }
0058 
0059     function streamsForPid(pid) {
0060         var streams = findStreams("pid", pid);
0061 
0062         if (streams.length === 0) {
0063             for (var i = 0, length = instantiator.count; i < length; ++i) {
0064                 var stream = instantiator.objectAt(i);
0065 
0066                 if (stream.parentPid === -1) {
0067                     stream.parentPid = backend.parentPid(stream.pid);
0068                 }
0069 
0070                 if (stream.parentPid === pid) {
0071                     streams.push(stream);
0072                 }
0073             }
0074         }
0075 
0076         return streams;
0077     }
0078 
0079     // QtObject has no default property, hence adding the Instantiator to one explicitly.
0080     property var instantiator: Instantiator {
0081         model: PulseObjectFilterModel {
0082             filters: [ { role: "VirtualStream", value: false } ]
0083             sourceModel: SinkInputModel {}
0084         }
0085 
0086         delegate: QtObject {
0087             readonly property int pid: Client ? Client.properties["application.process.id"] : 0
0088             // Determined on demand.
0089             property int parentPid: -1
0090             readonly property string appName: Client ? Client.properties["application.name"] : ""
0091             readonly property bool muted: Muted
0092             // whether there is nothing actually going on on that stream
0093             readonly property bool corked: Corked
0094 
0095             readonly property int volume: Math.round(pulseVolume / PulseAudio.NormalVolume * 100.0)
0096             readonly property int pulseVolume: Volume
0097 
0098             function mute() {
0099                 Muted = true
0100             }
0101             function unmute() {
0102                 Muted = false
0103             }
0104 
0105             function increaseVolume() {
0106                 var bVolume = pulseAudio.boundVolume(Volume + pulseAudio.volumeStep);
0107                 Volume = bVolume;
0108             }
0109 
0110             function decreaseVolume() {
0111                 var bVolume = pulseAudio.boundVolume(Volume - pulseAudio.volumeStep);
0112                 Volume = bVolume;
0113             }
0114         }
0115 
0116         onObjectAdded: pulseAudio.streamsChanged()
0117         onObjectRemoved: pulseAudio.streamsChanged()
0118     }
0119 
0120     Component.onCompleted: {
0121         console.log("PulseAudio Latte interface was loaded...");
0122     }
0123 }