Skip to content

fix: keep the output device the user picked in Volume Control - #2097

Merged
laurentiu021 merged 1 commit into
mainfrom
fix/audio-route-user-pick-survives-refresh
Sep 4, 2026
Merged

fix: keep the output device the user picked in Volume Control#2097
laurentiu021 merged 1 commit into
mainfrom
fix/audio-route-user-pick-survives-refresh

Conversation

@laurentiu021

Copy link
Copy Markdown
Owner

Closes #2096.

What was wrong

OutputRouteUnknown drives the picker's "Choose a device" placeholder, and OnSelectedOutputDeviceChanged never cleared it after a successful write. Two consequences:

  1. The placeholder TextBlock shares its Grid cell with the ComboBox at Margin="10,0,0,0" — where the box draws its selected item — so the prompt was painted over the name the user picked.
  2. RefreshDevicesAsync snapshots each row as OutputRouteUnknown ? null : id. A row still flagged unknown snapshotted as null and was re-applied as null, so the picker blanked on the tenth reconcile pass, about ten seconds after the choice. Windows kept the route; the UI forgot it, leaving the user no way to see or undo what they set.

Every routable app on every machine, because the route read is still a stub returning null (#2088).

Introduced in v1.76.7 with the three-state flag. Before it the snapshot read the selection directly and a hand-made pick survived — a regression, not a long-standing gap.

The fix

A successful write settles the flag: SysManager knows the route because it is what set it. A refused write leaves it alone, because nothing moved.

Verification

Red-before / green-after, both tests, mutation = the pre-fix shape of OnSelectedOutputDeviceChanged:

Test Red reason under mutation
AUserPickedDevice_IsNoLongerAnUnknownRoute FalseException — the flag stays up, so the prompt covers the chosen name
AUserPickedDevice_SurvivesADeviceRefresh EqualException: Expected "{hdst}", Actual null — the pick is discarded

Both green after; AnUnknownRoute_StaysUnknownAcrossADeviceRefresh and PuttingAnAppBackOnTheDefaultDevice_ClearsTheOverride stayed green throughout, so the unknown-route contract is intact.

Regression sweep: 137 named tests across the audio suites and ArchitectureTests — 152 cases, all green. Builds 0 errors / 0 warnings (app + tests), dotnet format --verify-no-changes clean on both, version consistency csproj 1.76.9 = CHANGELOG 1.76.9 = SECURITY 1.76.x.

Docs

No README change needed — it already promises this behaviour ("the device list is re-read every ten seconds, and each app keeps the destination you picked for it"). The claim was false until this commit.

The picker shows a "Choose a device" prompt while SysManager cannot read where
Windows is sending an app, which is every app today. Choosing a device routed the
app but never cleared that flag, so the prompt stayed painted over the chosen name
and the tab's ten-second device re-read then snapshotted the row as unrouted and
blanked the picker, discarding the only record of what the user had set.

A successful write now settles the flag: SysManager knows the route because it is
what set it. A refused write leaves the flag alone, since nothing moved.

Introduced in v1.76.7 with the three-state route flag -- before it the refresh
snapshot read the selection directly and a hand-made pick survived. README already
documented the fixed behaviour ("each app keeps the destination you picked for it").

Two regression tests, both red before this change: the flag one on the prompt
overprinting, the refresh one on "Expected {hdst}, Actual null".

Closes #2096
@laurentiu021
laurentiu021 merged commit eba59df into main Sep 4, 2026
5 checks passed
@laurentiu021
laurentiu021 deleted the fix/audio-route-user-pick-survives-refresh branch September 4, 2026 06:33
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.

[Bug]: Volume Control — the output device you pick is forgotten ten seconds later

1 participant