OLED burn-in protection for Linux laptops — a tiny, timer-driven pixel-shift for X11, plus documented idle-blank setup for X11 and Wayland.
Built on a ThinkPad P1 Gen7 (16" Samsung OLED, 3840×2400), but the output and resolution are auto-detected, so it works on any single-panel OLED laptop under X11.
OLED pixels age with use — static UI (panels, taskbars, terminals) burns in over months. Two cheap defenses:
- Pixel-shift — nudge the whole framebuffer a couple of pixels on a timer so no pixel renders the same content forever. This tool.
- Idle-blank — show black (OLED black ≈ pixels off ≈ zero light) after a few idle minutes. See docs/idle-blank.md.
Your panel's own ABL (automatic brightness limiting) caps luminance but does not shift pixels. On Linux there's no vendor pixel-shift (Lenovo Vantage's is Windows-only), so this fills that gap.
A systemd timer runs oled-shift every 10 min. On X11 it applies a small xrandr --panning
offset cycling through 8 positions. On Wayland/wlroots it is a deliberate no-op — wlroots has no
panning protocol and no compositor implements pixel-shift, so OLED protection there relies on the idle-blank.
yay -S oled-protect
sudo systemctl enable --now oled-shift.timergit clone https://github.com/ansulev/oled-protect && cd oled-protect
./install.shOverride via systemctl edit oled-shift.service:
| Var | Default | Meaning |
|---|---|---|
OLED_OUTPUT |
auto (eDP/LVDS) | output name — xrandr to list |
OLED_PADDING |
2 |
shift amplitude, px |
OLED_INTERVAL_MIN |
10 |
minutes between shifts |
systemctl status oled-shift.timer
journalctl -t oled-shift -n 5| X11 | Wayland (wlroots/labwc) | |
|---|---|---|
| pixel-shift | ✅ xrandr panning |
❌ no panning protocol — no-op |
| idle-blank | xfce4-screensaver / xscreensaver / xset |
swayidle |
DPMS caveat: on some Intel eDP panels (Meteor Lake) a full DPMS panel power-off can wedge the display PHY on resume. Prefer a black-framebuffer blank over DPMS-off, and keep DPMS disabled. See docs/idle-blank.md.
MIT © 2026 Angel Sulev