Skip to content

Native Apple Silicon support + working media keys and volume HUD on macOS 26 (Tahoe) - #41

Open
sparc5 wants to merge 1 commit into
rlxone:masterfrom
sparc5:master
Open

Native Apple Silicon support + working media keys and volume HUD on macOS 26 (Tahoe)#41
sparc5 wants to merge 1 commit into
rlxone:masterfrom
sparc5:master

Conversation

@sparc5

@sparc5 sparc5 commented Jul 11, 2026

Copy link
Copy Markdown

This PR makes MultiSoundChanger build natively for Apple Silicon and restores full media-key + on-screen HUD functionality on macOS 26 (Tahoe), where the current approach no longer works.

Why

  1. The repo can't build for arm64. The bundled private OSD.framework binary is x86_64-only, and the project sets EXCLUDED_ARCHS = arm64 to work around it.
  2. On macOS 26 the system handles volume keys at the HID layer, before any CGEventTap can swallow them. I verified this empirically: an active tap at .cgSessionEventTap and .cghidEventTap (head-inserted, swallowing every NX_SYSDEFINED volume event) still cannot prevent the system's "Multi-Output Device" HUD from appearing — the events taps see are downstream copies.
  3. OSDUIHelper is defunct on macOS 26. OSDManager.showImage(...) succeeds but draws nothing, so the app's HUD never appears.

What

  • arm64 build: replaced the bundled x86_64 OSD.framework binary with a hand-written universal .tbd linker stub. Its install name resolves to /System/Library/PrivateFrameworks/OSD.framework at runtime, so nothing changes at run time. EXCLUDED_ARCHS removed; deployment target bumped to 11.0.
  • CocoaPods → Swift Package Manager: MediaKeyTap (the0neyouseek fork) is vendored under Vendor/ with a small patch mapping F18/F19/F20 keycodes to volumeUp/volumeDown/mute.
  • Media keys on macOS 26: on launch the app remaps the consumer-page volume/mute usages to F18/F19/F20 via hidutil (reverted in applicationWillTerminate). The system never sees volume keys — no system HUD, no phantom full-volume slider — and the app receives them as regular function-key events through the existing event tap.
  • Custom volume HUD: new VolumeHUD.swift draws a vibrancy pill (speaker icon, level bar, percentage) reflecting the actual multi-output volume, replacing the dead OSD.framework path.

Tested

On an Apple Silicon Mac running macOS 26.5 with a multi-output (aggregate) device: volume up/down/mute keys adjust the aggregate's sub-device volumes, the system HUD no longer appears, and the app's own HUD tracks the real volume. Menu-bar slider behavior unchanged.

Trade-off worth noting: while the app is running it owns the volume keys at the driver level; if it exits uncleanly the remap persists until relaunch, reboot, or hidutil property --set '{"UserKeyMapping":[]}'.

🤖 Generated with Claude Code

…acOS 26

- Replace bundled x86_64-only private OSD.framework binary with a universal
  .tbd linker stub (the install name resolves to the system framework at
  runtime) and drop EXCLUDED_ARCHS=arm64 so the app builds natively for arm64.
- Replace CocoaPods with Swift Package Manager; vendor MediaKeyTap locally
  (the0neyouseek fork) with added F18/F19/F20 media key mappings.
- On macOS 26 the system handles volume keys at the HID layer before any
  CGEventTap can swallow them, so the system "Multi-Output Device" HUD always
  appeared. Remap volume/mute keys to F18/F19/F20 via hidutil while the app
  runs (reverted on quit) so the system never sees them.
- The private OSDUIHelper no longer draws on macOS 26; add a custom
  vibrancy-pill VolumeHUD showing the actual multi-output volume instead.
- Bump deployment target to macOS 11.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant