A minimal macOS menu bar app that toggles the system grayscale color filter with a single click or configurable global keyboard shortcut.
- Menu bar icon - Lucide-inspired eye icon (eye = color, eye-off/slashed = grayscale)
- One-click toggle - Click the icon to switch between color and grayscale
- Global keyboard shortcut - Configurable system-wide hotkey (set in Settings)
- Launch at Login - Optional auto-start via Settings
- System sync - Detects when grayscale is toggled externally (via System Settings)
- Lightweight - No dock icon, minimal memory footprint
Grab the latest .dmg from Releases, open it, and drag GrayscaleToggle.app to /Applications.
Note: Since the app is not notarized (no Apple Developer Program), macOS will show a warning on first launch. To bypass:
- Right-click the app → Open → click Open in the dialog, OR
- Run:
xattr -cr /Applications/GrayscaleToggle.app
Requires macOS 13+ and Xcode 15+.
git clone https://github.com/3sztof/menubar-grayscale-toggle.git
cd menubar-grayscale-toggle
make build
make run- Launch the app - a small eye icon appears in your menu bar
- Click the icon to open the menu, then click "Switch to Grayscale" / "Switch to Color"
- Open Settings to configure a global keyboard shortcut and Launch at Login
- The icon changes to indicate current state:
- Eye icon = color mode (normal)
- Eye-off icon (slashed) = grayscale active
| Target | Description |
|---|---|
make build |
Debug build |
make run |
Build and launch |
make release |
Release build |
make zip |
Release build packaged as .zip |
make clean |
Remove build artifacts |
- macOS 13.0 (Ventura) or later
- Xcode 15+ to build
- No App Sandbox (required for accessing system accessibility APIs)
This app uses undocumented APIs from MediaAccessibility.framework to read/write macOS color filter preferences, and libUniversalAccess.dylib to wake the universalaccessd daemon that applies the filter:
MADisplayFilterPrefSetType()- sets the filter type to grayscaleMADisplayFilterPrefSetCategoryEnabled()- enables/disables the system filter_UniversalAccessDStart()- kicks the daemon to apply changes immediately
This is the same mechanism that System Settings uses internally.
defaults write com.apple.universalaccess grayscaleis deprecated since macOS 11 and has no visible effectCGDisplayForceToGrayis broken on Apple Silicon Macs running macOS Ventura+- The MediaAccessibility approach works reliably on macOS 12+ (Intel and Apple Silicon)
The menu bar icon is based on the Lucide eye and eye-off icons, rendered programmatically as template images that adapt to light/dark menu bar appearance.
- KeyboardShortcuts (v2.0+) - Global keyboard shortcut recording and handling by sindresorhus
- Uses private/undocumented APIs - may break on future macOS versions (tested on macOS 13-15)
- Not suitable for Mac App Store distribution (private API usage)
- Requires running without App Sandbox
- brettferdosi/grayscale - reverse engineering of MediaAccessibility APIs
- Lucide Icons - menu bar icon design
- sindresorhus/KeyboardShortcuts - keyboard shortcut framework
MIT