audio: audio device changed toasts (#684)

* Added toast notifications for audio device changes

* rename to toasts

* moved into audio service

* fixes

---------

Co-authored-by: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>
This commit is contained in:
Robin Seger 2025-09-23 10:04:21 +02:00 committed by GitHub
parent 7aaa14438f
commit bef5359702
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 45 additions and 1 deletions

View file

@ -567,7 +567,11 @@ default, you must create it manually.
}, },
"utilities": { "utilities": {
"enabled": true, "enabled": true,
"maxToasts": 4 "maxToasts": 4,
"toasts": {
"audioOutputChanged": true,
"audioInputChanged": true
}
} }
} }
``` ```

View file

@ -5,8 +5,14 @@ JsonObject {
property int maxToasts: 4 property int maxToasts: 4
property Sizes sizes: Sizes {} property Sizes sizes: Sizes {}
property Toasts toasts: Toasts {}
component Sizes: JsonObject { component Sizes: JsonObject {
property int width: 430 property int width: 430
} }
component Toasts: JsonObject {
property bool audioOutputChanged: true
property bool audioInputChanged: true
}
} }

View file

@ -2,12 +2,17 @@ pragma Singleton
import qs.config import qs.config
import Caelestia.Services import Caelestia.Services
import Caelestia
import Quickshell import Quickshell
import Quickshell.Services.Pipewire import Quickshell.Services.Pipewire
import QtQuick
Singleton { Singleton {
id: root id: root
property string previousSinkName: ""
property string previousSourceName: ""
readonly property var nodes: Pipewire.nodes.values.reduce((acc, node) => { readonly property var nodes: Pipewire.nodes.values.reduce((acc, node) => {
if (!node.isStream) { if (!node.isStream) {
if (node.isSink) if (node.isSink)
@ -74,6 +79,35 @@ Singleton {
Pipewire.preferredDefaultAudioSource = newSource; Pipewire.preferredDefaultAudioSource = newSource;
} }
onSinkChanged: {
if (!sink?.ready)
return;
const newSinkName = sink.description || sink.name || qsTr("Unknown Device");
if (previousSinkName && previousSinkName !== newSinkName && Config.utilities.toasts.audioOutputChanged)
Toaster.toast(qsTr("Audio output changed"), qsTr("Now using: %1").arg(newSinkName), "volume_up");
previousSinkName = newSinkName;
}
onSourceChanged: {
if (!source?.ready)
return;
const newSourceName = source.description || source.name || qsTr("Unknown Device");
if (previousSourceName && previousSourceName !== newSourceName && Config.utilities.toasts.audioInputChanged)
Toaster.toast(qsTr("Audio input changed"), qsTr("Now using: %1").arg(newSourceName), "mic");
previousSourceName = newSourceName;
}
Component.onCompleted: {
previousSinkName = sink?.description || sink?.name || qsTr("Unknown Device");
previousSourceName = source?.description || source?.name || qsTr("Unknown Device");
}
PwObjectTracker { PwObjectTracker {
objects: [...root.sinks, ...root.sources] objects: [...root.sinks, ...root.sources]
} }