diff --git a/src/config/names.rs b/src/config/names.rs index 09f6087..8af89ba 100644 --- a/src/config/names.rs +++ b/src/config/names.rs @@ -16,6 +16,7 @@ impl Names { pub fn default_endpoint() -> Vec { vec![ + "{node:node.nick}".parse().unwrap(), "{device:device.nick}".parse().unwrap(), "{node:node.description}".parse().unwrap(), ] diff --git a/src/view.rs b/src/view.rs index 08877d8..aab096e 100644 --- a/src/view.rs +++ b/src/view.rs @@ -365,28 +365,56 @@ impl Device { .profiles .values() .map(|profile| { - let title = if profile.available { - profile.description.clone() + let profile_devices: Vec = profile + .classes + .iter() + .flat_map(|(_, devices)| devices.iter().copied()) + .collect(); + let matching_routes: Vec<_> = device + .enum_routes + .values() + .filter(|route| { + route + .devices + .iter() + .any(|d| profile_devices.contains(d)) + }) + .collect(); + let monitor_name = if matching_routes.len() == 1 { + matching_routes[0].product_name.as_deref() } else { - format!("{} (unavailable)", profile.description) + None + }; + let title = match (profile.available, monitor_name) { + (true, Some(name)) => { + format!("{} \u{2014} {}", profile.description, name) + } + (false, Some(name)) => format!( + "{} \u{2014} {} (unavailable)", + profile.description, name + ), + (true, None) => profile.description.clone(), + (false, None) => { + format!("{} (unavailable)", profile.description) + } }; (profile.index, title) }) .collect(); profiles.sort_by_key(|&(index, _)| index); - let profiles = profiles + let profiles: Vec<(Target, String)> = profiles .into_iter() .map(|(index, title)| (Target::Profile(object_id, index), title)) .collect(); - let target_profile = device.profiles.get(&device.profile_index?)?; - let target_title = if target_profile.available { - target_profile.description.clone() - } else { - format!("{} (unavailable)", target_profile.description) - }; + let profile_index = device.profile_index?; + let target_title = profiles + .iter() + .find(|(t, _)| *t == Target::Profile(object_id, profile_index)) + .map(|(_, title)| title.clone()) + .unwrap_or_default(); - let target = Some(Target::Profile(object_id, device.profile_index?)); + let target = Some(Target::Profile(object_id, profile_index)); let object_serial = *device.props.object_serial()?; diff --git a/src/wirehose/device.rs b/src/wirehose/device.rs index 9b236ca..ff18b78 100644 --- a/src/wirehose/device.rs +++ b/src/wirehose/device.rs @@ -100,6 +100,7 @@ fn device_enum_route(object_id: ObjectId, param: Object) -> Option { let mut available = None; let mut profiles = None; let mut devices = None; + let mut product_name = None; for prop in param.properties { match prop.key { @@ -129,6 +130,25 @@ fn device_enum_route(object_id: ObjectId, param: Object) -> Option { devices = Some(value); } } + libspa_sys::SPA_PARAM_ROUTE_info => { + if let Value::Struct(info_struct) = prop.value { + let skip = match info_struct.first() { + Some(Value::Int(_)) => 1, + _ => 0, + }; + let mut iter = info_struct.into_iter().skip(skip); + while let ( + Some(Value::String(key)), + Some(Value::String(val)), + ) = (iter.next(), iter.next()) + { + if key == "device.product.name" { + product_name = Some(val); + break; + } + } + } + } _ => {} } } @@ -140,6 +160,7 @@ fn device_enum_route(object_id: ObjectId, param: Object) -> Option { available: available?, profiles: profiles?, devices: devices?, + product_name, }) } diff --git a/src/wirehose/event.rs b/src/wirehose/event.rs index 8785fe5..852de8b 100644 --- a/src/wirehose/event.rs +++ b/src/wirehose/event.rs @@ -28,6 +28,7 @@ pub enum StateEvent { available: bool, profiles: Vec, devices: Vec, + product_name: Option, }, DeviceEnumProfile { object_id: ObjectId, diff --git a/src/wirehose/state.rs b/src/wirehose/state.rs index 7e93071..b6d02f6 100644 --- a/src/wirehose/state.rs +++ b/src/wirehose/state.rs @@ -21,6 +21,7 @@ pub struct EnumRoute { pub available: bool, pub profiles: Vec, pub devices: Vec, + pub product_name: Option, } #[derive(Debug)] @@ -162,6 +163,7 @@ impl State { available, profiles, devices, + product_name, } => { self.device_entry(object_id).enum_routes.insert( index, @@ -171,6 +173,7 @@ impl State { available, profiles, devices, + product_name, }, ); } diff --git a/wiremix.toml b/wiremix.toml index d1e521f..4621f2d 100644 --- a/wiremix.toml +++ b/wiremix.toml @@ -166,7 +166,7 @@ keybindings = [ # Streams in the Playback/Recording tabs stream = [ "{node:node.name}: {node:media.name}" ] # Endpoints in the Input/Output Devices tabs -endpoint = [ "{device:device.nick}", "{node:node.description}" ] +endpoint = [ "{node:node.nick}", "{device:device.nick}", "{node:node.description}" ] # Devices in the Configuration tab device = [ "{device:device.nick}", "{device:device.description}" ]