Skip to content

Commit b7ba9c1

Browse files
fix(pw): show all input devices, not just the default source (#3387)
routeDirectionForMediaClass() returns SPA_DIRECTION_INPUT (== 0) for Audio/Source, which collides with the 0 value used as the "no direction" sentinel. The availability logic guarded on `wantDir != 0`, so for every input device activeRoute was forced to null while hasDirRoutes stayed true, leaving node.available = false. The audio panel's availableDevices() then kept only the current default source and hid all other microphones. Guard on the media class being a device node instead, matching the isDeviceNode check already used during route parsing. This also repairs recomputeEffectiveMute() for inputs, which carried the same guard. Outputs were never affected because SPA_DIRECTION_OUTPUT == 1. Co-authored-by: TheBinaryLoop <13447164+TheBinaryLoop@users.noreply.github.com>
1 parent ab16afc commit b7ba9c1

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

src/pipewire/pipewire_service.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,12 +1607,15 @@ void PipeWireService::rebuildState() {
16071607
// explicitly unavailable and no available alternative is hidden. Cards that report "unknown"
16081608
// (many HDA/HiFi setups) stay visible.
16091609
const std::uint32_t wantDir = routeDirectionForMediaClass(nd->mediaClass);
1610-
const DeviceRouteData* activeRoute = wantDir != 0 ? activeRouteForDirection(nd->routes, wantDir) : nullptr;
1610+
// SPA_DIRECTION_INPUT == 0, so `wantDir != 0` would wrongly exclude every Audio/Source; guard on the
1611+
// media class being a device node instead (matches the isDeviceNode check used during route parsing).
1612+
const bool isDeviceNode = nd->mediaClass == "Audio/Sink" || nd->mediaClass == "Audio/Source";
1613+
const DeviceRouteData* activeRoute = isDeviceNode ? activeRouteForDirection(nd->routes, wantDir) : nullptr;
16111614
const DeviceData* device = nullptr;
16121615
if (nd->deviceId != 0) {
16131616
if (const auto devIt = m_devices.find(nd->deviceId); devIt != m_devices.end()) {
16141617
device = &devIt->second;
1615-
if (activeRoute == nullptr && wantDir != 0) {
1618+
if (activeRoute == nullptr && isDeviceNode) {
16161619
activeRoute = activeRouteForDirection(device->routes, wantDir);
16171620
}
16181621
}
@@ -1677,9 +1680,11 @@ void PipeWireService::rebuildState() {
16771680

16781681
void PipeWireService::recomputeEffectiveMute(NodeData& nd) {
16791682
const std::uint32_t wantDir = routeDirectionForMediaClass(nd.mediaClass);
1680-
const DeviceRouteData* nodeRoute = wantDir != 0 ? activeRouteForDirection(nd.routes, wantDir) : nullptr;
1683+
// SPA_DIRECTION_INPUT == 0, so guard on the media class rather than `wantDir != 0` (which would skip sources).
1684+
const bool isDeviceNode = nd.mediaClass == "Audio/Sink" || nd.mediaClass == "Audio/Source";
1685+
const DeviceRouteData* nodeRoute = isDeviceNode ? activeRouteForDirection(nd.routes, wantDir) : nullptr;
16811686
const DeviceRouteData* deviceRoute = nullptr;
1682-
if (nd.deviceId != 0 && wantDir != 0) {
1687+
if (nd.deviceId != 0 && isDeviceNode) {
16831688
const auto it = m_devices.find(nd.deviceId);
16841689
if (it != m_devices.end()) {
16851690
deviceRoute = activeRouteForDirection(it->second.routes, wantDir);

0 commit comments

Comments
 (0)