Introduction
Sunsetr is an automatic blue-light filter for Wayland compositors. It automates smooth color-temperature transitions from neutral to warmer tones, designed to reduce eye strain and improve sleep. Sunsetr automatically adjusts your displays based on your geolocation or manual time settings. It can also be used to persist the same color-temperature and gamma indefinitely, and can alternate between various user-defined presets. The controller can integrate with and automate changes in your shell or UI applications via IPC.
Getting Started
To get started, continue to the Installation guide, then follow the Quick Start guide to set up sunsetr with your compositor.
Project Links
- GitHub Repository: github.com/psi4j/sunsetr
- Issue Tracker: Report bugs or request features
- Discussions: Ask questions or share your setup
Installation
- Dependencies
- Build from Source
- Arch Linux (AUR)
- NixOS
- Other Distributions
- Verifying Installation
- Next Steps
Sunsetr can be installed through several methods depending on your distribution and preferences.
Dependencies
Optional for Hyprland Users
- Hyprland >= 0.49.0
- hyprsunset >= v0.2.0 (only if using the hyprsunset backend)
For Other Wayland Compositors
- Any Wayland compositor supporting
wlr-gamma-control-unstable-v1protocol - No external dependencies - uses native Wayland protocols
Build from Source
Installing
First, clone the repository:
git clone https://github.com/psi4j/sunsetr.git &&
cd sunsetr
Then install using cargo-make:
# Install cargo-make if you don't have it already
cargo install cargo-make
# Then install system-wide (requires sudo)
cargo make install
# Or install to ~/.local (no sudo)
cargo make install-local
Or install manually:
# Build with cargo
cargo build --release
# Then install manually
sudo cp target/release/sunsetr /usr/local/bin/
Uninstalling
If you used cargo make install:
cargo make uninstall
If you manually copied the binary:
sudo rm /usr/local/bin/sunsetr
Arch Linux (AUR)
sunsetr, sunsetr-git, and sunsetr-bin are available in the AUR:
sunsetr (Latest Version)
paru -S sunsetr
sunsetr-git (Development Version)
paru -S sunsetr-git
sunsetr-bin (Pre-compiled Binary)
paru -S sunsetr-bin
Recommendation: Use sunsetr for stability, or sunsetr-git if you want to help test the latest features.
NixOS
sunsetr is available in nixpkgs unstable.
NixOS Configuration
Add to your configuration.nix:
environment.systemPackages = with pkgs; [
sunsetr
];
Then rebuild your system:
sudo nixos-rebuild switch
Imperative Installation
For non-NixOS systems or user-level installation:
nix-env -iA nixpkgs.sunsetr
Install using nix-shell
Test sunsetr without permanently installing it:
nix-shell -p sunsetr
Using Flakes
A flake is available for those wanting to use the latest version from main without waiting for it to be added to nixpkgs.
Add sunsetr to your flake inputs:
{
inputs.sunsetr.url = "github:psi4j/sunsetr";
}
Then use it in your configuration:
{ inputs, pkgs, ... }:
{
# Install as a system package
environment.systemPackages = [
inputs.sunsetr.packages.${pkgs.system}.sunsetr
];
# OR with home-manager
home.packages = [
inputs.sunsetr.packages.${pkgs.system}.sunsetr
];
}
Other Distributions
Fedora / RHEL (Copr)
Coming soon! Copr repository support is planned.
Debian / Ubuntu
Coming soon! .deb packages are planned for Debian-based distributions.
Manual Installation (Any Distribution)
If your distribution isn't listed above, you can build from source:
-
Install Rust and Cargo (if not already installed):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -
Follow the Build from Source instructions above.
Verifying Installation
After installation, verify sunsetr is available:
sunsetr --version
You should see output with the current version number.
Next Steps
Now that sunsetr is installed, you can follow the Quick Start guide to continue setting things up.
Quick Start
This guide will help you get sunsetr running on your system in just a few minutes.
Once you've completed these steps, you can customize sunsetr with the Configuration options, set your precise Geographic location, or create Presets for different scenarios.
First Run
On the first run, sunsetr will automatically create a default configuration file at ~/.config/sunsetr/sunsetr.toml. The defaults are carefully tuned to provide an excellent experience out of the box:
sunsetr
You should see output like:
┣ Automatic location detection
┃ Detecting coordinates from system timezone...
┃ Detected timezone: America/Chicago
┃ Timezone mapping: Chicago, United States
┃ Coordinates: 41.8500°N, 87.6501°W
┃ Auto-detected location for new config: Chicago
┃
┣ Loaded default configuration
┃ Backend: Auto (Wayland)
┃ Mode: Time-based (geo)
┃ Location: 41.850°N, 87.650°W
┃ Night: 3300K @ 90% gamma
┃ Day: 6500K @ 100% gamma
┃ Update interval: 60 seconds
This will use your detected timezone to automatically populate coordinates for geolocation-based sunset and sunrise transitions. I recommend most users run the geo command to select more precise coordinates when using the geo transition mode.
Compositor Setup
Sunsetr works best when started automatically via the compositor. Here's how to set it up for different compositors.
Hyprland
Add this line near the beginning of your ~/.config/hyprland/hyprland.conf:
exec-once = sunsetr
Starting sunsetr early during compositor initialization ensures seamless color temperature management from the moment your desktop loads.
⚠️ WARNING:
If selecting the Hyprland or Hyprsunset backend:
- Do not use with hyprsunset's native config: I recommend removing
hyprsunset.confentirely or backing it up. (sunsetr will need full control for smooth transition times) - Make sure hyprsunset isn't already running if you want to use the Hyprland or Hyprsunset backends. You can check that a hyprsunset process isn't already running using btop or an alternative method.
- I recommend you disable hyprsunset's systemd service using
systemctl --user disable hyprsunset.serviceand make sure to stop the process before running sunsetr.
Niri
Add this line near the beginning of your ~/.config/niri/config.kdl:
spawn-at-startup "sunsetr"
Sway
Add this line to your ~/.config/sway/config:
exec sunsetr
River
Add this line to your ~/.config/river/init:
sunsetr &
Wayfire
Add this to your ~/.config/wayfire.ini in the [autostart] section:
[autostart]
sunsetr = sunsetr
Other Wayland Compositors
Consult your compositor's documentation for how to start background applications on startup.
Alternative Setup: Systemd Service
If you prefer systemd management over compositor-based startup:
systemctl --user enable --now sunsetr.service
Note: The systemd service file should be installed automatically with the listed Installation methods, or you can install it using cargo-make:
cargo make install-service
Running Sunsetr
Sunsetr runs in the foreground by default:
Foreground Mode (Default)
sunsetr
This is the recommended way to run sunsetr when starting it from compositor configs. The process stays attached to your compositor's lifecycle.
Background Mode
To run sunsetr as a background process:
sunsetr --background
This starts sunsetr in the background via the compositor. Useful if you're starting it manually from a terminal session and want to free up the terminal.
Debug Mode
To see detailed logging including sunrise/sunset calculations for geo mode:
sunsetr --debug
Verifying It's Working
After starting sunsetr, you can verify it's running and see its current state:
sunsetr status
You should see output showing:
Active preset: default
Current period: Night
State: stable
Temperature: 3300K
Gamma: 90.0%
Next period: 06:29:21 (in 4h54m)
Testing Your Setup
You may want to test various temperature and gamma settings to find your ideal values for night time using the test command:
sunsetr test <TEMPERATURE> <GAMMA>
This temporarily applies temperature and gamma settings. Press ESC or Ctrl+C to restore the display and try something new.
The first value controls the color temperature (1000-20000K) and the second value (10-200%) controls the gamma of the display. Try different values to find what works best for you:
sunsetr test 4000 95 # Warm, a little dimmer
sunsetr test 3300 90 # Warmer, dimmer
sunsetr test 2333 70 # Very warm, quite dim
Once you've found your desired values (night_temp, night_gamma), you can set them in ~/.config/sunsetr/sunsetr.toml or in a custom location. You can do this by manually editing the config, or by using the set command.
Next Steps
Now that sunsetr is running, you might want to:
- Configure location - Use
sunsetr geoto select your city for accurate sunrise/sunset times - Customize settings - Adjust temperatures, gamma values, and transition behavior
- Create presets - Set up different profiles for various scenarios
- Learn commands - Explore all available commands and options
Troubleshooting
If sunsetr isn't working as expected, check the Troubleshooting guide for solutions to common issues.
Configuration
Sunsetr is highly configurable through TOML files. This section covers all configuration options and how to customize sunsetr for your needs.
Configuration Files
Sunsetr creates its configuration at ~/.config/sunsetr/sunsetr.toml on first run.
Default Configuration
Here's the complete default configuration with all available options:
#[Backend]
backend = "auto" # Backend to use: "auto", "hyprland", "hyprsunset" or "wayland"
transition_mode = "geo" # Select: "geo", "finish_by", "start_at", "center", "static"
#[Smoothing]
smoothing = true # Enable smooth transitions during startup and exit
startup_duration = 0.5 # Duration of smooth startup in seconds (0.1-60 | 0 = instant)
shutdown_duration = 0.5 # Duration of smooth shutdown in seconds (0.1-60 | 0 = instant)
adaptive_interval = 1 # Adaptive interval base for smooth transitions (1-1000)ms
#[Time-based config]
night_temp = 3300 # Color temperature during night (1000-20000) Kelvin
day_temp = 6500 # Color temperature during day (1000-20000) Kelvin
night_gamma = 90 # Gamma percentage for night (10-200%)
day_gamma = 100 # Gamma percentage for day (10-200%)
update_interval = 60 # Update frequency during transitions in seconds (10-300)
#[Static config]
static_temp = 6500 # Color temperature for static mode (1000-20000) Kelvin
static_gamma = 100 # Gamma percentage for static mode (10-200%)
#[Manual transitions]
sunset = "19:00:00" # Time for manual sunset calculations (HH:MM:SS)
sunrise = "06:00:00" # Time for manual sunrise calculations (HH:MM:SS)
transition_duration = 45 # Transition duration in minutes (5-120)
#[Geolocation]
latitude = 30.267153 # Geographic latitude (auto-detected on first run)
longitude = -97.743057 # Geographic longitude (use 'sunsetr geo' to change)
Configuration Location
The configuration directory structure looks like this:
~/.config/sunsetr/
├── sunsetr.toml # Main configuration file
├── geo.toml # Optional: private geographic coordinates
└── presets/ # Optional: preset configurations
├── day/
│ └── sunsetr.toml
├── gaming/
│ └── sunsetr.toml
└── ...
For more information on how to use and manage presets, please see the preset command.
Configuration Management
Sunsetr provides CLI commands for reading and modifying configuration values:
sunsetr get- Read configuration valuessunsetr set- Modify configuration values
Hot Reloading
Sunsetr automatically detects and applies configuration changes without requiring a restart. Simply edit your configuration file, save it, and sunsetr will reload the new settings.
Watched files:
~/.config/sunsetr/sunsetr.toml- Main configuration~/.config/sunsetr/geo.toml- Private geo coordinates (if it exists)- Active preset configuration files
See Hot Reloading in Advanced Features for more details.
Next Steps
- Backend Selection - Choose the right backend for your compositor
- Transition Modes - Configure when and how color temperature changes
- Temperature & Gamma - Fine-tune display settings
- Smooth Transitions - Configure startup/shutdown animations
Backend Selection
Sunsetr supports multiple backends for different compositors. The backend determines how color temperature is applied to your display.
Available Backends
auto (Recommended)
backend = "auto"
Automatically detects your compositor and selects the best backend:
- Hyprland detected → Uses native Hyprland CTM backend
- Other Wayland compositor → Uses generic Wayland backend
- Detection fails → Returns error with suggestions
Recommendation: Use auto unless you have a specific reason to override. This ensures optimal backend selection and makes your config portable across different compositors.
hyprland (Hyprland CTM Manager)
backend = "hyprland"
Uses Hyprland's native Color Transformation Matrix protocol (hyprland-ctm-control-v1).
Pros:
- Most efficient for Hyprland
- Syncs CTM animations to display's refresh rate
- No external dependencies
- Direct protocol communication
Cons:
- Only works on Hyprland
- Hyprland's built-in CTM animations are not adjustable like sunsetr's smoothing using the
waylandbackend
Notes:
- Hyprland's CTM animations override sunsetr's smooth transitions. To use sunsetr's smooth transitions, use
backend = "wayland"instead - To disable Hyprland's CTM animations for instant temperature and gamma updates, set this in
hyprland.conf:render { ctm_animation = 0 }
hyprsunset (Hypsunset Controller)
backend = "hyprsunset"
Controls color temperature through Hyprland's hyprsunset CTM manager.
Pros:
- Works as Hyprland's team intends it to
- May integrate better with their other tools and ecosystem
Cons:
- Requires an additional dependency
- Less efficient than using the native CTM backend
- Process management overhead
wayland (WLR Gamma Control)
backend = "wayland"
Uses the standard Wayland wlr-gamma-control-unstable-v1 protocol.
Pros:
- Works on any Wayland compositor supporting the protocol
- Smooth transitions fully supported
- No external dependencies
Cons:
- Does not sync to dispay's refresh rate
Supported compositors: Hyprland, Niri, Sway, River, Wayfire, and most Wayland compositors.
Backend Selection Guide
| Use Case | Recommended Backend |
|---|---|
| Hyprland with smooth transitions | wayland |
| Hyprland with CTM animations | auto (uses native CTM) |
| Niri, Sway, River, other Wayland | auto (uses wayland) |
| Force Hyprland CTM for preset | hyprland |
| Force WLR gamma control for preset | wayland |
| Integrate with Hyprland ecosystem | hyprsunset |
| Portable config across compositors | auto |
Transition Modes
Transition modes determine when and how sunsetr adjusts color temperature. There are 4 time-based modes and a static mode. Time-based modes use these settings since they gradually transition from day to night values and back regularly at their specified times:
#[Time-based config]
night_temp = 3300 # Color temperature during night (1000-20000) Kelvin
day_temp = 6500 # Color temperature during day (1000-20000) Kelvin
night_gamma = 90 # Gamma percentage for night (10-200%)
day_gamma = 100 # Gamma percentage for day (10-200%)
update_interval = 60 # Update frequency during transitions in seconds (10-300)
1. geo (Geographic) - Recommended
transition_mode = "geo"
Automatically calculates sunrise and sunset windows based on your geographic location. This provides the most natural transitions that change throughout the year as seasons shift.
How it works:
- Uses your latitude and longitude to calculate solar elevation angles
- Determines precise sunrise and sunset times for your location
- Transitions windows match the calculated solar timing closely
- Automatically recalculates daily after midnight
Configuration:
transition_mode = "geo"
latitude = 40.7128 # Your latitude
longitude = -74.0060 # Your longitude
Note: When using geo mode, the sunset, sunrise, and transition_duration settings are ignored. These values are calculated automatically from your coordinates.
See Geographic Setup for detailed location configuration.
Manual Transitions:
For finish_by, start_at, and center modes, configure these settings:
sunset = "19:00:00" # HH:MM:SS format
sunrise = "06:00:00" # HH:MM:SS format
transition_duration = 45 # Minutes (5-120)
2. finish_by (Complete By Time)
transition_mode = "finish_by"
Ensures transitions complete exactly at the configured sunset and sunrise times.
Behavior:
- Transition begins
transition_durationminutes before the configured time - Reaches target temperature/gamma at the configured time
Example:
transition_mode = "finish_by"
sunset = "19:00:00"
transition_duration = 45
# Transition starts: 18:15:00
# Transition ends: 19:00:00 ← Configured time
When to use: You want night mode fully active at a specific time.
3. start_at (Begin At Time)
transition_mode = "start_at"
Transitions begin exactly at the configured sunset and sunrise times.
Behavior:
- Transition begins at the configured time
- Reaches target temperature/gamma
transition_durationminutes after
Example:
transition_mode = "start_at"
sunset = "19:00:00"
transition_duration = 45
# Transition starts: 19:00:00 ← Configured time
# Transition ends: 19:45:00
When to use: You want transitions to start at specific times.
4. center (Center On Time)
transition_mode = "center"
Transitions are centered around the configured sunset and sunrise times.
Behavior:
- Transition begins
transition_duration / 2minutes before - Reaches target at configured time (midpoint)
- Continues
transition_duration / 2minutes after
Example:
transition_mode = "center"
sunset = "19:00:00"
transition_duration = 60
# Transition starts: 18:30:00
# Midpoint: 19:00:00 ← Configured time
# Transition ends: 19:30:00
When to use: You want the transition midpoint to align with specific times.
5. static (Constant Values)
transition_mode = "static"
Maintains constant color temperature and gamma values without any time-based transitions.
When to use:
- You want consistent display settings 24/7
- You prefer manual control over automatic adjustments
- You're creating a preset for specific lighting conditions
- You need color accuracy (e.g., photo editing)
Configuration:
transition_mode = "static"
static_temp = 6500 # Constant temperature
static_gamma = 100 # Constant gamma
Note: When using static mode, all time-based settings (night_temp, day_temp, update_interval, etc ) are ignored.
Examples:
# Always neutral (daytime)
static_temp = 6500
static_gamma = 100
# Always warm (nighttime)
static_temp = 3300
static_gamma = 90
# Gaming/color-accurate mode
static_temp = 6500
static_gamma = 100
Temperature and Gamma Settings
Color temperature and gamma control how your display looks during different periods.
Color Temperature
Color temperature is measured in Kelvin (K) and affects the color "warmth" of your display:
- 2000-3000K: Very warm, orange-yellow (candlelight to incandescent)
- 3000-4000K: Warm white to neutral warm (halogen, sunrise/sunset)
- 4000-5000K: Neutral white to cool white (fluorescent)
- 5000-6500K: Daylight white (direct sunlight, overcast sky)
- 6500-8000K: Cool white to blue-white (bright daylight)
- 8000+K: Very cool, ice blue (this will wake you up)
Valid range: 1000-20000K
Gamma
Gamma controls the overall brightness and contrast of your display:
- 10-80%: Very dim, reduced contrast
- 80-90%: Dim, comfortable for night
- 90-100%: Normal brightness
- 100-150%: Bright, increased contrast
- 150-200%: Very bright, high contrast
Valid range: 10-200%
Note: Gamma values above 100% increase brightness but may wash out colors. Values below 80% may make the display difficult to read.
Day and Night Configuration
Configure separate temperature and gamma values for day and night periods:
# Daytime values (during day period)
day_temp = 6500 # Neutral, natural light
day_gamma = 100 # Full brightness
# Nighttime values (during night period)
night_temp = 3300 # Warm, reduced blue light
night_gamma = 90 # Slightly dimmed
Update Interval
Controls how frequently sunsetr updates color temperature during transitions:
update_interval = 60 # Seconds (10-300)
- Lower values (10-30s): More frequent updates for maintaining smoothness with a shorter
transition_duration(5-20min) - Higher values (60-120s): Less frequent updates for longer a
transition_duration(30-120min) - Default (60s): Good balance for most durations
Note: This only affects updates during sunset/sunrise transitions. Day and night periods are stable and don't update continuously.
Testing Values
Use the test command to temporarily try different temperature and gamma values:
# Test typical night-time settings
sunsetr test 3300 90
# Try different warmth levels
sunsetr test 4000 95 # Slightly cooler, brighter
sunsetr test 3000 85 # Warmer, dimmer
sunsetr test 2333 70 # Very warm, quite dim
Press ESC or Ctrl+C to restore previous settings.
Smooth Transitions
- Backend Compatibility
- Configuration
- How Smoothing Works
- Duration Settings
- Adaptive Interval
- Instant updates
Smooth transitions provide gradual fade effects when sunsetr starts up, reloads, switches presets, and shuts down.
Backend Compatibility
⚠️ Important: Smooth transitions are only supported on the Wayland backend. To use smoothing on Hyprland, set backend = "wayland".
Configuration
smoothing = true # Enable/disable smooth transitions
startup_duration = 0.5 # Seconds (0.1-60, 0 = instant)
shutdown_duration = 0.5 # Seconds (0.1-60, 0 = instant)
adaptive_interval = 1 # Base interval in milliseconds (1-1000)
How Smoothing Works
startup_durationdetermines the duration of the smoothing animation at startup, for preset switching, and configuration reloading.shutdown_durationdetermines the duration of the smoothing animation at shutdownadaptive_intervalcontrols the minimum granularity of the update interval that affects the perceived smoothness of the animation
Duration Settings
The duration determines how long transitions take:
# Fast (default)
startup_duration = 0.5 # Half second
shutdown_duration = 0.5
# Moderate
startup_duration = 5.0 # 5 seconds
shutdown_duration = 5.0
Adaptive Interval
The adaptive interval controls the base update interval during transitions:
adaptive_interval = 1
The adaptive interval uses an algorithm designed to adapt to your particular machine's capabilities. The default 1ms maximizes the granularity of the update interval automatically, allowing for the smoothest possible subsecond animations from current to target values. The current wlr-gamma-control-unstable-v1 protocol used by the Wayland backend relies on each compositor's implementation for gamma control updates. Each compositor will have their own performance characteristics for each type of CPU/GPU for this protocol.
Currently, niri and Hyprland handle the default settings quite well when used with Intel CPUs, and NVIDIA and AMD GPUs are noticeably less smooth. The performance characteristics of the smooth transitions are a result of the interaction between the compositor, the Linux kernel, and the GPU. Refining this further is out of the scope of this application, therefore, I've opened up the adaptive_interval as a configuration point to the user in case they'd like to attempt to refine things further to their taste.
When to adjust:
If you find that your mouse is lagging when the smoothing animation is occurring, you could try adjusting the base update interval a bit higher to reduce the granularity of the updates, but you will have to accompany this with a longer startup_duration and shutdown_duration if you want this to be a bit smoother. It's important to note that it is not necessarily the number or frequency of the updates causing the lag, but rather the way the compositor has to batch updates for rendering when sent to the kernel to then be processed by the GPU. Testing the smooth transitions on an old Intel CPU shows how smoothing works quite well when the process is streamlined between the compositor, kernel, and processor.
You may find success in further smoothing the animation with your compositor and processor by using settings similar to these:
#[Smoothing]
smoothing = true # Enable smooth transitions during startup and exit
startup_duration = 5 # Duration of smooth startup in seconds (0.1-60 | 0 = instant)
shutdown_duration = 5 # Duration of smooth shutdown in seconds (0.1-60 | 0 = instant)
adaptive_interval = 144 # Adaptive interval base for smooth transitions (1-1000)ms
Instant updates
If the smoothing animations don't meet your expectations or you want to decrease startup time, you can always disable smoothing to achieve the same results as something like wlsunset by setting:
smoothing = false
Correspondingly, if you want to disable Hyprland's native CTM animations, you can set this in hyprland.conf:
render {
ctm_animation = 0
}
Geographic Setup
- Interactive City Selection
- Testing other cities' coordinates
- Using Arbitrary Coordinates
- Privacy-Focused Geographic Configuration
- Next Steps
When using transition_mode = "geo", sunsetr automatically calculates sunrise and sunset times based on your geographic location. This provides the most natural transitions that adjust throughout the year as seasons change.
Interactive City Selection
The easiest way to configure your location is using the interactive city selector. This launches a fuzzy search interface where you can search a local database of 10,000+ cities worldwide by country or city name to populate your coordinates.
Example Usage
$ sunsetr geo
You'll see this interface:
┣ Select the nearest city for more accurate transition times
┃ Type to search, use ↑/↓ to navigate, Enter to select, Esc to cancel
┃
┃ Search: _
┃ ▶ A Coruna, Spain
┃ Aabenraa, Denmark
┃ Aachen, Germany
┃ Aalborg, Denmark
┃ Aalst, Belgium
┃ 100 of 10592 cities
After Selection
Once you select a city, sunsetr will:
- Show calculated times for today:
┣ Sun times for A Coruna, Spain (43.3713°N, 8.3960°W)
┃ Today's sunset: 18:09 (transition from 17:18 to 18:19)
┃ Tomorrow's sunrise: 08:27 (transition from 08:16 to 09:18)
┃ Sunset transition duration: 61 minutes
┃ Sunrise transition duration: 61 minutes
- Save coordinates to your configuration
- Change config to
transition_mode="geo" - Reload automatically with the new location
The coordinates are saved to the active configuration (default or an active preset):
~/.config/sunsetr/sunsetr.toml(default)
Testing other cities' coordinates
I realize we might want to test other cities' sunset/sunrise times and transition durations. Maybe we have to fly to another timezone for a special event and we want to get ahead of the jet lag and fix our sleeping schedule to their timezone.
Just run sunsetr geo. If you run this with --debug, you'll see an additional set of times in brackets [] to the right of the primary set of times. These times are in your autodetected local timezone. The primary set of times correspond to the selected city's coordinates' sunset/sunrise transition times. Ex:
┣[DEBUG] Solar calculation details for 2025-11-06:
┃ Raw coordinates: 35.6895°, 139.6917°
┃ Sunrise UTC: 21:07
┃ Sunset UTC: 07:41
┃ Coordinate Timezone: Asia/Tokyo (+09:00)
┃ Local timezone: America/Chicago (-06:00)
┃ Current time (Coords): 10:39:17
┃ Current time (Local): 19:39:17
┃ Time difference: +15 hours
┃ --- Sunrise (ascending) ---
┃ Civil dawn (-6°): 05:41:07 [14:41:07]
┃ Transition start (-2°): 05:58:53 [14:58:53]
┃ Sunrise (0°): 06:07:46 [15:07:46]
┃ Golden hour end (+6°): 06:34:25 [15:34:25]
┃ Transition end (+10°): 06:52:11 [15:52:11]
┃ Sunrise duration: 53 minutes
┃ Day duration: 9 hours 5 minutes (11-06)
┃ --- Sunset (descending) ---
┃ Transition start (+10°): 15:57:30 [00:57:30]
┃ Golden hour start (+6°): 16:15:16 [01:15:16]
┃ Sunset (0°): 16:41:55 [01:41:55]
┃ Transition end (-2°): 16:50:48 [01:50:48]
┃ Civil dusk (-6°): 17:08:34 [02:08:34]
┃ Sunset duration: 53 minutes
┃ Night duration: 13 hours 8 minutes (11-06 → 11-07)
┃
┣[DEBUG] Next transition will begin at: 15:57:30 [00:57:30] Day → Sunset
Using Arbitrary Coordinates
If the city selector (sunsetr geo) is not as precise as you'd like, you're welcome manually add coordinates to sunsetr.toml. I recommend using https://www.geonames.org/ or Google Earth to find your coordinates. North is positive, South is negative. East is positive, West is negative.
#[Geolocation]
latitude = 29.424122 # just switch these up
longitude = -98.493629 # `sunsetr --debug` to see the times/duration
Privacy-Focused Geographic Configuration
If you version control your configuration files (e.g., in a dotfiles repository), you may not want to expose your geographic location. sunsetr supports storing coordinates in a separate geo.toml file that you can keep private:
-
Create the geo.toml file in the same directory as your sunsetr.toml:
touch ~/.config/sunsetr/geo.toml -
Add geo.toml to your .gitignore:
echo "geo.toml" >> ~/.gitignore -
Run
sunsetr geoto populate it (or enter manual coordinates) -
Delete or spoof coordinates in
sunsetr.toml
Once geo.toml exists, it will:
- Override any coordinates in your main
sunsetr.toml - Receive all coordinate updates when you run
sunsetr geo - Keep your location private while allowing you to version control all other settings
Example geo.toml:
#[Private geo coordinates]
latitude = 40.7128
longitude = -74.0060
This separation allows you to share your sunsetr configuration publicly without accidentally doxxing yourself. geo.toml can also serve as a temporary place to store your coordinates when travelling.
⭐ Note: Your debug output will still print your coordinates on startup for debugging purposes, so be extremely careful when sharing your debug output online.
┣ Loaded default configuration
┃ Loaded coordinates from geo.toml
┃ Backend: Auto (Wayland)
┃ Mode: Time-based (geo)
┃ Location: 41.850°N, 87.650°W <--- ⭐ Careful!
┃ Night: 3300K @ 90% gamma
┃ Day: 6500K @ 100% gamma
┃ Update interval: 60 seconds
Next Steps
- Explore configuration options - Customize temperature and gamma values
- Create presets - Set up location-based presets for travel
- Learn about commands - See all available CLI commands
Hot Reloading
Sunsetr automatically detects and applies configuration changes without requiring a restart.
How It Works
Sunsetr watches these files for changes:
- Main configuration:
~/.config/sunsetr/sunsetr.toml - Geographic coordinates:
~/.config/sunsetr/geo.toml(if it exists) - Active preset configuration:
~/.config/sunsetr/presets/<active>/sunsetr.toml - Active preset coordinates:
~/.config/sunsetr/presets/<active>/geo.toml(if it exists)
When any watched file changes:
- Detects change
- Validates new configuration before applying
- Applies smooth transition to new values (if configured)
- Logs reload in debug output
Using Hot Reload
Simply edit your configuration and save:
# Start sunsetr
sunsetr
# In another terminal, edit config
vim ~/.config/sunsetr/sunsetr.toml
# Changes apply automatically on save!
What Gets Hot-Reloaded
Applies immediately:
- Temperature values (
night_temp,day_temp,static_temp) - Gamma values (
night_gamma,day_gamma,static_gamma) - Update interval (
update_interval) - Transition mode changes (
transition_mode) - Coordinates (
latitude,longitude) - Timing values (
sunset,sunrise,transition_duration) - Smoothing settings (
smoothing,startup_duration,shutdown_duration)
Requires restart:
- Backend changes (
backend)
Hot Reload with Custom Config
Hot reload works with custom configuration directories:
# Start with custom config
sunsetr --config ~/dotfiles/sunsetr/
# Edit custom config
vim ~/dotfiles/sunsetr/sunsetr.toml
# Changes apply automatically
Debugging Hot Reload
Use debug mode to see reload events:
sunsetr --debug
When configuration changes, you'll see:
┣[DEBUG] Reload state change detection:
┃ State: Day → Night
┃ Temperature: 6500 → 3300K
┃ Gamma: 100% → 90%
┃ Smooth transition: enabled
Limitations
- Backend changes require
sunsetr restart - Invalid configurations are rejected (keeps current config)
- Very rapid changes may be debounced (1-2 second window)
Preset System
- Preset Management
- Set up keyboard shortcuts for instant toggling:
- Creating Presets
- Advanced Preset Usage
- Next Steps
The preset system allows quick switching between different configuration profiles for different activities, times of day, days of the week, or locations.
Preset Management
The preset system can be used via the CLI, added to keybinds, or bash scripts:
# Show currently active preset
sunsetr preset active
# List all available presets
sunsetr preset list
# Switch to a specific preset
sunsetr preset day
sunsetr preset gaming
# Return to default configuration
sunsetr preset default
# Or call the same preset twice to toggle back to default
sunsetr preset day
sunsetr preset day # returns to default
Set up keyboard shortcuts for instant toggling:
Hyprland (hyprland.conf)
bind = $mod, W, exec, sunsetr preset day # toggle between day preset and default config
Niri (config.kdl)
Mod+W { spawn "sh" "-c" "sunsetr p day"; }
Creating Presets
Create preset files in ~/.config/sunsetr/presets/:
~/.config/sunsetr/
├── sunsetr.toml # Main/default config
├── geo.toml # Optional: private coordinates
└── presets/
├── day/
│ └── sunsetr.toml # Static day values
├── gaming/
│ └── sunsetr.toml # Gaming-optimized settings
├── weekend/
│ └── sunsetr.toml # Weekend schedule
└── london/
├── sunsetr.toml # London timezone
└── geo.toml # London coordinates
Each preset can have:
- Its own
sunsetr.tomlwith complete or partial configuration - Optional
geo.tomlfor location-specific presets - Any valid sunsetr configuration options
Example preset for static day mode (~/.config/sunsetr/presets/day/sunsetr.toml):
#[Backend]
backend = "auto" # Backend to use: "auto", "hyprland" or "wayland"
transition_mode = "static" # Select: "geo", "finish_by", "start_at", "center", "static"
#[Smoothing]
smoothing = true # Enable smooth transitions during startup and exit
startup_duration = 0.5 # Duration of smooth startup in seconds (0.1-60 | 0 = instant)
shutdown_duration = 0.5 # Duration of smooth shutdown in seconds (0.1-60 | 0 = instant)
adaptive_interval = 1 # Adaptive interval base for smooth transition (1-1000)ms
#[Static configuration]
static_temp = 6500 # Color temperature for static mode (1000-20000) Kelvin
static_gamma = 100 # Gamma percentage for static mode (10-200%)
Advanced Preset Usage
Day-of-Week Preset Switching:
Start sunsetr with different presets based on the day of week:
#!/bin/bash
# Start sunsetr with preset based on day of week
day=$(date +%u) # 1=Monday, 7=Sunday
if [ $day -ge 1 ] && [ $day -le 5 ]; then
# Weekdays: work schedule with earlier transitions
sunsetr preset weekday
else
# Weekends: relaxed schedule, sleep in
sunsetr preset weekend
fi
Then use this script in your compositor startup:
Hyprland:
exec-once = ~/.config/hypr/scripts/start-sunsetr.sh
Niri:
spawn-at-startup "~/.config/niri/scripts/start-sunsetr.sh"
Next Steps
- See preset examples - Ready-to-use preset configurations
- Learn about all commands - Explore the full command reference
- Configure settings - Fine-tune your preset configurations
Preset Examples
Ready-to-use preset configurations for common scenarios.
Static Day Mode
Perfect for daytime work or when you want consistent, neutral lighting.
~/.config/sunsetr/presets/day/sunsetr.toml:
#[Backend]
backend = "auto"
transition_mode = "static" # No time-based transitions
#[Smoothing]
smoothing = true
startup_duration = 0.5 # Quick fade-in
shutdown_duration = 0.5 # Instant shutdown
adaptive_interval = 1
#[Static configuration]
static_temp = 6500 # Neutral daylight
static_gamma = 100 # Full brightness
Usage:
sunsetr preset day # Enable day mode
sunsetr preset day # Toggle back to default
Gaming Mode
Optimized for color accuracy and maximum brightness.
~/.config/sunsetr/presets/gaming/sunsetr.toml:
#[Backend]
backend = "auto"
transition_mode = "static"
#[Smoothing]
smoothing = true
startup_duration = 0.5
shutdown_duration = 0.5
adaptive_interval = 1
#[Static configuration]
static_temp = 6500 # Accurate colors
static_gamma = 115 # Slightly boosted brightness
Usage:
sunsetr preset gaming # Enable gaming mode
Weekend Schedule
Different sunrise/sunset schedule for weekends.
~/.config/sunsetr/presets/weekend/sunsetr.toml:
#[Backend]
backend = "auto"
transition_mode = "finish_by"
#[Smoothing]
smoothing = true
startup_duration = 0.5
shutdown_duration = 0.5
adaptive_interval = 1
#[Time-based config]
night_temp = 2800 # Warmer for late nights
day_temp = 6500
night_gamma = 85 # Dimmer for comfort
day_gamma = 100
update_interval = 60
#[Manual transitions]
sunset = "22:00:00" # Stay up later
sunrise = "09:00:00" # Sleep in
transition_duration = 90 # Longer transitions
Usage:
# Friday night
sunsetr preset weekend
# Monday morning
sunsetr preset default
Location-Based Preset (Travel)
Separate coordinates for different locations.
~/.config/sunsetr/presets/london/sunsetr.toml:
#[Backend]
backend = "auto"
transition_mode = "geo" # Use London coordinates
#[Smoothing]
smoothing = true
startup_duration = 0.5
shutdown_duration = 0.5
adaptive_interval = 1
#[Time-based config]
night_temp = 3300
day_temp = 6500
night_gamma = 90
day_gamma = 100
update_interval = 60
#[Geolocation]
latitude = 51.508415
longitude = -0.125533
Usage:
# When traveling to London
sunsetr preset london
# After returning home
sunsetr preset default
Reading Mode
Extra warm, dimmed for late-night reading.
~/.config/sunsetr/presets/reading/sunsetr.toml:
#[Backend]
backend = "auto"
transition_mode = "static"
#[Smoothing]
smoothing = true
startup_duration = 0.5 # Slow transition
shutdown_duration = 0.5
adaptive_interval = 1
#[Static configuration]
static_temp = 2333 # Very warm
static_gamma = 75 # Quite dim
Usage:
sunsetr preset reading # Late-night reading mode
Minimal Blue Light
Maximum blue light reduction for sensitive users.
~/.config/sunsetr/presets/no-blue/sunsetr.toml:
#[Backend]
backend = "auto"
transition_mode = "static"
#[Smoothing]
smoothing = true
startup_duration = 0.5
shutdown_duration = 0.5
adaptive_interval = 1
#[Static configuration]
static_temp = 1000 # Extreme warmth
static_gamma = 70 # Reduced brightness
Usage:
sunsetr preset no-blue # Extreme blue light reduction
Command Reference
This section provides a complete reference for all sunsetr commands and global flags.
Command Cheat Sheet
| Command | Purpose | Example |
|---|---|---|
sunsetr | Start sunsetr | sunsetr |
sunsetr --background | Start in background | sunsetr --background |
sunsetr --debug | Start with debug output | sunsetr --debug |
sunsetr test <TEMP> <GAMMA> | Test temperature/gamma | sunsetr test 3300 90 |
sunsetr geo | Select city | sunsetr geo |
sunsetr preset <NAME> | Switch preset | sunsetr preset day |
sunsetr preset active | Show active preset | sunsetr preset active |
sunsetr preset list | List presets | sunsetr preset list |
sunsetr status | Show current state | sunsetr status |
sunsetr status --json | JSON output | sunsetr status --json |
sunsetr status --follow | Stream updates | sunsetr status --follow |
sunsetr get <FIELD> | Read config value | sunsetr get night_temp |
sunsetr set <FIELD>=<VALUE> | Write config value | sunsetr set night_temp=3500 |
sunsetr restart | Restart sunsetr | sunsetr restart --instant |
sunsetr stop | Stop sunsetr | sunsetr stop |
sunsetr --simulate ... | Simulate time window | sunsetr --simulate "..." "..." 60 |
Built-in Help
Sunsetr includes comprehensive built-in help:
# General help
sunsetr help # Show all available commands
sunsetr --help # Show detailed usage information
# Command-specific help
sunsetr help <COMMAND>
Commands
- test - Test color temperature and gamma values temporarily
- geo - Configure geographic location interactively
- preset - Switch between configuration presets
- status - Monitor current runtime state
- get & set - Read and modify configuration values
- restart & stop - Process management commands
- Global Flags - Flags available on main command
Next Steps
- Explore advanced features - IPC integration, simulation mode details
- Configure settings - Fine-tune your configuration
- Create presets - Set up different profiles
test
Test color temperature and gamma values temporarily without modifying your configuration.
Usage
sunsetr test <TEMPERATURE> <GAMMA>
Arguments
TEMPERATURE: Color temperature in Kelvin (1000-20000)GAMMA: Gamma percentage (10-200)
Examples
# Test typical night-time settings
sunsetr test 3300 90
# Try different warmth levels
sunsetr test 4000 95 # Slightly cooler, brighter
sunsetr test 3000 85 # Warmer, dimmer
sunsetr test 2500 80 # Very warm, quite dim
# Test day-time neutral values
sunsetr test 6500 100
Behavior
- Temporarily applies the specified temperature and gamma values
- Works with running instance - Sends values to the existing sunsetr process
- Press ESC or Ctrl+C to automatically restore previous settings
- Does not modify your configuration file
- Perfect for finding your preferred settings before committing them to config
geo
Configure geographic location through an interactive city selector.
- See Geographic Setup for more details on location configuration
Usage
sunsetr geo
Interactive Interface
The geo command launches a fuzzy search interface where you can:
- Type to search from 10,000+ cities worldwide
- Navigate with arrow keys (↑/↓)
- Select with Enter
- Cancel with Esc
- Search by city name or country
Examples
# Launch city selector
sunsetr geo
# Run sunsetr in debug mode to see detailed solar calculations
sunsetr --debug
# Or
sunsetr restart -d
Behavior
After selecting a city, sunsetr will:
- Display calculated times for today (sunrise, sunset, transition durations)
- Save coordinates to either:
~/.config/sunsetr/geo.toml(if it exists)~/.config/sunsetr/sunsetr.toml(otherwise)
- Change config to
transition_mode="geo" - Restart automatically with the new location
Notes
- Only works with
transition_mode = "geo" - See Geographic Setup for more details on location configuration
preset
Switch between configuration presets or view preset information.
- See Preset System for detailed preset configuration
Usage
sunsetr preset <PRESET_NAME>
sunsetr preset active
sunsetr preset list
Subcommands
preset <name> - Switch to a specific preset
sunsetr preset day # Switch to day preset
sunsetr preset gaming # Switch to gaming preset
sunsetr preset default # Return to default configuration
preset active - Show which preset is currently active
sunsetr preset active
Output:
gaming
preset list - List all available presets
sunsetr preset list
Output:
day
gaming
weekend
london
Toggle Behavior
Calling the same preset twice toggles back to default:
sunsetr preset day # Switches to day preset
sunsetr preset day # Switches back to default
Notes
- Presets are stored in
~/.config/sunsetr/presets/ - Each preset is a directory containing
sunsetr.toml(and optionallygeo.toml) - See Preset System for detailed preset configuration
status
Monitor the current runtime state of sunsetr via IPC.
Usage
sunsetr status
sunsetr status --json
sunsetr status --follow
sunsetr status --json --follow
Flags
--json, -j: Output in JSON format for scripting--follow, -f: Stream real-time state changes continuously
One-Shot Mode (Default)
Displays current state once and exits:
sunsetr status
Output:
Active preset: default
Current period: Sunset (32.19%)
State: transitioning
Temperature: 5470K → 3300K
Gamma: 96.8% → 90.0%
Next period: 17:49:25 (in 31m)
Follow Mode
Stream real-time state changes:
sunsetr status --follow
Events displayed:
- StateApplied: Temperature/gamma updates
- PeriodChanged: Period transitions (Day → Sunset → Night → Sunrise)
- PresetChanged: Preset switching
JSON Output
Machine-readable output for scripting:
sunsetr status --json
{
"active_preset": "default",
"period": "sunset",
"state": "transitioning",
"progress": 0.4637135,
"current_temp": 5016,
"current_gamma": 95.36286,
"target_temp": 3300,
"target_gamma": 90.0,
"next_period": "2025-11-11T17:49:25.000679991-06:00"
}
Use Cases
- Verify sunsetr is running correctly
- Monitor transition progress and timing
- Status bar integration (waybar, quickshell, etc.)
- Automating changes in your UI or other applications
IPC Socket
The IPC can be used directly with a custom client or you can use the status command in follow and json mode (sunsetr -f -j) using something like jq. The IPC is located at:
$XDG_RUNTIME_DIR/sunsetr-events.sock
# Typically: /run/user/1000/sunsetr-events.sock
Notes
- Requires sunsetr to be running
- See IPC Integration for advanced usage
get & set
Read and modify configuration values.
Using the get command
Read configuration values from sunsetr configuration files.
Usage:
sunsetr get <FIELD>...
sunsetr get all
sunsetr get <FIELD> --json
sunsetr get <FIELD> --target <PRESET>
Arguments:
FIELD: One or more configuration field namesall: Special keyword to retrieve all configuration values
Flags:
--json: Output in JSON format--target <PRESET>, -t <PRESET>: Read from specific preset (default:default)
Examples:
# Get specific field
sunsetr get night_temp
# Output: night_temp = 3300
# Get multiple fields
sunsetr get night_temp day_temp
# Output:
# night_temp = 3300
# day_temp = 6500
# Get all configuration
sunsetr get all
# JSON output for scripting
sunsetr get night_temp --json
# Output: {"night_temp": 3300}
# Full config as JSON
sunsetr get all --json
# Read from specific preset
sunsetr get night_temp --target gaming
sunsetr get night_temp -t day
Available Fields:
All fields from sunsetr.toml:
backendtransition_modesmoothingstartup_durationshutdown_durationadaptive_intervalnight_tempday_tempnight_gammaday_gammaupdate_intervalstatic_tempstatic_gammasunsetsunrisetransition_durationlatitudelongitude
Notes:
- Does not require sunsetr to be running
- Reads from configuration files directly
- Useful for scripting and automation
Using the set command
Modify configuration values with validation and safety features.
Usage:
sunsetr set <FIELD>=<VALUE>... # sets values in default config
sunsetr set --target <PRESET> <FIELD>=<VALUE>...
Arguments:
FIELD=VALUE: One or more field-value pairs to set
Flags:
--target <PRESET>, -t <PRESET>: Modify specific preset configuration (default:default)
Examples:
# Set single value
sunsetr set night_temp=3500
# Set multiple values
sunsetr set night_temp=3500 day_temp=6000
# Modify specific preset
sunsetr set --target gaming static_temp=4700
sunsetr set -t day static_gamma=110
Notes:
- Does not require sunsetr to be running
- Changes are written to configuration files
- If sunsetr is running, changes are applied immediately via hot reload
restart & stop
Process management commands for controlling the running sunsetr instance.
Using the restart command
Restart sunsetr with clean backend re-initialization.
Usage:
sunsetr restart
sunsetr restart --instant
sunsetr restart --background
Flags:
--instant: Skip smooth transitions for immediate restart--background: Restart in background mode
Examples:
# Normal restart with smooth transitions
sunsetr restart
# Skip smooth transitions for faster restarts
sunsetr restart --instant
# Restart in background mode
sunsetr restart --background
Behavior:
The restart command performs a clean stop-wait-start sequence:
- Stops current instance gracefully
- Waits for shutdown to complete
- Starts new instance with fresh backend initialization
- Applies smooth transitions (unless you run with
--instant)
When to Use:
- DPMS recovery: After manual display sleep/wake cycles on Hyprland
- Backend issues: If temperature/gamma stop working
Using the stop command
Gracefully shutdown the running sunsetr instance.
Usage:
sunsetr stop
Behavior:
- Graceful shutdown: Applies smooth shutdown transitions if configured
- Cleanup: Removes lock files and IPC socket
- Restoration: Returns display to configured day values
- Verification: Confirms process has terminated
Global Flags
These flags modify how sunsetr runs and are available on the main command.
--debug
Enable detailed debug output including solar calculations and state changes.
sunsetr --debug
Shows:
- Configuration loading details
- Detected/configured coordinates and timezone when using geo mode
- Precise sunset/sunrise timing with transition boundaries
- Real-time state changes and temperature updates
--background
Start sunsetr in the background via the compositor. Also compatible with the restart command.
sunsetr --background
sunsetr restart --background
Note: Not needed when starting from compositor config (exec-once, spawn-at-startup)
--config
Use a custom configuration directory instead of ~/.config/sunsetr/.
sunsetr --config ~/dotfiles/sunsetr/
Use cases:
- Portable configuration setups
- Multiple configuration profiles
- Custom dotfiles management
Behavior:
- All commands respect the custom directory
- Relative directory structure remains the same:
~/dotfiles/sunsetr/
├── sunsetr.toml
├── geo.toml
└── presets/
└── [your presets]
Examples:
# Start with custom config
sunsetr --config ~/dotfiles/sunsetr/
Note: Once started with --config, subsequent commands during that session automatically use the custom directory.
See Custom Config Directories for more details.
--simulate
Test sunsetr's behavior across arbitrary time windows without waiting.
sunsetr --simulate "<START>" "<END>" <MULTIPLIER>
sunsetr --simulate "<START>" "<END>" --fast-forward
sunsetr --simulate "<START>" "<END>" <MULTIPLIER> --log
Arguments:
START: Start time in format "YYYY-MM-DD HH:MM:SS"END: End time in format "YYYY-MM-DD HH:MM:SS"MULTIPLIER: Time speed multiplier (0.1x to 3600x)--fast-forward: Near-instant updates (maximum speed)--log: Save output to timestamped log file
Examples:
# Simulate evening to morning at 60x speed
sunsetr --simulate "2025-01-15 18:00:00" "2025-01-16 08:00:00" 60
# Fast-forward through time window
sunsetr --simulate "2025-01-15 18:00:00" "2025-01-16 08:00:00" --fast-forward
# Save output to log file
sunsetr --simulate "2025-01-15 18:00:00" "2025-01-16 08:00:00" 60 --log
# Creates: sunsetr-simulation-20250115-232140.log
Behavior:
- Simulates runtime during specified time window
- Faithfully reproduces actual behavior including temperature/gamma updates
- Shows all logging and state transitions
- Respects active preset and custom config directory
Use for:
- Testing geo calculations for specific dates
- Verifying transition timing
- Debugging time-dependent behavior
- Generating logs for bug reports
Note: At higher multipliers, actual time may exceed theoretical time due to system overhead.
Advanced Features
This section covers advanced features for power users, including various IPC integrations and using custom configuration directories.
Features
- IPC Integration - Real-time state monitoring and external integrations
- Custom Config Directories - Portable setups and multiple profiles
Next Steps
- Master all commands - Complete command reference
- Troubleshooting - Common issues and solutions
- Configuration reference - All configuration options
IPC Integration
Sunsetr provides a Unix socket-based IPC (Inter-Process Communication) system for real-time state monitoring and external integrations. The easiest way to interact with IPC is through the status command.
IPC Socket Location
The IPC socket is created at:
$XDG_RUNTIME_DIR/sunsetr-events.sock
Typically this resolves to:
/run/user/1000/sunsetr-events.sock
Event Types
The IPC socket broadcasts three types of events:
1. StateApplied:
Sent when temperature/gamma values are applied to the display.
JSON format:
{
"active_preset": "default",
"period": "sunset",
"state": "transitioning",
"progress": 0.4637135,
"current_temp": 5016,
"current_gamma": 95.36286,
"target_temp": 3300,
"target_gamma": 90.0,
"next_period": "2025-11-11T17:49:25.000679991-06:00"
}
2. PeriodChanged:
Sent when transitioning between periods (Day ↔ Sunset ↔ Night ↔ Sunrise).
Available periods:
day- Stable day periodsunset- Transitioning from day to nightnight- Stable night periodsunrise- Transitioning from night to daystatic- Static mode (no transitions)
3. PresetChanged:
Sent when switching presets.
Includes:
- New preset name
- Target temperature and gamma values
- Target Period
Status Bar Integration
Waybar Example:
Add to ~/.config/waybar/config:
{
"custom/sunsetr": {
"exec": "sunsetr status --json --follow | jq --unbuffered --compact-output 'if .event_type == \"preset_changed\" then {text: \"\\(.target_temp)K\", alt: .target_period, tooltip: \"Preset: \\(.to_preset // \"default\")\\nTarget: \\(.target_temp)K @ \\(.target_gamma)%\"} elif .event_type == \"state_applied\" then {text: \"\\(.current_temp)K\", alt: .period, tooltip: \"Period: \\(.period)\\nTemp: \\(.current_temp)K @ \\(.current_gamma)%\"} else empty end'",
"return-type": "json",
"format": "{icon} {text}",
"format-icons": {
"day": "",
"night": "",
"sunset": "",
"sunrise": "",
"static": ""
},
"on-click": "sunsetr preset day"
}
}
Note: This requires that you have a day preset set in your presets directory.
Custom IPC Clients
You can write custom clients that connect to the IPC socket directly.
Python Example
import socket
import json
def monitor_sunsetr():
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect("/run/user/1000/sunsetr-events.sock")
buffer = ""
try:
while True:
data = sock.recv(4096).decode('utf-8')
buffer += data
while '\n' in buffer:
line, buffer = buffer.split('\n', 1)
if line.strip():
event = json.loads(line)
event_type = event.get('event_type', 'unknown')
if event_type == 'state_applied':
period = event.get('period', 'unknown')
temp = event.get('current_temp', 0)
gamma = event.get('current_gamma', 0)
print(f"Period: {period}")
print(f"Temp: {temp}K")
print(f"Gamma: {gamma}%")
elif event_type == 'preset_changed':
preset = event.get('to_preset') or 'default'
target_period = event.get('target_period', 'unknown')
target_temp = event.get('target_temp', 0)
target_gamma = event.get('target_gamma', 0)
print(f"Preset changed to: {preset}")
print(f"Period: {target_period}")
print(f"Target: {target_temp}K @ {target_gamma}%")
elif event_type == 'period_changed':
to_period = event.get('to_period', event.get('period', 'unknown'))
from_period = event.get('from_period', 'unknown')
print(f"Period: {from_period} → {to_period}")
else:
# Unknown event type, print full event for debugging
print(f"Unknown event: {json.dumps(event, indent=2)}")
print("---")
except KeyboardInterrupt:
print("\nExiting...")
finally:
sock.close()
if __name__ == "__main__":
monitor_sunsetr()
Bash Example with socat
# Stream IPC events (all events, raw JSON)
socat UNIX-CONNECT:/run/user/1000/sunsetr-events.sock -
# Parse state_applied events with jq
socat UNIX-CONNECT:/run/user/1000/sunsetr-events.sock - | \
while read -r line; do
echo "$line" | jq -r 'select(.event_type == "state_applied") | "Period: \(.period) | Temp: \(.current_temp)K"'
done
Custom Config Directories
Use custom configuration directories for portable setups, testing, or multiple profiles.
Basic Usage
sunsetr --config ~/dotfiles/sunsetr/
Directory Structure
The custom directory must maintain the same structure:
~/dotfiles/sunsetr/
├── sunsetr.toml # Main configuration
├── geo.toml # Optional: geographic coordinates
└── presets/ # Optional: presets
├── day/
│ └── sunsetr.toml
└── gaming/
└── sunsetr.toml
All Commands Respect Custom Directory
Once started with --config, all subsequent commands use the custom directory:
# Start with custom config
sunsetr --config ~/dotfiles/sunsetr/
# All commands use custom directory
sunsetr preset gaming
sunsetr geo
sunsetr set night_temp=3500
sunsetr status
Note: You don't need to specify --config for subsequent commands during the same session.
Use Cases
Portable Configuration:
# Keep config with dotfiles
~/dotfiles/
└── sunsetr/
├── sunsetr.toml
└── presets/
# Use from dotfiles
sunsetr --config ~/dotfiles/sunsetr/
Testing Configuration:
# Create test config
mkdir -p ~/test-sunsetr
cp ~/.config/sunsetr/sunsetr.toml ~/test-sunsetr/
# Test without affecting main config
sunsetr --config ~/test-sunsetr/
Multiple Profiles:
# Work profile
sunsetr --config ~/configs/sunsetr-work/
# Home profile
sunsetr --config ~/configs/sunsetr-home/
# Travel profile
sunsetr --config ~/configs/sunsetr-travel/
Simulation with Custom Config:
sunsetr --config ~/test-config/ \
--simulate "2025-01-15 18:00:00" "2025-01-16 08:00:00" 60
Configuration Precedence
When using custom directories:
- Custom directory files take precedence
- Default directory is never read
- All operations affect custom directory only
Lock Files and IPC
Custom directories create separate lock files and IPC sockets:
# Default instance
$XDG_RUNTIME_DIR/sunsetr/sunsetr.lock
$XDG_RUNTIME_DIR/sunsetr/ipc.sock
# Custom instance (hashed path)
$XDG_RUNTIME_DIR/sunsetr/sunsetr-<hash>.lock
$XDG_RUNTIME_DIR/sunsetr/ipc-<hash>.sock
This allows multiple instances with different config directories to run simultaneously.
Troubleshooting
This guide covers common issues and their solutions. If you encounter a problem not listed here, please open an issue on GitHub.
Sunsetr won't start hyprsunset
- Ensure hyprsunset is installed and accessible if you're attempting to use sunsetr as a controller
- Make sure hyprsunset is not already running
- Be sure you're running on Hyprland
- Try using the Hyprland backend instead and consider removing hyprsunset as a dependancy.
Smooth transitions aren't smooth
- Ensure
smoothing = truein config - Try different
startup_durationandshutdown_durationsettings for smoother transitions - Adjust
adaptive_intervalfor extended durations - Check that no other color temperature tools are running
Display doesn't change
- If using the Hyprsunset backend, verify hyprsunset works independently:
hyprctl hyprsunset temperature 4000 - Check configuration file syntax
- Look for error messages in terminal output, follow their recommendations
- Use
"wayland"as your backend (even on Hyprland)
Still Having Issues?
If none of these solutions work:
- Search existing issues: GitHub Issues
- Open a new issue: Include debug output and system information
When reporting, please include:
- Sunsetr version
- Operating system and version
- Compositor and version
- Configuration file (redacted if needed)
- Debug output
- Steps to reproduce
Changelog
v0.11.0
- Process Management Commands: New
status,stop, andrestartcommandsstatuscommand displays current runtime state with JSON output supportstopcommand cleanly terminates running instances with verificationrestartcommand recreates backend with clean stop-wait-start sequence
- Background Operation: New
--backgroundflag for daemon-like operation - Extended Gamma Range: Gamma now supports 10-200% (previously 10-100%) for enhanced brightness control
- IPC Foundation: Unix socket-based IPC for real-time state broadcasting to external applications
- Critical Timing Fixes:
- Eliminated period transition boundary delays (transitions now occur exactly on time)
- Fixed time jump handling for NTP sync, sleep/resume, and manual time adjustments
- Corrected DST boundary handling in status output and transition schedules
- Fixed geo mode timezone mismatch causing delayed transition updates
- Reliability Improvements:
- Session-aware zombie process detection with automatic recovery after logout/reboot
- Test command instance isolation to prevent concurrent instance conflicts
- Multiple preset switching fixes and edge case improvements
- Geographic Data Improvements:
- Added Asia/Kolkata timezone support (Special thanks @acagastya)
- Fixed country/coordinate data accuracy (Special thanks @acagastya)
- Breaking Changes:
reloadcommand deprecated and removed (userestartor rely on automatic hot reloading)
v0.10.0
- Configuration Management Commands: New
getandsetcommands for CLI-based config managementgetcommand reads configuration values with JSON output supportsetcommand modifies configuration fields with validation and safety features
- Enhanced Preset System: Improved preset command with subcommands
preset activeshows the currently active presetpreset listdisplays all available presets
- Native Hyprland CTM Backend: Experimental Color Transformation Matrix support for Hyprland
- Comprehensive Help System: Built-in help command with detailed documentation for all features
- XDG Base Directory Support: Migrated state management to follow XDG specifications
- Improved Error Handling: Consistent error severity levels and better user guidance
- Interactive Configuration Warnings: Safer configuration editing with preset warnings
- Enhanced Logger: Colored severity levels and cleaner output formatting
- Bug Fixes:
- Fixed config directory handling with
--configflag - Resolved smooth transition issues during reload for Hyprland
- Fixed config directory handling with
v0.9.0
- Static Mode: New transition mode for maintaining constant temperature/gamma values
- Preset Management System: Quick switching between configuration profiles with
sunsetr preset - Hot Configuration Reloading: Automatic detection and application of config file changes
- Custom Config Directories: Support for portable configurations with
--configflag - Enhanced Smooth Transitions: Configurable startup/shutdown durations with adaptive algorithm
- Improved D-Bus Handling: Better recovery from system sleep/resume cycles
- Configuration Refactoring: Modular config system with better organization and validation
- CLI Architecture Improvements: Subcommand-based CLI with backward compatibility
v0.8.0
- D-Bus Sleep/Resume Detection: Automatically resumes from sleep using systemd-recommended D-Bus approach
- No Root Scripts: Sleep/resume detection now runs entirely in user space via D-Bus
- Nix Flake Support: Added official flake.nix with reproducible builds and development shell (Special thanks @scottmckendry)
- Display Hotplug Detection: Automatically detects and handles monitor connection/disconnection (Special thanks @scottmckendry)
v0.7.0
- Runtime Simulations: New
--simulatecommand for testing transitions and geo calculations - NixOS/Nix Support: Now available in nixpkgs unstable repository (Special thanks @DoctorDalek1963)
- Enhanced Logging System: Zero-cost abstraction via macros, improved performance and cleaner output formatting
- Progress Bar Improvements: Extracted reusable progress bar component with new EMA smoothing
- Geo Module Refactoring: Improved transition time calculations, fixed nanosecond precision timing bugs
v0.6.0
- Privacy-Focused Geo Configuration: New optional
geo.tomlfile for privately storing coordinates separately from main config - Smoother Startup Transitions: New Bézier curve for startup transitions and new minimum of 1 second
startup_transition_duration
v0.5.0
- Geographic Location Support: Complete implementation of location-based sunrise/sunset calculations
- Interactive City Selection: Fuzzy search interface with 10,000+ cities worldwide (
sunsetr geo) - Automatic Location Detection: Smart timezone-based coordinate detection with 466 timezone mappings
- Enhanced Transitions: Fine-tuned sun elevation angles and Bézier curves for more natural transitions
- Extreme Latitude Handling: Robust polar region support with seasonal awareness
- Comprehensive Timezone System: Multiple detection methods with intelligent fallbacks
- Geographic Debug Mode: Detailed solar calculation information for location verification
- Timezone Precision: Automatic timezone determination from coordinates for accurate times
- Default Geo Mode: New installations use geographic mode by default for optimal experience
- Live Reload Command: New
reloadflag to reload configuration without restarting - Interactive Testing: New
testcommand for trying different temperature/gamma values - Signal-Based Architecture: Improved process communication for reload and test commands
Version History
For the complete version history with all minor releases and patches, see the GitHub Releases page.