Skip to content

feat: add tray microphone switcher - #215

Merged
jatinkrmalik merged 1 commit into
VocaHQ:mainfrom
Mr-Sunglasses:feat/tray-microphone-switcher
Aug 13, 2026
Merged

feat: add tray microphone switcher#215
jatinkrmalik merged 1 commit into
VocaHQ:mainfrom
Mr-Sunglasses:feat/tray-microphone-switcher

Conversation

@Mr-Sunglasses

@Mr-Sunglasses Mr-Sunglasses commented Aug 12, 2026

Copy link
Copy Markdown
Member

Problem

Users had to open Settings to change the microphone used for dictation from VocaMac.

Demo

Screenshot 2026-08-13 at 2 24 32 AM Screenshot 2026-08-13 at 2 24 40 AM

Summary

  • Add a microphone picker directly to the menu-bar popover.
  • Support System Default, available devices, refresh, and unavailable-device status.
  • Persist tray selections through AppState and keep Settings synchronized.
  • Add regression coverage for selection persistence.

Verification

  • swift test — 359 tests passed, 3 skipped
  • make build — succeeded with local ad-hoc signing
  • git diff --check — passed

@github-actions github-actions Bot added app bug Something isn't working ci and removed bug Something isn't working ci labels Aug 12, 2026
@jatinkrmalik
jatinkrmalik merged commit ab480ee into VocaHQ:main Aug 13, 2026
5 checks passed
@jatinkrmalik

Copy link
Copy Markdown
Member

@Mr-Sunglasses the next-recording path looks right. selectAudioDevice writes the same selectedAudioDeviceID that startRecording already passes into AudioEngine, and Settings stays in sync because it binds to those keys. Disabling the menu while isRecording matches how the engine works (device is applied at start, not live).

The helper caption is already clipped in your first screenshot: "Does not change macOS's system d...". That's the only line that says VocaMac will not steal the macOS default input, and it's unreadable. MenuBarView is 380pt wide. The permission captions in this same file wrap with .fixedSize(horizontal: false, vertical: true). This Text doesn't.

Two gaps vs AudioSettingsTab:

  1. Settings appends " (Unavailable)" at the Picker and tells you the next recording falls back to System Default. The tray bakes "(Unavailable)" into the helper, shows a dead Text row with no checkmark, and never says that. Tray refreshAudioDevices() also writes selectedAudioDeviceName directly instead of going through selectAudioDevice.

  2. If Settings and the tray share one picker (or one set of helpers), this won't drift. Until then, keep the display-name rules identical and show the same fallback sentence.

Nit on the new test: after selectAudioDevice(device), start a recording and assert mocks.audioEngine.lastPreferredInputDeviceID. Right now it only checks that two properties were written.

@jatinkrmalik

Copy link
Copy Markdown
Member

@Mr-Sunglasses I have merged it for now but this will require a small follow-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants