113 lines
3.3 KiB
QML
113 lines
3.3 KiB
QML
// Read-only contract harness for the Sound page. It instantiates every device
|
|
// row against the real PipeWire graph but exposes no mutating IPC methods.
|
|
//
|
|
// The two services that read the machine rather than the graph -- SoundDefaults
|
|
// and SoundCards -- are fed through their own fixture seams by the contract, so
|
|
// the ghost row and the profile card can be measured against canned state
|
|
// instead of against whatever hardware is plugged in today.
|
|
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import Quickshell.Services.Pipewire
|
|
import QtQuick
|
|
import qs.services
|
|
import qs.modules.settings
|
|
|
|
ShellRoot {
|
|
id: root
|
|
|
|
QtObject {
|
|
id: fixtureAudio
|
|
property real volume: 0.42
|
|
property bool muted: false
|
|
}
|
|
|
|
QtObject {
|
|
id: fixtureNode
|
|
property QtObject audio: fixtureAudio
|
|
}
|
|
|
|
readonly property var fixtureApplication: ({
|
|
key: "fixture.player",
|
|
label: "Fixture Player",
|
|
icon: "audio-x-generic-symbolic",
|
|
nodes: [fixtureNode]
|
|
})
|
|
|
|
SoundPage {
|
|
width: 760
|
|
height: 900
|
|
}
|
|
|
|
// A device list of its own, so the ghost row can be read without reaching
|
|
// into the page's internals.
|
|
SoundDeviceList {
|
|
id: outputList
|
|
width: 620
|
|
visible: false
|
|
output: true
|
|
}
|
|
|
|
SoundCaptureRow {
|
|
id: captureProbe
|
|
width: 620
|
|
}
|
|
|
|
ApplicationMixer {
|
|
id: populatedMixer
|
|
width: 620
|
|
visible: false
|
|
applications: [root.fixtureApplication]
|
|
pipewireReady: true
|
|
}
|
|
|
|
ApplicationMixer {
|
|
id: emptyMixer
|
|
width: 620
|
|
visible: false
|
|
applications: []
|
|
pipewireReady: true
|
|
}
|
|
|
|
ApplicationMixer {
|
|
id: unavailableMixer
|
|
width: 620
|
|
visible: false
|
|
applications: []
|
|
pipewireReady: false
|
|
}
|
|
|
|
PwObjectTracker {
|
|
objects: AudioDevices.outputs.concat(AudioDevices.inputs)
|
|
}
|
|
|
|
IpcHandler {
|
|
target: "sound-page-test"
|
|
|
|
function status(): string {
|
|
return JSON.stringify({
|
|
ready: Pipewire.ready,
|
|
outputs: AudioDevices.outputs.length,
|
|
inputs: AudioDevices.inputs.length,
|
|
applications: AudioDevices.applications.length,
|
|
defaultOutput: AudioDevices.label(AudioDevices.current(true)),
|
|
defaultInput: AudioDevices.label(AudioDevices.current(false)),
|
|
populatedRows: populatedMixer.rowCount,
|
|
populatedStatus: populatedMixer.statusText,
|
|
emptyRows: emptyMixer.rowCount,
|
|
emptyStatus: emptyMixer.statusText,
|
|
unavailableRows: unavailableMixer.rowCount,
|
|
unavailableStatus: unavailableMixer.statusText,
|
|
captureApplications: AudioDevices.captureApplications.length,
|
|
captureTypesValid: AudioDevices.captureApplications.every(application =>
|
|
application.nodes.every(node =>
|
|
(node.type & PwNodeType.AudioInStream)
|
|
=== PwNodeType.AudioInStream)),
|
|
captureRowVisible: captureProbe.visible,
|
|
ghostVisible: !!outputList.absent,
|
|
ghostLabel: outputList.absent ? String(outputList.absent.label) : ""
|
|
});
|
|
}
|
|
}
|
|
}
|