From acd8b6ed42255f22e1cc85fba38dcd38847d8f18 Mon Sep 17 00:00:00 2001 From: Tomas Hlavacek Date: Thu, 23 Apr 2026 11:05:58 +0200 Subject: [PATCH] fix(sound): match ActiveRoute events to the correct node via card_profile_device Fix https://github.com/pop-os/cosmic-applets/issues/1388 When a device has multiple sink/source nodes (e.g. a GPU with multiple HDMI outputs on a single ALSA card), an ActiveRoute event for the currently active device caused the handler to pick the first node from the device_ids IntMap whose device matched. IntMap iteration order is hash-based, so the first node was effectively random among nodes sharing the same device. Use card_profile_device to disambiguate: only match a node when its card.profile.device is listed in route.devices. This mirrors the matching already done in update_device_route_name. A LLM was used to analyze the code paths and draft the patch. The diagnosis and fix were verified end-to-end against a real multi-HDMI setup (Radeon HDMI/DP card with three sink nodes) by reproducing the stuck-volume symptom and confirming it no longer occurs after the patch is applied. --- subscriptions/sound/src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/subscriptions/sound/src/lib.rs b/subscriptions/sound/src/lib.rs index adac229d8..2423303d6 100644 --- a/subscriptions/sound/src/lib.rs +++ b/subscriptions/sound/src/lib.rs @@ -520,6 +520,15 @@ impl Model { if active_device == Some(id) { for (node_id, &device) in &self.device_ids { if device == id && node_ids.contains(&node_id) { + // Match the route to the correct node via card_profile_device, + // so that devices with multiple nodes (e.g. multi-HDMI cards) + // don't get their active sink switched to a wrong node. + if let Some(&cpd) = self.card_profile_devices.get(node_id) { + if !route.devices.contains(&(cpd as i32)) { + continue; + } + } + set_default_node(self, node_id); break; }