A workaround for adjusting screen color temperature on COSMIC Desktop Environment (Pop!_OS), until native gamma control is implemented (cosmic-comp#2059).
COSMIC DE doesn't implement wlr-gamma-control-unstable-v1 protocol yet, so tools like redshift, wlsunset, and gammastep don't work.
This package provides:
- Direct DRM manipulation tool to set color temperature
- Automatic daemon that applies settings when you switch TTYs (auto, force warm, force cool)
- Config file with live reload (changes apply instantly via inotify)
- Desktop notifications to remind you when to apply (optional)
- A daemon runs in the background monitoring TTY switches
- You press Ctrl+Alt+F3 (switches to TTY3) for automatic time-based temperature
- Daemon detects the switch and applies gamma (COSMIC releases DRM lock on TTY switch)
- You immediately press Ctrl+Alt+F2 (back to COSMIC)
- Total time: ~2 seconds, screen flickers briefly
You can also force a specific temperature:
- Ctrl+Alt+F4 (TTY4) - Force warm/night temperature (e.g. 3500K)
- Ctrl+Alt+F5 (TTY5) - Force cool/day temperature (6500K)
The gamma settings persist even after switching back to COSMIC!
sudo apt install build-essential libdrm-dev linux-libc-dev libnotify-binbuild-essential- gcc, makelibdrm-dev- DRM/KMS headers and librarylinux-libc-dev- Linux kernel headers (ioctl definitions)libnotify-bin-notify-sendfor desktop notifications (optional)
# Clone and build
git clone https://github.com/jjo/drm-colortemp.git
cd drm-colortemp
make
# Interactive installer (recommended)
sudo ./scripts/install_daemon.sh
# Or non-interactive
sudo make install
sudo make install-notifier # Optional: desktop notifications
sudo systemctl enable --now drm-colortemp-daemon
sudo systemctl enable --now drm-colortemp-notifier # Optional
# Use it! Press Ctrl+Alt+F3, then immediately Ctrl+Alt+F2Pre-built binaries are also available on the Releases page.
At 19:55 (if sunset is 20:00), you'll see:
🌙 Night Mode Ready
Press Ctrl+Alt+F3 then F2 to apply warm 3500K
Press Ctrl+Alt+F3 then Ctrl+Alt+F2. Done!
Just press Ctrl+Alt+F3 then Ctrl+Alt+F2 whenever you want to apply:
- Evening (after 20:00): Warm 3500K applied
- Morning (after 08:00): Neutral 6500K applied
Override time-based logic anytime:
- Ctrl+Alt+F4 then Ctrl+Alt+F2 - Force warm (NIGHT_TEMP)
- Ctrl+Alt+F5 then Ctrl+Alt+F2 - Force cool (DAY_TEMP)
You can also use the tool directly (requires TTY):
# From TTY (Ctrl+Alt+F3):
sudo drm_colortemp -d /dev/dri/card1 -t 3500Edit the config file (changes apply automatically via inotify, no restart needed):
sudo nano /etc/default/drm-colortemp.conf| Option | Default | Description |
|---|---|---|
| DEVICE | (auto) | DRM device — omit to auto-detect all cards with CRTCs |
| DEVICE1 … DEVICE8 | — | Explicit multi-card setup (see below) |
| DAY_TEMP | 6500 | Daytime temperature (Kelvin) |
| NIGHT_TEMP | 3500 | Nighttime temperature (Kelvin) |
| SUNSET_HOUR | 20 | When to switch to night mode (24h) |
| SUNRISE_HOUR | 8 | When to switch to day mode (24h) |
| MONITOR_TTY | 3 | Which TTY to monitor for auto-apply |
| WARM_TTY | 4 | TTY to force warm (night) temperature |
| COOL_TTY | 5 | TTY to force cool (day) temperature |
| NOTIFY_ENABLED | 0 | Enable desktop notifications (0/1) |
| NOTIFY_USER | "" | Username to send notifications to |
| NOTIFY_MINUTES_BEFORE | 5 | Minutes before sunset/sunrise to notify |
| VERBOSE | 0 | Enable verbose logging (0/1) |
By default (no DEVICE key set), the daemon auto-detects all DRM cards that have active CRTCs and applies temperature to all of them simultaneously.
For explicit control:
# Single card (legacy syntax, still supported)
DEVICE="/dev/dri/card1"
# Multi-card: apply to two GPUs at once
DEVICE1="/dev/dri/card0"
DEVICE2="/dev/dri/card1"Up to 8 devices (DEVICE1–DEVICE8) are supported. If both DEVICE and DEVICE1 are specified, DEVICE1 takes the slot 1 position.
- 6500K - Neutral daylight (default)
- 5500K - Slightly warm
- 4500K - Warm
- 3500K - Evening/sunset
- 2700K - Warm incandescent bulb
- 2000K - Very warm candlelight
# Install notification service (if not done during initial install)
sudo make install-notifier
# Set in /etc/default/drm-colortemp.conf:
# NOTIFY_ENABLED=1
# NOTIFY_USER="your_username"
sudo systemctl enable --now drm-colortemp-notifierSee NOTIFICATIONS.md for detailed documentation.
# Main daemon
sudo systemctl status drm-colortemp-daemon
sudo systemctl restart drm-colortemp-daemon
sudo journalctl -u drm-colortemp-daemon -f
# Notification daemon (if installed)
sudo systemctl status drm-colortemp-notifier
sudo journalctl -u drm-colortemp-notifier -f- Ensure daemon is running:
sudo systemctl status drm-colortemp-daemon - Check device path in config:
/etc/default/drm-colortemp.conf - Verify you're on the correct TTY when applying
- Check logs:
sudo journalctl -u drm-colortemp-daemon -f - Ensure you switch to TTY3 (not TTY1 or TTY2)
- Verify the tool works manually from TTY3
- Check logs for inotify errors
- Make sure config file exists:
ls -la /etc/default/drm-colortemp.conf - Inotify watches the directory, so any editor (nano, vim, etc.) should work
- Check
NOTIFY_ENABLED=1andNOTIFY_USERin config - Ensure
notify-sendis installed:sudo apt install libnotify-bin - Test manually:
sudo ./scripts/drm-colortemp-notify.sh your_username 3500 night
ls -la /dev/dri/
# Look for card0, card1, etc.The daemon auto-detects all cards with CRTCs when no DEVICE is configured. To target specific cards, set DEVICE1, DEVICE2, etc. in /etc/default/drm-colortemp.conf.
sudo make uninstall
# Config file is preserved at /etc/default/drm-colortemp.conf
# Remove manually if desired: sudo rm /etc/default/drm-colortemp.confNew in v2.0: Complete rewrite in Rust for improved safety and maintainability!
The Rust implementation (drm-colortemp-rs) provides:
- Memory safety - No segfaults, buffer overflows, or use-after-free bugs
- Thread-safe daemon - Proper signal handling and concurrent access
- Better error messages - Clear, actionable error output
- Same functionality - 100% feature parity with C version
- Smaller binary - ~1.8 MB stripped (vs ~3 MB for C version)
# Install Rust (if not already installed)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Build release version
cd drm-colortemp
cargo build --release
# Install binary
sudo cp target/release/drm-colortemp-rs /usr/local/bin/drm-colortemp
sudo cp drm-colortemp.service /etc/systemd/system/
sudo systemctl daemon-reload| Feature | C Version | Rust Version |
|---|---|---|
| CLI tool | ✅ | ✅ |
| Daemon mode | ✅ | ✅ |
| Config parsing | ✅ | ✅ |
| Inotify watch | ✅ | ✅ |
| Signal handling | ✅ | ✅ |
| Memory safety | ✅ Compile-time | |
| Binary size | ~3 MB | ~1.8 MB |
| Build time | ~5s | ~45s |
Both versions are supported. The C version remains available for systems without Rust.
The Linux DRM (Direct Rendering Manager) subsystem controls display output. Wayland compositors like COSMIC hold "DRM master" - exclusive control over the display. This prevents other processes from adjusting gamma.
When you switch to a text console (TTY3), COSMIC temporarily releases DRM master. Our daemon detects this switch and immediately applies the gamma settings before COSMIC reclaims control. When you switch back, the settings persist because COSMIC doesn't actively reset them.
- drm_colortemp - CLI tool using DRM ioctls to set gamma LUTs
- drm_colortemp_daemon - Monitors VT switches via
VT_GETSTATEioctl - drm_device - Shared DRM device detection and auto-fallback
- inotify - Watches config file directory for changes without polling
- systemd - Manages daemon lifecycle and logging
- notification system - Optional reminder service with desktop notifications
COSMIC needs to implement the wlr-gamma-control-unstable-v1 Wayland protocol for tools like redshift and wlsunset to work. Until then, direct DRM manipulation is the only option.
Track progress: pop-os/cosmic-comp#2059
Once COSMIC implements wlr-gamma-control-unstable-v1, you can switch to:
wlsunset- Automatic sunset/sunrise calculationgammastep- Redshift fork for Wayland- Native COSMIC settings
Until then, this provides a functional workaround!
Apache License 2.0 - see LICENSE
Color temperature algorithm based on Tanner Helland's work: http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
See CONTRIBUTING.md for contribution guidelines.
This is a workaround tool. The real solution is for COSMIC to implement gamma control protocol. Consider contributing to https://github.com/pop-os/cosmic-comp.