Skip to content

feat: detect clamshell mode and skip built-in mic when lid is closed#567

Open
pascalwhoop wants to merge 1 commit into
Beingpax:mainfrom
pascalwhoop:fix/clamshell-mic-detection
Open

feat: detect clamshell mode and skip built-in mic when lid is closed#567
pascalwhoop wants to merge 1 commit into
Beingpax:mainfrom
pascalwhoop:fix/clamshell-mic-detection

Conversation

@pascalwhoop
Copy link
Copy Markdown

@pascalwhoop pascalwhoop commented Mar 5, 2026

Summary

Fixes #566

When a MacBook lid is closed in clamshell mode the built-in microphone stays visible in CoreAudio's device list but is physically inaccessible. The existing kAudioHardwarePropertyDevices listener never fires (nothing actually disconnects), so VoiceInk had no way to know the mic was unusable and kept trying to use it.

  • Subscribe to NSApplication.didChangeScreenParametersNotification in AudioDeviceManager to detect display configuration changes
  • Call CGDisplayIsBuiltin() on each active screen's display ID — when no built-in display is found, the lid is closed (isClamshellMode = true)
  • All three device-selection paths now skip the built-in mic in clamshell mode: findBestAvailableDevice, selectHighestPriorityAvailableDevice, and getCurrentDevice (custom mode)
  • If there is truly no alternative mic available the built-in is used as a last resort rather than returning nothing
  • State is seeded at launch so the app behaves correctly when started while already docked in clamshell mode
  • Active recordings are never interrupted by a lid-close event

Test plan

  • Start VoiceInk with laptop open (no external display) — internal mic selected as expected
  • Connect external display and close lid — app should automatically switch to next available mic (e.g. AirPods, USB mic) without user interaction
  • Open lid again — built-in mic becomes eligible for selection again
  • Launch VoiceInk while already in clamshell mode — built-in mic is skipped from the start
  • Test all three input modes (System Default, Custom, Prioritized) with lid close/open cycle
  • Verify an active recording is not interrupted when the lid is closed mid-session

🤖 Generated with Claude Code


Summary by cubic

Detects clamshell mode and skips the built-in MacBook mic when the lid is closed, so we auto-select a usable external mic. Fixes #566 and keeps ongoing recordings uninterrupted.

  • New Features
    • Detect clamshell mode via display change notifications (NSApplication.didChangeScreenParametersNotification) and CGDisplayIsBuiltin; seed state at launch.
    • Skip the built-in mic in System Default, Prioritized, and Custom modes when the lid is closed.
    • Fall back to the built-in mic only if no other input is available.
    • Never switch devices mid-recording when the lid closes.

Written for commit 549b890. Summary will update on new commits.

When a MacBook lid closes in clamshell mode the internal microphone stays
visible in CoreAudio's device list but becomes physically inaccessible.
The existing kAudioHardwarePropertyDevices listener never fires because
no device disconnects, leaving VoiceInk stuck on a non-functional mic.

Subscribe to NSApplication.didChangeScreenParametersNotification and check
NSScreen.screens for a built-in display using CGDisplayIsBuiltin(). When no
built-in display is active the lid is closed and isClamshellMode is set to
true, which causes all three device-selection paths (custom, prioritized,
fallback) to skip the built-in microphone and pick the next available device.
State is seeded at launch so the app behaves correctly when started while
already in clamshell mode. Active recordings are never interrupted.

Closes Beingpax#566

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

@jonnywilliamson
Copy link
Copy Markdown

Yes, I noticed this as well. And the only way around it for me was to use the priority list with the other microphones above the MacBook Pro one.

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.

Auto detect clamshell mode and deactivate build in mic

2 participants