Table of Contents
MacBook Pro XDR displays go up to 1600 nits but macOS caps you at ~500 in normal use. Fullbright removes that cap.
Menu bar app. Toggles XDR. Intercepts your brightness keys and gives you control over the full 1-1600 nit range. Uses Apple's private SkyLight framework to switch display presets.
I wanted something simple and open source that just did this one thing.
| Model | Chip | |
|---|---|---|
| MacBook Pro 14" | M1 Pro/Max+ | ✓ |
| MacBook Pro 16" | M1 Pro/Max+ | ✓ |
| Pro Display XDR | ✓ |
macOS 13.0+
Download the .dmg from Releases, drag to Applications. If macOS complains about unidentified developer, right-click > Open.
Lives in the menu bar. No Dock icon by default (changeable in settings).
- Click the icon in the menu bar
- Toggle XDR on
- Use brightness keys for 1-1600 nit range
Custom OSD shows current nits. Bottom half of the slider is SDR (1-500 nits), top half is XDR (500-1600). Turning XDR off restores your previous brightness and Night Shift state.
XDR on:
- Hardware brightness + linear brightness to 1.0
- Disable ambient light compensation (fights gamma changes otherwise)
- Disable Night Shift (breaks gamma precision)
- Clear gamma mods via ColorSync
- Spawn 2x2px
CAMetalLayerwindow inextendedLinearITUR_2020(triggers EDR headroom allocation) - 2s delay for EDR, then scale system gamma table and reapply at 60Hz
Brightness: Default gamma table read once at launch, R/G/B scaled with vDSP, reapplied 60x/sec. 30% lerp per frame for smooth transitions.
XDR off: Stop gamma timer, restore ColorSync, restore Night Shift if it was on, re-enable auto brightness, restore previous brightness.
Accessibility required for CGEventTap (brightness key interception). macOS prompts on first use.
Network access to fullbright.app for license validation and Sparkle update checks. Certificate pinned to ISRG Root X1.
git clone https://github.com/137137137/Fullbright.git
cd Fullbright/Fullbright
open Fullbright.xcodeprojSet your signing team, build. Xcode 15+, macOS 13.0+ SDK. Only dependency is Sparkle via SPM.
The source includes a trial/license system (14-day trial, license keys, server validation) used by the distributed version at fullbright.app. To build without it, strip the Authentication/ directory and the auth state checks in AppCoordinator, or hardcode auth state to .authenticated. XDR code has no licensing gates, it's all in Core/Controllers/.
Fullbright/
├── App/
│ ├── AppCoordinator Composition root
│ ├── AppDelegate Lifecycle, signal handlers, crash recovery
│ └── FullbrightApp SwiftUI entry
│
├── Core/
│ ├── Controllers/
│ │ ├── XDRController Enable/disable/brightness
│ │ ├── GammaTableManager Read, scale, 60Hz reapply
│ │ ├── BrightnessKeyManager CGEventTap, key interception
│ │ ├── DisplayServicesClient DisplayServices.framework
│ │ ├── NightShiftManager CBBlueLightClient
│ │ └── HDRWindow CAMetalLayer for EDR
│ ├── Protocols/
│ └── Utilities/
│
├── Authentication/
│ ├── Managers/ Trial, license, server
│ ├── Models/ State, data structs
│ └── Security/ Keychain, AES-GCM, cert pinning
│
├── Features/
│ ├── MenuBar/
│ ├── OSD/
│ ├── Settings/
│ ├── Onboarding/
│ └── Updates/
│
└── Components/
MVVM, @Observable, protocol DI via AppCoordinator. Display ops on @MainActor. CGEventTap callback is C convention, uses OSAllocatedUnfairLock for cross-thread state.
Private frameworks: SkyLight (display presets), DisplayServices (brightness), CoreBrightness (Night Shift).
Apple throttles pixel brightness at the firmware level if the panel overheats. Fullbright can't bypass that.
If the app crashes with modified gamma (screen looks washed out):
- Dirty-gamma flag is set before modifying, cleared after restore
- On next launch, if flag is set, gamma resets immediately
- SIGTERM/SIGINT handlers restore gamma on quit
Relaunch fixes everything. Nothing permanent.
PRs welcome. Open an issue first for anything big.
MIT