Skip to content

fix(pipewire): mute route-less virtual sources - #4250

Open
kvnloo wants to merge 1 commit into
noctalia-dev:mainfrom
kvnloo:fix/noctalia-4226-virtual-source-mute
Open

fix(pipewire): mute route-less virtual sources#4250
kvnloo wants to merge 1 commit into
noctalia-dev:mainfrom
kvnloo:fix/noctalia-4226-virtual-source-mute

Conversation

@kvnloo

@kvnloo kvnloo commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Mute route-less virtual audio sources (EasyEffects virtual microphones) by continuing past mixer-api to the existing SPA PROP_mute node write. Hardware sources that already have a DeviceRoute stay mixer-api-only.

Audio/Source/Virtual is collapsed to Audio/Source after #3846, so panel mute currently writes mixer-api, sets optimistic swMute for the icon, and returns before SPA mute. That stops capture on routed hardware mics but leaves EasyEffects filter-graph capture live.

Motivation

#4226 — muting the selected EasyEffects virtual microphone flips the muted icon while capture still passes. Hardware "Kreo Sonic Analog Stereo" mutes correctly. Virtual recognition (#3846) listed these sources; it did not make mute stop capture.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Build / packaging

Related Issue

Closes #4226

Testing

  • clang-format 22.1.8 --dry-run --Werror on src/pipewire/pipewire_service.cpp: exit 0
  • git diff --check: exit 0
  • Standalone control-flow contract virtual_source_mute_test.cpp:
    • baseline (-DBASELINE): exit 1 — route-less virtual source must receive a direct SPA node mute
    • candidate 1736d19f75c37e177e18d2b2f9d3f6897842ef13: exit 0 — PASS
    • cases: route-less source gets SPA mute; routed hardware source stays mixer-only; program stream retains SPA mute; device source without mixer retains SPA mute
  • Full Meson/Ninja suite was not run; this host has no EasyEffects capture graph. The change is the early-return gate in PipeWireService::setNodeMuted only.

Manual Coverage

  • Tested on Niri
  • Tested on Hyprland
  • Tested on Sway
  • Tested on another compositor:
  • Tested with different bar positions and density settings
  • Tested at different interface scaling values
  • Tested with multiple monitors

No live EasyEffects session was available on the verification host.

Screenshots / Videos

N/A — mute control-flow, no UI layout change.

Checklist

  • This PR is ready for review, or it is marked as Draft.
  • I read and followed the relevant guidance in CONTRIBUTING.md.
  • I ran just format with clang-format v22+ installed, or this PR has no code changes.
  • I ran the relevant build or test commands, or explained why they were not run.
  • I self-reviewed the changes.
  • I checked for new warnings or errors.
  • I updated user-facing documentation in docs/user/ when this PR changes documented behavior or configuration, or this PR does not require documentation changes.
  • I added or updated assets/translations/en.json, or this PR adds no new user-facing strings.
  • I did not edit non-English translation files unless this PR is explicitly for translation tooling, an import/export sync, or a maintainer-requested locale change.
  • I used the existing canonical names for config keys, IPC names, paths, and identifiers.

Additional Notes

Candidate SHA 1736d19f75c37e177e18d2b2f9d3f6897842ef13 on baseline a1a0e0ffc841af1f77901bc7ebc81c104ed8d56e. Does not implement #3274 (visual mute desync). Does not change default-device selection.

@Krak8

Krak8 commented Sep 4, 2026

Copy link
Copy Markdown

Thanks for the mic fix :)

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] Virtual Audio Sinks can't be muted

2 participants