• v0.9.1 27d5f0c818

    In-app audio device picker (controller-driven)
    release / Build Windows .zip (push) Canceled after 0s

    LastSkywalker released this 2026-05-31 09:07:39 +03:00

    The shell mode was missing a way to switch the default audio device from
    a controller — the only path was the Settings button that popped open
    the Windows "Параметры → Звук" page, mouse-only and outside the
    fullscreen shell. Same gap the monitor picker closed earlier.

    internal/audio (Windows-only, no CGO):

    • enumerates active render+capture endpoints via the documented MMDevice
      API (IMMDeviceEnumerator, IPropertyStore, PKEY_Device_FriendlyName);
    • switches the default via undocumented IPolicyConfigVista
      (CLSID 870af99c-..., IID 568b9108-..., SetDefaultEndpoint at vtable
      slot 12 — same interface SoundSwitch, NirSoft, AHK scripts have used
      for ~15 years; stable across Vista→Win11);
    • hand-rolled vtable dispatch via syscall.SyscallN, CoInitializeEx(MTA)
      • LockOSThread per call. Same pattern as internal/display.
    • SetDefault flips Console + Multimedia roles (what the Windows "Set
      Default" button does); Communications role left alone.

    AudioPicker (frontend):

    • two columns (output / input), pre-selects current default per column;
    • controller bindings mirror MonitorPicker: ↑↓ within column,
      ←→/LB/RB swap columns, A applies, B/Esc closes; same for keyboard.

    Wired into three surfaces:

    • Settings page: replaces "Открыть «Параметры → Звук»" button with the
      inline picker (system shortcut kept as a fallback sibling button);
    • 🎧 corner icon next to 🖥 monitor switch in shell mode;
    • one-shot auto-chain on shell startup: after MonitorPicker.onDone fires
      for the first time (or if the picker was skipped because there's only
      one display) the AudioPicker opens once. Guard via useRef so
      re-picking a monitor mid-session does not drag audio back open.

    inputBlocked in ShellApp now also gates on audioOpen so the carousel
    behind the picker doesn't double-handle d-pad/A.

    ADR: .claude/decisions/0023-in-app-audio-device-picker.md.

    Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

    Downloads