Skip to content

fix: show monitor name for HDMI/DP audio endpoints#46

Open
okhomenko wants to merge 4 commits intotsowell:mainfrom
okhomenko:fix/hdmi-endpoint-name
Open

fix: show monitor name for HDMI/DP audio endpoints#46
okhomenko wants to merge 4 commits intotsowell:mainfrom
okhomenko:fix/hdmi-endpoint-name

Conversation

@okhomenko
Copy link

@okhomenko okhomenko commented Mar 18, 2026

Problem

image image

When using NVIDIA GPU audio in pro-audio mode, or any HDMI/DP output, all sinks share the same PipeWire device. The default endpoint name template resolves {device:device.nick} first — which returns the GPU/card name (e.g. HDA NVidia) for every output — making multiple HDMI/DP sinks completely indistinguishable in wiremix.

Additionally, the Configuration tab shows generic names for both the selected profile and the profile dropdown, with no indication of which physical monitor each profile corresponds to.

Reproducing steps:

  1. Have a machine with an NVIDIA GPU and multiple monitors connected via HDMI/DisplayPort
  2. Enable pro-audio profile: pactl set-card-profile alsa_card.pci-0000_01_00.1 pro-audio
  3. Open wiremix → all HDMI/DP sinks appear as HDA NVidia in Output Devices tab
  4. Switch to the Configuration tab → selected profile shows Digital Stereo (HDMI 2) Output and the dropdown lists all profiles without monitor names

Expected: each sink, selected profile, and profile dropdown entry shows the name of the connected monitor (e.g. PA32QCV, DELL U2723QE)

Actual: all sinks show HDA NVidia; selected profile and dropdown show generic HDMI port numbers only

Root cause

Output Devices tab: PipeWire reads the monitor name from EDID/ELD data and stores it in node.nick (e.g. PA32QCV, DELL U2723QE). The device-level device.nick is the GPU name shared by all HDMI outputs on that card. The default endpoint template tried {device:device.nick} first — it always succeeds — so {node:node.description} was never reached.

Configuration tab: Profile descriptions (Digital Stereo (HDMI) Output) come from PipeWire and don't include monitor names. The SPA_PARAM_ROUTE_info dict on each EnumRoute contains device.product.name (the EDID monitor name) but was not being parsed. The selected profile display was also derived independently from the raw profile description, so it missed the enrichment too.

This can be verified:

$ aplay -l | grep NVidia
card 0: NVidia [HDA NVidia], device 3: HDMI 0 [DELL U2723QE]
card 0: NVidia [HDA NVidia], device 7: HDMI 1 [PA32QCV]

$ pactl list sinks | grep "node.nick"
  node.nick = "DELL U2723QE"
  node.nick = "PA32QCV"

Fix

image image

Output Devices tab: Add {node:node.nick} as the first template in default_endpoint. When node.nick is set (HDMI/DP monitors), it is used. When absent, falls through to {device:device.nick} as before.

 pub fn default_endpoint() -> Vec<NameTemplate> {
     vec![
+        "{node:node.nick}".parse().unwrap(),
         "{device:device.nick}".parse().unwrap(),
         "{node:node.description}".parse().unwrap(),
     ]
 }

Configuration tab: Parse SPA_PARAM_ROUTE_info in device_enum_route to extract device.product.name. When a profile maps to exactly one route with a known monitor name, append it to the profile description. The selected profile display reuses this enriched title so it stays consistent with the dropdown.

Before: Digital Stereo (HDMI 2) Output
After:  Digital Stereo (HDMI 2) Output — PA32QCV

Profiles that map to multiple routes (e.g. Pro Audio) or no routes (e.g. Off) are left unchanged.

When using NVIDIA GPU audio in pro-audio mode (or any HDMI/DP output),
all sinks share the same PipeWire device. The previous default endpoint
template resolved {device:device.nick} first, which returns the GPU
name ("HDA NVidia") for every output, making them indistinguishable.

PipeWire populates node.nick with the monitor name sourced from EDID/ELD
data (e.g. "PA32QCV", "DELL U2723QE"). By trying {node:node.nick} first,
each HDMI/DP sink now shows its connected monitor's name. For devices
where node.nick is absent, the template falls through to device.nick as
before.
@okhomenko okhomenko force-pushed the fix/hdmi-endpoint-name branch from 7343a46 to 3b39bf1 Compare March 18, 2026 16:57
Parse SPA_PARAM_ROUTE_info from EnumRoute params to extract
device.product.name (sourced from EDID/ELD data). When a profile maps
to exactly one route with a known monitor name, append it to the profile
description in the Configuration tab dropdown.

Before: Digital Stereo (HDMI 2) Output
After:  Digital Stereo (HDMI 2) Output — PA32QCV

Profiles that map to multiple routes (e.g. Pro Audio) or no routes
(e.g. Off) are left unchanged.
Reuse the enriched profile title (which includes the monitor name) for
the target_title shown below the device name in the Configuration tab,
instead of re-deriving it from the raw profile description.
@okhomenko
Copy link
Author

Brainstorming on how we could make this PR stronger for long-term quality: instead of treating this as just an HDMI/NVIDIA naming fix, maybe we should establish a reusable "physical endpoint label" concept and have both the Output Devices tab and Configuration tab build on that.

What I mean by that is:

  • move the route/profile/device matching heuristics out of view.rs and into a small helper/domain layer owned by PipeWire state
  • define one source of truth for "what physical thing does this endpoint/profile correspond to?"
  • make the default endpoint naming use that concept, rather than hard-coding node.nick
  • reuse the same helper when enriching Configuration profile titles

That would give us one place to handle cases like:

  • one profile mapping cleanly to one physical output
  • shared device ids across multiple routes/profiles
  • multi-route profiles like pro-audio
  • fallback when no monitor/product name exists

If we go that route, I think the cleanest version may be to expose a computed label through the naming system itself, so templates/overrides can use it too, instead of keeping it as a view-only special case.

@tsowell curious what you think — is that too much scope for this PR, or does it feel like the right direction while we're touching this area?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant