AudioService: properly filter outputs with no inputs

AudioCard & OSD: use said detection
This commit is contained in:
Ly-sec
2025-11-11 16:25:52 +01:00
parent 508f8be6b8
commit 6ae3a19e1e
3 changed files with 79 additions and 12 deletions
+6
View File
@@ -511,6 +511,9 @@ Variants {
if (!inputAudioInitialized) {
return
}
if (!AudioService.hasInput) {
return
}
showOSD("inputVolume")
}
@@ -518,6 +521,9 @@ Variants {
if (!inputAudioInitialized) {
return
}
if (!AudioService.hasInput) {
return
}
showOSD("inputVolume")
}
}
@@ -9,12 +9,19 @@ import qs.Widgets
NBox {
id: root
property real localOutputVolume: AudioService.volume || 0
property real localOutputVolume: 0
property bool localOutputVolumeChanging: false
property real localInputVolume: AudioService.inputVolume || 0
property real localInputVolume: 0
property bool localInputVolumeChanging: false
Component.onCompleted: {
var vol = AudioService.volume
localOutputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0
var inputVol = AudioService.inputVolume
localInputVolume = (inputVol !== undefined && !isNaN(inputVol)) ? inputVol : 0
}
// Timer to debounce volume changes
Timer {
interval: 100
@@ -31,11 +38,32 @@ NBox {
}
// Connections to update local volumes when AudioService changes
Connections {
target: AudioService
function onVolumeChanged() {
if (!localOutputVolumeChanging) {
var vol = AudioService.volume
localOutputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0
}
}
}
Connections {
target: AudioService.sink?.audio ? AudioService.sink?.audio : null
function onVolumeChanged() {
if (!localOutputVolumeChanging) {
localOutputVolume = AudioService.volume
var vol = AudioService.volume
localOutputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0
}
}
}
Connections {
target: AudioService
function onInputVolumeChanged() {
if (!localInputVolumeChanging) {
var vol = AudioService.inputVolume
localInputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0
}
}
}
@@ -44,7 +72,8 @@ NBox {
target: AudioService.source?.audio ? AudioService.source?.audio : null
function onVolumeChanged() {
if (!localInputVolumeChanging) {
localInputVolume = AudioService.inputVolume
var vol = AudioService.inputVolume
localInputVolume = (vol !== undefined && !isNaN(vol)) ? vol : 0
}
}
}
+40 -8
View File
@@ -24,7 +24,11 @@ Singleton {
})
readonly property PwNode sink: Pipewire.defaultAudioSink
readonly property PwNode source: Pipewire.defaultAudioSource
readonly property PwNode rawSource: Pipewire.defaultAudioSource
readonly property PwNode source: (rawSource && !rawSource.isSink && (!rawSource.mediaClass || rawSource.mediaClass.startsWith("Audio/Source"))) ? rawSource : null
readonly property bool hasInput: !!source
Component.onCompleted: updateInputVolume()
readonly property list<PwNode> sinks: nodes.sinks
readonly property list<PwNode> sources: nodes.sources
@@ -37,13 +41,33 @@ Singleton {
// Input volume [0..1] is readonly from outside
readonly property alias inputVolume: root._inputVolume
property real _inputVolume: source?.audio?.volume ?? 0
property real _inputVolume: 0
readonly property alias inputMuted: root._inputMuted
property bool _inputMuted: !!source?.audio?.muted
readonly property real stepVolume: Settings.data.audio.volumeStep / 100.0
function updateInputVolume() {
if (source && source.audio) {
var vol = source.audio.volume
if (vol !== undefined && !isNaN(vol)) {
root._inputVolume = vol
} else {
root._inputVolume = 0
}
root._inputMuted = !!source.audio.muted
} else {
root._inputVolume = 0
root._inputMuted = true
}
}
// Update input volume when source property changes
onSourceChanged: {
updateInputVolume()
}
PwObjectTracker {
objects: [...root.sinks, ...root.sources]
}
@@ -76,8 +100,9 @@ Singleton {
target: source?.audio ? source?.audio : null
function onVolumeChanged() {
var vol = (source?.audio.volume ?? 0)
if (isNaN(vol)) {
var vol = source?.audio?.volume
if (vol === undefined || isNaN(vol)) {
root._inputVolume = 0
return
}
// Only update if the value actually changed to prevent spurious signals
@@ -91,10 +116,18 @@ Singleton {
// Only update if the value actually changed
if (root._inputMuted !== newMuted) {
root._inputMuted = newMuted
Logger.i("AudioService", "OnInputMuteChanged:", root._inputMuted)
}
}
}
Connections {
target: Pipewire
function onDefaultAudioSinkChanged() {}
function onDefaultAudioSourceChanged() {
updateInputVolume()
}
}
function increaseVolume() {
setVolume(volume + stepVolume)
@@ -158,9 +191,8 @@ Singleton {
function setAudioSource(newSource: PwNode): void {
Pipewire.preferredDefaultAudioSource = newSource
// Volume is changed by the source change
root._inputVolume = newSource?.audio?.volume ?? 0
root._inputMuted = !!newSource?.audio?.muted
// The source property will update automatically, which triggers onSourceChanged
// which calls updateInputVolume()
}
function getOutputIcon() {