Weird monitor bugs people sent me in the last 5 years
I develop 🌕 Lunar, a macOS app for getting intelligent adaptive brightness on external monitors and controlling every aspect of your monitor using DDC and other obscure protocols.
I get tons of email about Lunar, especially after it became my full time “job” in 2021. A lot of those emails complain about Lunar bugs, but sometimes, after a good multi day chase, I conclude it’s actually a monitor bug and the user has to kind of.. deal with it.
”Buy another monitor” is never a good response, so I try to help and provide a workaround whenever I can.
But anyway, here’s a small collection of those bugs.
# Dual monitors swapped positions
You know how people get two identical monitors and place them side by side for a neat ultrawide-like look.
Well a lot of those people experience a very annoying behavior: After standby or restart, the monitors get swapped by the OS, so moving the cursor to the left monitor will actually appear on the right monitor, and vice-versa.
If the monitors also had some of the settings different, like resolution or color profile, those also get swapped.
This doesn’t happen for Apple vendored monitors like the Pro Display XDR in the above image, and you’ll see why in a minute.
# How monitor settings are stored
Whenever you arrange monitors, the system has to store those coordinates persistently and restore them when the monitor reconnects. In standby, the monitor is actually disconnected and disappears from the I/O Registry, so on system wake, it reconnects and the OS has to rearrange based on the stored settings.
To store something persistently, you need to have a way of identifying that monitor precisely. So the OS computes an UUID
from whatever it can find inside the data provided by the monitor.
That data is called the EDID structure and it contains things like vendor ID, week/year of manufacture, serial number etc.
# Why does this happen?
The problem comes from vendors who flash the same exact firmware with the same EDID to multiple monitors in the same batch.
Serial number is emphasized above especially because by definition it should be a unique number that increments with each monitor. Well it doesn’t. And it has nothing to do with the serial number you see on the back of the monitor or the box or wherever it’s placed.
So if you have the bad luck to buy two identical monitors, from the same batch, with the same EDID, then the OS will compute the same UUID for both.
That means that on reconnection, the monitors will look identical from the OS side, so the stored settings will have to be assigned randomly for each monitor. That will sometimes, not always, but deterministically when it's most annoying, cause the swapping bug.
And there’s nothing you can do to fix it.
# Workaround
The simplest solution is present in Lunar's Shortcuts (available without a Pro license):
- Swap Monitors to fix arrangement on setups with 2 monitors
- Fix Monitor Arrangement for setups with 3 or more monitors
For people that don't want to use Lunar, I wrote a simple CLI for swapping monitors here:
mac-utils/SwapMonitors.swift · GitHub
# Installation
- You can either install it from the Terminal:
export BINDIR=/usr/local/bin
export BINURL="https://github.com/alin23/mac-utils/raw/main/bin/SwapMonitors"
mkdir -p "$BINDIR" && \
curl "$BINURL" > "$BINDIR/SwapMonitors" && \
chmod +x "$BINDIR/SwapMonitors"
- Or use a Shortcut that does that automatically
The shortcut also provides a way to bind a hotkey, or run it from the menu bar.
# Usage
- Just run it and let the algorithm find the monitors that should be swapped: (either press the hotkey you assigned to the Shortcut, or run it from the command line)
⌁ ❯ SwapMonitors
Swapping Dell U2719D (2) [ID: 17] with Dell U2719D (1) [ID: 18]
External Display 1: x=4872.0 y=0.0 width=2560.0 height=1440.0
Moving to: x=1800.0 y=0.0
External Display 2: x=1800.0 y=0.0 width=3072.0 height=1620.0
Moving to: x=4872.0 y=0.0
- Or pass the IDs of the monitors to swap as arguments
⌁ ❯ SwapMonitors print-ids
IDs of monitors in order of appearance from left to right: [17, 19, 18]
Names of monitors in order of appearance from left to right: ["Dell U2719D (2)", "LG Ultrafine", "Dell U2719D (1)"]
⌁ ❯ SwapMonitors 17 18
Swapping Dell U2719D (2) [ID: 17] with Dell U2719D (1) [ID: 18]
External Display 1: x=1800.0 y=0.0 width=2560.0 height=1440.0
Moving to: x=4360.0 y=0.0
External Display 2: x=4360.0 y=0.0 width=3072.0 height=1620.0
Moving to: x=1800.0 y=0.0
# Monochrome HDR
While developing external monitor support for XDR Brightness, I needed a way to test it.
And since I don't have a 600nits+ monitor, I reached out to my friend István Tóth, the developer of BetterDisplay (and also a previous Lunar user who became a MonitorControl maintainer by porting Lunar's M1 DDC code to MonitorControl, long story).
When István turned on XDR Brightness on his Lenovo Creator Extreme, it was suddenly stripped of all color and everything became grayscale on it.
Other Lunar users also mentioned this issue on other specific monitor models, even before XDR Brightness was a thing. I thought I had an idea then on what could cause this, but this new data point dismantled my previous theory.
Some causes I can think of:
- The macOS ICC profile for that monitor computes a
0
chroma value in specific Gamma table configurations - The monitor internal color profile/preset is reverted to some default value on receiving a DDC command that's not handled correctly
- The grayscale filter of macOS is enabled somehow? ¯\_(ツ)_/¯
In the end, I have no idea what causes the problem, I simply disabled XDR for external monitors by default in Lunar, and made it opt-in.
# Blacking out
This is the bug that causes the most angry and panicky emails I get.
On receiving specific DDC commands, some monitors simply go black and stop responding to any user input.
Reconnecting the video cable doesn't do anything, the power button doesn't work, from the user perspective it looks like Lunar just bricked their monitors.
The fix is simple: unplug the power cable, and plug it back again
# What's happening?
I have an idea.
# Firmware bugs
Since Lunar doesn't do anything unusual (it just sends standard DDC commands for setting brightness and contrast), I assume the bug is in the DDC handler code inside the monitor controller firmware.
It's possible that either a specific series of bytes, or a burst of DDC messages, causes the firmware to crash, and maybe even enter in a tight loop since it doesn't seem to restart itself.
I keep an extensive FAQ with possible monitor features and settings that can break DDC and even cause this bug in specific setups: FAQ - The brightness or volume doesn't change
# Long cables
On rare occasions, the issue was actually being caused by a too long Thunderbolt cable.
Most people don't know that there's no such thing as a 6 meter Thunderbolt cable, not without built-in signal amplifiers or fiber optics and expensive converter chips.
So, expectedly, when using the data channel for DDC for longer than a few milliseconds, the video signal will drop completely, or revert to a much lower resolution and refresh rate.
# Custom color profiles
In other cases, the issue was a custom color profile, and the problem was actually caused by a macOS bug.
One Lunar user was an astronomer, and had a self-made observatory at home. He created a color profile that pushed most colors towards dark red, to keep his natural night vision when working.
But when Lunar adjusted the Gamma tables, the macOS color formula was sometimes reaching a point where every color computed to rgb(0, 0, 0)
.
The Lunar adjustments were completely normal and well within the documented range, and I found no way to predict on what values would the system reach that point.
I had to add a periodic timer that checks if the macOS color curve gets to 0, and reset all color adjustments, then forcefully disable that functionality for the user and let him know about it.
# Switching input just blinks the screen
The DDC protocol (or more exactly the Monitor Control Command Set (MCCS) specification), defines a command for switching monitor inputs.
So you might have:
- a MacBook on the Thunderbolt input of your monitor
- a PlayStation on the HDMI1 input
- a Raspberry Pi on HDMI2
And to switch between those, you can fiddle with the monitor buttons, or you can do that with handy keyboard shortcuts through DDC.
Because KVMs are expensive, I implemented that functionality in Lunar for people that don't really need the "keyboard switching" part of a KVM, but mostly the "video switching" part.
# So, where's the bug?
The thing is, some monitors lie about this functionality.
Even if the monitor reports that the VCP code 0x60
for Input Select is implemented, when any input value is sent, the monitor just blinks. By that I mean it goes black for a second, then returns to the previous image.
There's no software fix for these monitors.
# Mute command doesn't do anything
Kind of in the same vein as with the input switching bug above, the DDC Mute command just doesn't do anything on some monitors.
The odd thing is that the monitors do have a mute switch in their OSD, but it's not controllable by the VCP code 0x8D
for Audio Mute.
Instead, on some monitors, it seems that setting the volume to some non-standard value like 255
(or -1
if we flip from unsigned
to signed
integers), might affect the volume setting. On most monitors though, it doesn't do anything at all.
That's another workaround that got its own section in Lunar's settings because of how often it's encountered.