mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
AudioService: properly filter outputs with no inputs
AudioCard & OSD: use said detection
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user