Skip to content

fix(audio): suppress Linux hotplug dialog when current selection still works (#2864). Principle III.#2913

Merged
aethersdr-agent[bot] merged 1 commit into
mainfrom
aetherclaude/issue-2864
May 21, 2026
Merged

fix(audio): suppress Linux hotplug dialog when current selection still works (#2864). Principle III.#2913
aethersdr-agent[bot] merged 1 commit into
mainfrom
aetherclaude/issue-2864

Conversation

@aethersdr-agent

Copy link
Copy Markdown
Contributor

Summary

Fixes #2864

What was changed

fix(audio): suppress hotplug dialog when current selection still works (#2864). Principle III.

Files modified

  • src/gui/MainWindow.cpp
 src/gui/MainWindow.cpp | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

Generated by AetherClaude (automated agent for AetherSDR)

#2864). Principle III.

The "Audio Device Detected" modal re-fires every few minutes on Linux
PipeWire because newlyAddedAudioDeviceIds() treats every previously-
unseen QAudioDevice::id() as a "new device" — but the pulse shim
constantly churns transient nodes (monitor sources, per-app loopbacks,
auto_null fallback, echo-cancel/combine virtuals, BT a2dp<->hfp flips).
None of these are actionable for the user, so re-opening the modal is
pure noise.

Two-part fix in src/gui/MainWindow.cpp:

1. isTransientAudioDeviceId() filters Linux pulse/PipeWire IDs that are
   never useful as a PC mic or local-speaker target. The helper is
   applied inside audioDeviceIds() and newlyAddedAudioDeviceIds() so
   transient nodes never enter the "known" set and never count as new.

2. Tighten the dialog gate to require !currentSelectionStillValid: the
   modal only appears when the user actually needs to pick again
   (current input or output went missing). USB-headset hotplug on
   Windows/macOS still triggers the dialog because the new arrival
   coincides with the old selection going away.

Blast radius: risk_score=0.289, 7 high-risk affected (top:
AppSettings::instance, AppSettings::value, AppSettings::setValue).
All high-risk downstream symbols are things this slot already calls
inside the prompt path; the change tightens *when* we enter that
path, not what happens once we are in it, so existing behavior is
preserved on the path the user actually sees.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@aethersdr-agent aethersdr-agent Bot requested a review from ten9876 as a code owner May 21, 2026 13:43
@aethersdr-agent aethersdr-agent Bot enabled auto-merge (squash) May 21, 2026 13:43
@jensenpat jensenpat changed the title fix(audio): suppress hotplug dialog when current selection still works (#2864). Principle III. fix(audio): suppress Linux hotplug dialog when current selection still works (#2864). Principle III. May 21, 2026

@aethersdr-agent aethersdr-agent Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling #2864 — the fix is well-scoped (one file, ~32 lines) and the logic reads cleanly. Two things I'd like the contributor to consider before merge:

1. The dialog-suppression behavior change is cross-platform, but the title implies Linux-only.

userChoiceRequired = deviceAdded && !currentSelectionStillValid is not guarded by #ifdef Q_OS_LINUX. On macOS/Windows, plugging in a brand-new USB headset will also no longer raise the dialog as long as the existing selection still works — the user has to know to open Preferences. That may well be the desired behavior (the previous "any new device → prompt" was likely over-eager everywhere), but it deserves a sentence in the PR body so reviewers understand the scope. Or, if Linux-only was the intent, wrap the new check in #ifdef Q_OS_LINUX.

2. The "combined" substring filter is broader than the others.

if (id.contains("combined")) return true;

This catches PipeWire's combine-sink correctly, but contains("combined") will also silently swallow any future device whose ID happens to embed that word (e.g., a hypothetical USB device named "Combined Output"). The other terms (.monitor, pulse_input_loopback, auto_null, echo-cancel) are all distinctive enough that false positives are very unlikely. For combined, consider tightening to a more specific token like contains("combine-sink") / contains("combine_sink") — that's the actual module-loopback name PipeWire/Pulse generate. Minor — won't block.

Verified:

  • Suppression preserves the existing "selection unusable → reset to default" path (resetInput/resetOutput branch at lines 6443–6446 still fires when the user's choice disappears).
  • audioDevicePresent returns true for null targets, so users following the system default are correctly treated as "selection still valid" and the dialog stays quiet — matches the issue.
  • The transient filter is applied to the snapshot (audioDeviceIds) and the diff (newlyAddedAudioDeviceIds), but not to the unfiltered inputDevices/outputDevices lists handed to AudioDeviceChangeDialog, so a user opening the dialog still sees the full device list. Good.

No bugs, no resource issues, no scope creep. LGTM modulo the two notes above.

@jensenpat jensenpat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suppress Linux Pipewire monitor devices from chooser. Approved

@aethersdr-agent aethersdr-agent Bot merged commit 3291780 into main May 21, 2026
5 checks passed
@aethersdr-agent aethersdr-agent Bot deleted the aetherclaude/issue-2864 branch May 21, 2026 23:54
G6PWY-Chris pushed a commit to G6PWY-Chris/AetherSDR that referenced this pull request Jun 22, 2026
…l works (aethersdr#2864). Principle III. (aethersdr#2913)

## Summary

Fixes aethersdr#2864

### What was changed

fix(audio): suppress hotplug dialog when current selection still works
(aethersdr#2864). Principle III.

### Files modified

- `src/gui/MainWindow.cpp`

```
 src/gui/MainWindow.cpp | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)
```

---
Generated by AetherClaude (automated agent for AetherSDR)

Co-authored-by: aethersdr-agent[bot] <273844287+aethersdr-agent[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.

Linux Pipewire causes pop-up for device changes FreeDV is requesting add the microphone and speaker that was already default from last use.

1 participant