"Use Windows default" is now exclusive: it clears + locks out the specific cards

Ed: ticking "Use Windows default audio device" should uncheck the other cards and stop
them being ticked again until the default is turned back off - in both the app and the
service. This replaces the old optional "shall I untick the others?" prompt with a hard
rule.

Behaviour (all follower lists: app received-outputs, outputs-to-send and inputs-to-send;
service outputs):
- Ticking the follower unticks every specific card in that list.
- While the follower is on, trying to tick a specific card is refused (the ItemCheck is
  vetoed straight back to unticked) - you're either following the Windows default or
  picking cards, never both.
- Unticking the follower frees the cards again.
- Enforced on load too, so a hand-edited/legacy profile carrying both comes up clean.

Shared, not duplicated: the veto + clear + follower-checked helpers live in
AudioDefaultFollower and are used by MainForm and the service dialog alike.

Removed the now-obsolete soft prompt and everything that hung off it:
- MainForm.MaybeUntickOthersForDefault + ResetDefaultAudioDevicePrompt.
- The "Reset the default audio device prompt" Options item (and its Alt+O,R).
- AppConfig.UntickOthersWhenUsingDefaultOutput/Input.
- Manual + About-box references to the prompt / reset item; the manual now documents
  the exclusive rule and lists all three follower lists (the outputs-to-send follower
  had been undocumented).

Test: "Default follower exclusivity" self-test - follower on clears + locks specific
cards, follower off frees them, unticking and the follower entry itself are never
vetoed. Gate 45/45.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ednunp
2026-07-17 23:26:38 +01:00
co-authored by Claude Opus 4.8
parent 4a86a82ec8
commit 5fc1b5bd75
7 changed files with 118 additions and 107 deletions
+18
View File
@@ -160,6 +160,21 @@ internal sealed class ServiceProfileDialog : Form
CheckedListAccessibility.Wire(appsList, appsStatus, "application");
CheckedListAccessibility.Wire(inputsList, inputsStatus, "input device");
// "Use Windows default output" is exclusive, same as the main app: while it's ticked the specific
// output cards can't be, and ticking it clears them.
outputsList.ItemCheck += (_, e) =>
{
if (suppressAppEvents) return;
if (AudioDefaultFollower.VetoRealDeviceCheck(outputsList, e)) return;
if (outputsList.Items[e.Index] is AudioDeviceChoice { IsDefaultFollower: true } && e.NewValue == CheckState.Checked)
BeginInvoke(new Action(() =>
{
suppressAppEvents = true;
try { AudioDefaultFollower.UncheckRealDevices(outputsList); }
finally { suppressAppEvents = false; }
}));
};
page.Controls.Add(panel);
tabs.TabPages.Add(page);
}
@@ -203,6 +218,9 @@ internal sealed class ServiceProfileDialog : Form
var outputChoices = new List<AudioDeviceChoice> { AudioDefaultFollower.LoopbackSendChoice() };
outputChoices.AddRange(AudioDeviceCatalog.LoadOutputs());
PopulateDeviceList(outputsList, outputChoices, working.SelectedWasapiSendOutputs);
// Default is exclusive: if the profile carries the follower, drop any specific outputs it also
// carried (already inside the suppressAppEvents guard set at the top of LoadFromProfile).
if (AudioDefaultFollower.IsFollowerChecked(outputsList)) AudioDefaultFollower.UncheckRealDevices(outputsList);
PopulateDeviceList(inputsList, AudioDeviceCatalog.LoadInputs(), working.SelectedWasapiSendInputs);
var appsMode = ProcessLoopbackCapture.IsSupported