feat: cycle output device button action#1
Merged
Conversation
Two endpoints can report the same friendly name (e.g. two monitors on one GPU's NVIDIA audio). list_devices now appends " (2)", " (3)", … to repeated names so each is shown and selectable; find_device parses the suffix back to the Nth same-named endpoint. The first occurrence stays bare, so already-saved configs keep resolving. Also pin the Icon component to a fixed size. Without a max-width, a layout gave it an implicit stretch factor of 1, so it ate row free space and the centered glyph drifted off the right edge. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a "Cycle output device" button action that switches the default audio endpoint to the next device in a configured list on each press (wrapping). An empty list cycles through all active outputs. - model: new ActionKind::CycleOutput; property holds a newline-separated device list (empty = all). - events/actuator: Cmd::CycleOutput dispatched on button press, applied off the UI thread via a new AudioBackend::cycle_output. - wasapi: switch the default endpoint via the undocumented IPolicyConfig COM interface (declared with the windows #[interface] macro), matching the current default by stable device id so duplicate friendly names still cycle correctly. find_device refactored to share the name resolver (resolve_in). - pulse: cycle_output via pactl get/set-default-sink. - UI: multi-select picker in the wizard — rows toggle membership, the chosen set lives in the wizard property; empty selection is allowed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ⇄ (U+21C4) separator isn't in Inter and rendered as a tofu box. Derive the action's secondary label at render time from the device list, joined with → (U+2192), so it's correct without a stored display and fixes already-saved actions without re-adding them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a "Cycle output device" button action. On each press it switches the default audio endpoint to the next device in a configured list (wrapping). An empty list cycles through all active output endpoints.
This is the first of the planned controller features and validates the non-volume action plumbing end-to-end.
What changed
ActionKind::CycleOutput; the action'spropertyholds a newline-separated device list (empty = all).Cmd::CycleOutput, applied off the UI thread via a newAudioBackend::cycle_output.IPolicyConfigCOM interface, declared with thewindows#[interface]macro (addedwindows-coreas a direct dep so the macro's::windows_corepaths resolve, pinned to the same 0.58windowsre-exports). The current default is matched by stable device id, so duplicate friendly names (e.g. two identically-named LG monitors) still cycle correctly.find_devicewas refactored to share the name resolver (resolve_in).cycle_outputviapactl get/set-default-sink.→.Testing
cargo buildclean;cargo test9 passed.🤖 Generated with Claude Code