Frequently Asked Questions
1. Quit Lunar
2. Delete caches and preferences
~/Library/Application Support/Lunar
~/Library/Caches/Lunar
~/Library/Preferences/fyi.lunar.Lunar.plist
3. Download the latest version
4. Move the app to Applications
The app does not have any daemons or background services.
The 2 most common causes for this are Color Profiles and Firmware bugs in the monitor's DDC implementation.
Color Profiles
Because of a macOS bug in the Gamma API, your screen can go black then get back to normal after a few seconds.
There's no complete fix for this as it is a macOS bug, but you can lower the chances of it appearing using the following steps:
- Use a default color profile in System Preferences -> Displays
- Minimise future Gamma resets by disabling the HDR compatibility workaround from Advanced Settings
Technical explanation
This usually happens when custom color profiles are used, but it was reported on some default monitor profiles as well.
The bug is usually triggered when Lunar tries to reset the gamma tables to their default values by calling the
CGDisplayRestoreColorSyncSettings()
system method.
This should be a completely normal use case, and the call should simply do nothing if the gamma tables are already at their default values. But for unknown reasons, this API call will sometimes set all RGB Gamma tables to
0
and all colors will show up as black.
The flash you see comes from Lunar detecting this zero-gamma problem in the background, and applying a default Gamma table forcefully to avoid being stuck with a blacked out display.
Firmware bugs
Some monitors have firmware bugs and don't react well to DDC commands.
You may first try to open Advanced Settings and:
- Enable the Wait longer between DDC requests setting
- Disable the Re-apply brightness on screen wake setting
If the problem persists, you will need to disable DDC completely.
To do that, disable Hardware (DDC) controls from the Controls menu:
Lunar will fallback to adjusting brightness and contrast in software using Gamma values.
Notes about Gamma:
- Conflicts with other apps that use Gamma like f.lux so you have to quit them
- Night Shift is a good alternative as it doesn't use Gamma
- Can only lower the brightness, not increase it
- That's why you have to manually set the monitor brightness and contrast to maximum using its physical buttons
- Can't change the volume or input of the monitor
- Those features require DDC
Some monitors don't accept DDC commands (which Lunar uses to control brightness and volume).
Below are some possible causes for this issue.
HDMI port of the Mac Mini or MacBook Pro 2021
The HDMI port of these devices is blocking DDC requests without a known cause.
Using one of the Thunderbolt ports usually fixes this (through USB-C-to-HDMI cable, Thunderbolt hub, etc.).
What we know so far
These HDMI ports use an internal MCDP29xx chip to convert the HDMI signal to DisplayPort. That chip supports DDC, but the method we use to write the DDC commands to the monitor (
IOAVServiceWriteI2C
) fails when used through it.
There are other
WriteI2C
methods specifically for this chip inside theDCPAVFamilyProxy.kext
but they're not available to be used inside an app like Lunar.
HDMI-to-USB-C Cables
Some users report that DDC controls are blocked on specific monitors when using HDMI to USB-C cables and that switching to DisplayPort fixes their problem.
If possible, try a DisplayPort to USB-C cable.
Known to work cables
Smart Monitors
In most cases, DDC is blocked by a monitor setting that tries to take complete control of Brightness, Contrast or Volume.
Usually disabling those functions in the monitor settings will allow Lunar control brightness.
Below are some settings that are known to block DDC, grouped by monitor vendor.
Samsung
Note: DDC seems to be unresponsive on M7/M5 Smart Monitors even after disabling all the below features. There is no currently known solution for those monitors for now. You'll have to rely on Lunar's fallback controls.
- Disable Input Signal Plus
- Disable Magic Bright
- Disable Eye Saver Mode
- Disable Eco Saving Plus
- Disable Smart ECO Saving
- Disable PIP/PBP Mode
- Disable Dynamic Brightness
Dell
- Disable Uniformity Compensation
- Set Preset Mode to Custom or Standard to allow DDC
LG
- Disable Uniformity
- Disable Auto Brightness
- Set Picture Mode to Custom or Standard to allow DDC
BenQ
- Disable Bright Intelligence
- Disable Bright Intelligence Plus or B.I.+
- Set Picture Mode to Standard
Lenovo
- Disable Local Dimming
- Disable HDR
- Disable Dynamic Contrast
- Set Color Mode Custom
- Set Scenario Modes to Panel Native
Xiaomi Mi Monitor
- Disable Dynamic Brightness
- Set Smart Mode to Standard
PRISM
- Set On-the-Fly Mode to Standard to allow DDC
Others
- Disable Ambient Light Sensing
- Disable Dual DisplayPort
- Set Dynamic Picture Mode to Custom or Standard to allow DDC
- Set Color Presets to Custom or Standard to allow DDC
DDC blockers
Other cases where DDC will not work:
- TV working as monitor
- TVs don't support the
VESA Monitor Control Command Set
which is needed for sending DDC requests
- TVs don't support the
- DisplayLink
- DisplayLink uses proprietary drivers and while it has support for DDC, that functionality is not provided on macOS
- Lunar can control DisplayLink monitors using the Network Control feature
- HDMI port of the Mac Mini or MacBook Pro 2021
- The HDMI port of these devices is blocking DDC requests without a known cause
- Using the Thunderbolt connector fixes this (through USB-C-to-HDMI cable, Thunderbolt hub, etc.)
- Non-compliant hub/dock/adapter
- This is the most common issue and it can't be fixed in software
- Because most new Macs only have USB-C ports, most users use some kind of Thunderbolt hub or dock
- A lot of these hubs block DDC requests completely,
- If the hub supports more than one monitor, it usually forwards DDC requests to only one of them
- Here are some of the hubs that are known to work:
If Lunar doesn't fallback automatically to a working control mode, you can manually disable Hardware (DDC) controls from the Controls menu:
Lunar will fallback to adjusting brightness and contrast in software using Gamma values.
Notes about Gamma:
- Conflicts with other apps that use Gamma like f.lux so you have to quit them
- Night Shift is a good alternative as it doesn't use Gamma
- Can only lower the brightness, not increase it
- That's why you have to manually set the monitor brightness and contrast to maximum using its physical buttons
- Can't change the volume or input of the monitor
- Those features require DDC
The active monitor hotkey behaviour was changed because a lot of users requested it.
Basically, Ctrl+Brightness is now the way to control the external monitor as that is also how macOS works natively with Ultrafine and Thunderbolt monitors.
You can still go back to the old behaviour (mostly) by setting the Brightness keys adjust in other modes dropdown to Display with cursor:
Yes, it is mostly safe. The MacBook and Pro Display XDR have been designed to sustain higher than 500nits of brightness.
- macOS has a hard limit on the LED temperature and it will start lowering brightness forcefully way before it can do any damage
- If used with mostly non-white backgrounds/apps, only the really close-to-white pixels will actually reach 1600 nits, while the rest will hover below 1000 nits, so they'll have plenty of time to cool down
While sifting through macOS internals, I've discovered a lot of logic for temperature thresholds, local dimming zones to keep pixels at their most efficient brightness, and safe measures for high power usage.
Based on the current knowledge, I'd say this is pretty safe to use, given that the system will not allow you to go past unsafe limits.
LED lifespan
Yes, the lifespan of the LEDs will be lowered if XDR Brightness is used daily, but no one can say by how much.
That's just how LEDs work.
Heat degrades the junction between the semiconductors, causing less of the electrical current to be converted to light which will make LEDs dimmer over time.
How are LEDs affected by heat?
macOS will stop XDR when the heat passes a threshold, but if you find that the warning icon (⚠️) appears often in the menu bar you might want to use XDR less often.
Perfectly safe.
Sub-zero dimming darkens the colours in software after the lowest possible native brightness has been reached.
This can't cause any damage. It is equivalent to having dark colored or black pixels on the screen which is completely normal.
Lunar needs Accessibility permissions to listen for Media Keys (brightness and volume).
To make sure the permissions are enabled, launch System Preferences->Security & Privacy and check if Lunar is present and enabled in the Accessibility list.
If it is, try removing it and re-adding it just be sure it isn't a code signing issue.
If the keys still don't work, it's possible that:
- the F14/F15 as brightness keys option is disabled and the keyboard used doesn't send brightness key events
- enable the option on the Hotkeys page to allow Lunar to listen for default brightness key events
- the system permissions database is corrupted
- Launch Terminal.app and run the following command:
/usr/bin/tccutil reset All fyi.lunar.Lunar
- Reboot the system, launch Lunar again, then give Lunar permissions when it asks
- Launch Terminal.app and run the following command:
- your monitor doesn't support brightness/volume control
To check why brightness doesn't work, try running diagnostics by clicking on Open Lunar Diagnostics from the Lunar menu.
These are some of the cases where volume control is not available:
- If you see Software Control under your monitor name in Lunar
- If DDC is not responsive because of a non-compliant hub/dock/adapter (Lunar should prompt you about that)
- In this case you could try a different way to connect the monitor to your Mac
Yes, there's a hidden Round Corners setting on the built-in page.
Hover your mouse above the Auto Blackout button to make the setting appear, then scroll to change the setting:
Lunar needs Accessibility permissions to know where the windows of an app are placed.
To make sure the permissions are enabled, launch System Preferences->Security & Privacy and check if Lunar is present and enabled in the Accessibility list.
If it is, try removing it and re-adding it just be sure it isn't a code signing issue.
If offsets still don't work, it's possible that the system permissions database is corrupted (see fix here)
Unfortunately most monitors don't offer a way to hide their volume indicator OSD.
But Lunar offers a way to hide the macOS volume OSD so that at least you can see only one volume indicator.
Toggle the macOS Volume OSD setting to Hide inside the Lunar DDC menu
These are system settings and are not honored by any macOS app
Lunar (and all other apps) have to listen for brightness keys explicitly and the above settings don't have any effect on apps.
To disable Lunar's own media keys listener, uncheck F14/F15 as brightness keys on the Hotkeys page.
Note: not all keyboards have brightness keys that send non-F14/F15 key events.
Re-check the checkbox if brightness keys stop working after unchecking it.
Corrupted permissions database
First thing to try is to reset the System's permissions database.
Launch Terminal.app and run the following command:
Note: to run a command, paste the text in the Terminal and press Enter after that
/usr/bin/tccutil reset All fyi.lunar.Lunar
Then reboot the system and launch Lunar again.
If you get a message saying you don't have permissions to do the above, you can try resetting all permissions:
/usr/bin/tccutil reset All
Note: This will reset the permissions for all apps on the system.
And as a last resort, you can delete the whole permissions database using the following steps:
- Open Finder
- Go to
/Library/Application\ Support/com.apple.TCC
- Find
TCC.db
and move it to Trash
Then reboot the system and launch Lunar again.
Wrong app location
Where Lunar is launched from matters.
If you, for example, launched Lunar from Downloads and gave it permissions then, and then you moved it to Applications, then those permissions are not valid.
The macOS system stores permissions based on path and code signature.
You have to manually remove Lunar from the Accessibility list and add it again from the path you always launch it.
When a Mac device sends a command to a monitor through DDC, the whole system has to pause until the monitor replies.
Some monitors have very slow response times, and some don't respond at all.
If you enabled Refresh values from monitor settings or Smooth Transition, your system might freeze or be very slow because of one of those slow monitors.
Try disabling them from the Lunar UI if possible:
If your system is constantly freezing and you can't disable those options in the Lunar UI, try doing the following steps in Safe Mode:
- Make sure Lunar is not running
- Open Terminal.app
- Run the following commands
defaults write fyi.lunar.Lunar refreshValues 0
defaults write fyi.lunar.Lunar smoothTransition 0
defaults write fyi.lunar.Lunar brightnessTransition 0
- If the above doesn't work, you can reset Lunar settings by deleting the following file:
~/Library/Preferences/fyi.lunar.Lunar.plist
When the screens wake, Lunar forcefully re-applies the brightness and contrast values to all monitors to avoid a mismatch between what's in the UI and the actual monitor values.
This can cause lag if monitors take longer to respond or the monitors might behave in weird ways if the re-apply happens at the same time as the macOS display reconfiguration process.
You can disable this behaviour from Advanced Settings by unchecking the following checkbox (see the image below):
The Persistent IDs problem
For Lunar to be able to store settings for a monitor (name, brightness, input hotkey, etc.), it needs a way to uniquely identify that monitor through disconnects and reconnections.
The problem is that macOS doesn't always offer such a persistent ID.
So Lunar has to find workarounds, like reading the firmware data of the monitor, and computing a number from it that can be used as an ID.
The problem is that monitors of the same model usually have the exact same firmware data.
So if you, for example, use two monitors of the same kind, that computed ID is the same for both, so it is not unique and can't be used.
This leads to Lunar storing settings for a monitor with an ID that can:
- Disappear completely when the monitor is disconnected/sleeping
- This causes the monitor to be shown with default settings in Lunar the next time it connects
- Be reassigned to a different monitor
- This causes the settings to be assigned to the wrong monitor
Unfortunately this problem is not yet solvable, but I'm actively looking into anything that can help work around this limitation.
Display Data Channel
For most monitors, Lunar uses DDC (Display Data Channel) to read data or send commands directly to the monitor.
Examples of DDC commands:
set brightness to 30
(or any value between 0 and 255)set contrast to 15
(or any value between 0 and 255)set volume to 80
(or any value between 0 and 255)mute audio
switch input to HDMI 2
power off
(power on is not possible because a powered off monitor does not accept any commands)
After Lunar sends a DDC command, it's up to the monitor firmware to do something with that command.
Lunar can't know if, for example set brightness to 50
, did actually cause a brightness change in the monitor.
Some monitors don't accept DDC in some cases and can react in a few various ways to DDC commands:
- Ignore the command and do nothing
- e.g. you change the brightness value in Lunar but the monitor doesn't change at all
- Crash, lose video signal, turn off
- see here how to disable DDC in that case: Bad DDC issue
- Flicker green screen or weird colors
- disabling DDC is the only solution here as well: Bad DDC issue
Lunar also doesn't have any control on the monitor OSD so if brightness or volume appears as changing in both macOS and monitor OSD, that's just how your monitor works and can't be changed.
Apple DisplayServices
Apple vendored displays get special treatment as Lunar uses an implementation hidden inside macOS Display Services to control them natively. The list of Apple displays include:
- Pro Display XDR
- LG Ultrafine
- Thunderbolt Display
- LED Cinema (when connected via USB)
You can see when Lunar uses this method when you see Apple Native written under the monitor name in the Lunar window.
The DisplayServices method doesn't use DDC for brightness, it uses a proprietary protocol implemented by Apple through USB (as opposed to I2C for DDC).
Contrast, volume, input and power will still be controlled through DDC as DisplayServices only supports brightness changing.
Media Keys
Media Key events are sent when the checkbox for Use F1, F2, etc. keys as standard function keys on external keyboards is not checked and you press:
- F1/F2 (brightness)
- F10/F11/F12 (volume)
- Touchbar buttons for brightness and volume
- Touchbar slider for brightness when using Lunar's Sync Mode
Media Keys also need Accessibility permissions to be enabled for Lunar, while simple hotkeys can work without that.
Hotkeys
Simple hotkeys are what you can configure on Lunar's HOTKEYS page under the Function Keys section. These don't need special permissions.
If you haven't checked the checkbox for Use F1, F2, etc. keys as standard function keys on external keyboards, you will have to hold Fn
when pressing hotkeys that contain function keys like F1
, F2
etc.
Otherwise, something like Command
+F1
will actually send Command
+Brightness
which is a Media Key.
If you see the Software Controls tag under the monitor name in the Lunar UI, then Lunar can't use DDC to control this monitor.
Lunar can approximate a decrease in brightness by changing the software gamma tables to make the colors look darker.
This doesn't change the hardware brightness as DDC does and can only decrease brightness, not increase it.
You have to manually set the monitor's brightness and contrast (using the monitor physical buttons) to the highest possible values that look good for your monitor.
Yes, it is a known issue.
The MacBook display can increase the brightness on isolated local regions, which is the case when rendering HDR content.
The problem is that the system reports the highest brightness of the built-in display, not an average.
So even if the display contains only a small HDR-extra-bright-white square, Lunar receives that brightness from the system, and sends it to the external monitors.
You can read more about this here: https://prolost.com/blog/edr
Also, I have no idea how to fix this.
I tried to include the local cloud cover into the Location Mode algorithm but failed because of multiple reasons.
- Weather APIs are expensive
- Location Mode computes brightness and contrast every minute, doing an API request per minute, per user, would add up to a lot of requests
- I tried implementing some caching mechanism but it didn't help much
- Cloud Cover percentage can be quite irrelevant
- On some days, I would get a 95% cloud cover yet it was sunny where I stood
- This can happen if the weather station sensors are not close to your specific location
- Factoring in cloud cover is hard
- The way the current algorithm is written doesn't allow for adding additional factors easily
- A major refactor would be needed to make this work
If you can't use Sync Mode but would like your monitors to better react to the changes in the ambient light around you, you could try Sensor Mode.
If you use one of Lunar's adaptive modes (Sync, Location, Sensor), you can simply decrease the brightness/contrast of the brighter monitor until it looks the same as the other one.
You can use Shift
+Brightness
keys to adjust only the active monitor when the MacBook lid is closed, or use the Lunar UI otherwise.
Lunar will learn from that manual adjustment and try to match the monitors better in the future.
If the discrepancy appears again, just keep adjusting the brighter/darker monitor until Lunar has enough data to match a perfect curve.
This usually happens if you use identical monitors which have the exact same firmware data. Lunar tries to differentiate between them using multiple workarounds but it can still fail.
This can also happen if you use a Thunderbolt hub with two or more monitor connections. Most of these hubs forward DDC messages to only one of the monitors.
Finally, it's possible that the not-working monitor is connected through a non-compliant adapter.
Check the Non-compliant hub/dock/adapter section in this question for more details.
Yes, Lunar can do that using a feature called BlackOut.
Read more about it here: https://lunar.fyi/#blackout
This happens in rare cases and the cause is still unknown.
To fix the issue, restart your computer.
The system will revert automatically to the last known good resolution.
Usually after restarting, the orientation/resolution controls in Lunar start to work reliably.
Accessibility Permissions are needed for the following features:
- Media Keys (listening for brightness/volume key presses)
- App Presets (applying offsets based on what app is visible on each monitor)
Lunar has to tap into the global key events pipeline to know when a brightness or volume key has been pressed.
Brightness and volume key events are always global, not dispatched to the currently active app like other keys.
This means there's no way to listen to brightness/volume keys in a private way, but there's no privacy issue here as Lunar only cares about the following keys:
- Brightness Down (or
F1
) - Brightness Up (or
F2
) - Audio Mute (or
F10
) - Volume Down (or
F11
) - Volume Up (or
F12
)
All the other key events are ignored by Lunar.
If you don't need the Media Keys or the App Presets functions, you can disable them so Lunar doesn't ask for Accessibility Permissions.
Disabling App Presets
Disabling Media Keys
Looking at the % CPU usage is not a very accurate way of judging the app's efficiency.
Especially on M1, read more about it in this article: CPU percentage is misleading on M1 Macs by The Eclectic Light Company
Usually, you shouldn't look at the % CPU field, but at the CPU Time metric. By default Activity Monitor updates every 5 seconds, so even if the CPU % was at 20% for a few milliseconds, you'll still see it for 5 seconds.
Even with the Very often (1 sec) setting, the % CPU metric is still not best for judging app efficiency.
In the following case, from the time Lunar started running (1 day and 2 hours ago) until now, it only consumed about 3 minutes of CPU time.
That's an incredibly small amount of CPU power used for an app that has to:
- Constantly poll the MacBook display to check for brightness changes
- Listen for monitor connection/disconnection
- React to built-in display brightness changes in less than 100ms when there are a lot of small changes (see Dynamic Polling)
- Send low-level I²C messages to all monitors
- Check if visible app windows are included in the App Presets list
- Search for external light sensors on the network periodically
❯ echo "Lunar was launched "(soulver '(now - '(lsappinfo info -only kLSLaunchTimeKey Lunar | cut -d= -f2)') as time')" ago"
Lunar was launched 1 day 1 hour 50 min 5 s ago
❯ soulver '(3 min 25 s) is what % of (1 day 1 hour 50 min 5 s)'
0.220%
If you compare that to other frequently used utilities like the native macOS Messages.app for example, you'll see their CPU Time can be much higher than what Lunar uses.
For example in the same case, Messages was also launched 1 day and 2 hours ago and it already consumed 18 minutes of CPU time.
❯ echo "Messages was launched "(soulver '(now - '(lsappinfo info -only kLSLaunchTimeKey Messages | cut -d= -f2)') as time')" ago"
Messages was launched 1 day 1 hour 54 min 18 s ago
soulver '(18 min 35 s) is what % of (1 day 1 hour 54 min 18 s)'
1.196%
Your monitor has a non-standard DDC value range.
Adjust the max value in the DDC menu in Lunar as following:
- If the max value for brightness is
255
, set it to100
- If the max value for brightness is already
100
, set it to37
It's native
Lunar is a native app written in efficient Swift code. It doesn't use Electron or browser-based technologies.
Lunar is also open-source so you can check that for yourself: Github - alin23/Lunar
Checking for Electron
You can see if an app is Electron based by looking at its Frameworks folder.
For example, this is Discord containing Electron Framework.framework
:
Discord.app
based on Electron
And this is Lunar: