Skip to content

[BUG] UI can beachball while opening/closing audio devices during recording #1715

Description

@xronocode

Before You Submit

I searched existing open and closed issues/PRs for this specific failure mode. The closest reports I found are related but different:

I did not find an issue for the UI becoming unresponsive because audio open/close or device enumeration can run through UI-facing paths while the audio manager state mutex is contended.

Bug Description

Handy can intermittently beachball or become unresponsive while recording, especially when an external Bluetooth/USB microphone is opening or closing, when changing the selected input device, or when toggling microphone mode.

In the worst case the UI stops responding and the app has to be force-quit. This is separate from slow transcription after recording: the freeze happens around audio device operations and recording state updates.

The risky path is the UI waiting on audio work that can block at the OS/device layer:

  • is_recording() is polled by the frontend and currently locks the audio manager state.
  • update_microphone_mode, get_available_microphones, set_selected_microphone, and get_available_output_devices are synchronous Tauri commands, so cpal device enumeration or stream restart work can run inline on the webview/main run loop.

When another thread is holding the audio state mutex across a slow CoreAudio/cpal open or close, these UI-facing paths can serialize the main thread and make the app appear frozen.

I have seen this around external-device recording paths. Reproduction is hardware-dependent, but these paths exercise the problem area:

  1. Use push-to-talk with an on-demand Bluetooth or USB microphone.
  2. Start and stop recording repeatedly.
  3. While recording or shortly after stopping, open Settings > Audio, change the selected input device, or toggle Always-On / On-Demand microphone mode.
  4. The UI may beachball or stop responding.

Expected behavior: audio device open/close and enumeration may be slow, but the Handy UI should remain responsive.

System Information

App Version:

Development build from current main at d861e24 (0.9.3 in src-tauri/Cargo.toml).

Operating System:

macOS 26.5.1 (25F80).

CPU:

MacBook Air (Mac17,4), Apple M5, 10 cores, 32 GB memory.

GPU:

Apple M5 integrated GPU, 10 cores.

Logs

No stable app-level error log is available for the freeze. The failure presents as the UI beachballing around native audio device work rather than a normal logged Rust error.

Code-level evidence on main at d861e24:

  • src-tauri/src/managers/audio.rs: is_recording() locks state while the frontend polls recording state.
  • src-tauri/src/commands/audio.rs: update_microphone_mode, get_available_microphones, set_selected_microphone, and get_available_output_devices are synchronous Tauri commands and can call cpal device enumeration or stream restart work inline on the webview/main run loop.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions