Use any keyboard's volume keys to control audio on a DDC/CI external display.
Quick start · How it works · Mute behavior · Troubleshooting
DisplayVolumeKeys is a focused, open-source macOS menu-bar app. It maps volume up, volume down, and mute media keys to an external display's DDC/CI audio control and shows an accurate native-style volume HUD.
The project is inspired by BetterDisplay. I built it after experiencing a BetterDisplay memory leak in my own setup and wanting its useful keyboard-to-display volume behavior without virtual displays, scaling, HDR controls, display overrides, or other unrelated functionality.
| Capability | Status |
|---|---|
| Volume up, volume down, and held-key repeat | ✅ |
| Media keys from Apple and third-party keyboards | ✅ |
DDC/CI speaker volume (VCP 0x62) |
✅ |
| Displays with valid DDC reads | ✅ |
| Write-only displays with malformed reads | ✅ Cached level |
| Accurate native-style volume HUD | ✅ |
| Automatic launch at login | ✅ SMAppService |
| Root helper, kernel extension, or virtual audio driver | ❌ Not required |
- macOS 13 or later on Apple Silicon
- A DDC/CI display with audio-volume control
- Swift 5.10 or later to build from source
git clone https://github.com/TurabiOzturk/DisplayVolumeKeys.git
cd DisplayVolumeKeys
./Scripts/install-app.shThe script builds and locally signs the app, installs it at /Applications/DisplayVolumeKeys.app, and launches it.
On first launch, enable DisplayVolumeKeys under:
System Settings → Privacy & Security → Accessibility
The app automatically registers itself as a login item on first launch. You can change that setting from its menu-bar menu.
Important
On a display that cannot reliably report its DDC state, both the mute key and volume zero use the safe lowest-volume fallback. They do not send the separate DDC hardware-mute command.
Some displays accept a hardware-mute command but fail to accept the corresponding standard unmute command. That can leave their audio stuck muted until mute is toggled with the display's physical controls.
DisplayVolumeKeys avoids that failure mode. It saves the previous level, writes speaker volume 0, and restores the saved level when unmuted. A faint output may remain when the display treats zero as its lowest amplifier level rather than true silence. This is an intentional safety tradeoff.
flowchart LR
Keys["Keyboard media keys"] --> Tap["CGEventTap"]
Tap --> State["Normalized volume state"]
State --> DDC["DDC/CI VCP 0x62"]
DDC --> Audio["External display audio"]
State --> HUD["Native-style volume HUD"]
- A
CGEventTapcaptures standard volume media keys while a compatible display is active. - The current audio output is matched to a physical display through Core Audio and I/O Registry metadata.
AppleSiliconDDCsends volume commands through Apple'sIOAVServiceI²C interface.- Valid DDC values are normalized; write-only displays use a locally cached level.
- The app shows the system OSD where level updates work and a small reusable AppKit HUD where they do not.
DDC behavior depends on the display firmware and whether the connection forwards monitor-control commands. Direct connections are generally more reliable than docks or adapters. DisplayLink and virtual-display transports commonly do not forward DDC.
If no compatible display is matched, DisplayVolumeKeys leaves normal macOS media-key handling untouched.
- Confirm the menu-bar item reports a connected display.
- Enable DisplayVolumeKeys in Accessibility settings.
- If an older local build was previously approved, toggle permission off and on.
- Choose Reconnect to Monitor from the menu-bar menu.
Reset only this app's Accessibility decision if needed:
tccutil reset Accessibility com.turabiozturk.DisplayVolumeKeys
open /Applications/DisplayVolumeKeys.appThe connection may not forward DDC, or the display may not implement MCCS speaker volume. Try a direct connection and verify that DDC/CI is enabled in the display's settings.
This is the safe behavior described above: the display treats volume zero as a non-silent minimum, while its hardware-mute command cannot be used safely without a reliable unmute path.
Build without installing:
./Scripts/build-app.shThe app bundle is written to build/DisplayVolumeKeys.app. Local builds use a stable designated requirement so rebuilding does not repeatedly invalidate Accessibility permission.
DisplayVolumeKeys has no telemetry and makes no runtime network requests. It observes only volume-related media keys while a compatible display is active.
Apple does not publish supported APIs for every DDC transport or for caller-controlled system OSD levels. The project therefore uses undocumented interfaces also used by established display-control applications. These may change in future system releases, and the app is not intended for the Mac App Store.
Issues and pull requests are welcome. Include only the compatibility information you intentionally choose to disclose. Never post serial numbers, system profiles, logs containing identifiers, or other private device metadata.
See CONTRIBUTING.md for development guidance.
- BetterDisplay, which inspired this focused utility
AppleSiliconDDCby Istvan Toth / waydabberMonitorControlfor its open-source DDC and media-key work- The VESA DDC/CI and MCCS standards
Source code and original project artwork are available under the MIT License.