- Supports original HEIF/HEIC dynamic wallpaper files from macOS.
- Handles all schedule types: sun position, time-based, and dark/light mode.
- Automatic location detection via GeoClue 2.
- Set wallpapers once or continuously (daemon mode).
- Preview wallpaper transitions.
- Display wallpaper metadata.
- Extract all images and metadata as XML.
timewall requires libheif >= 1.19.7 for HEIF support. Ensure it is installed.
If building from source, you may also need libheif-dev, depending on your distribution.
Download the latest prebuilt binary and shell completions from the releases page.
Place the timewall binary in a directory included in your $PATH, e.g., /usr/local/bin.
Install via Cargo:
cargo install timewall
This repository provides a Nix flake, a nixpkgs overlay, and a Home Manager module.
Add timewall as an input to your flake.nix:
inputs.timewall.url = "github:bcyran/timewall";environment.systemPackages = [
  inputs.timewall.packages.${pkgs.system}.timewall
];nixpkgs.overlays = [
  inputs.timewall.overlays.default
]
environment.systemPackages = [
  pkgs.timewall
];services.timewall = {
  enable = true;
  wallpaperPath = ./wallpaper.heif; # optional, can be set at runtime
  config = {} # optional, see the configuration section
}Important
For sun position-based wallpapers, timewall needs your approximate location.
Ensure GeoClue 2 is available or configure your location manually.
See Configuration.
Set the wallpaper by running:
timewall set path/to/wallpaper.heif
This sets the wallpaper according to the current time or sun position, based on the wallpaper's schedule.
Note: This does not update automatically. To refresh, rerun the command or simply use timewall set (the last wallpaper is remembered).
See also: Where to find dynamic wallpapers.
To update the wallpaper automatically:
timewall set --daemon
This runs continuously, updating your wallpaper as time passes. It's recommended to run this at startup as a background process.
By default, daemon mode uses the last set wallpaper.
To change wallpapers, run timewall set path/to/new/wall.heif; the daemon will pick up the change.
To start timewall automatically, create ~/.config/systemd/user/timewall.service with:
[Unit]
Description=Dynamic wallpapers daemon
[Service]
Type=simple
ExecStart=timewall set --daemon
[Install]
WantedBy=default.target
Enable and start the service:
systemctl --user enable --now timewall.service
timewall will now start on boot and update your wallpaper throughout the day.
Preview wallpaper transitions with:
timewall preview path/to/wallpaper.heif
This cycles through all images in the wallpaper, simulating changes over the day.
Control preview speed with --delay (milliseconds) and loop with --repeat.
Extract all images and metadata as XML:
timewall unpack path/to/wallpaper.heif path/to/output/directory
Display all metadata:
timewall info path/to/wallpaper.heif
timewall uses a config file at $XDG_CONFIG_HOME/timewall/config.toml (typically ~/.config/timewall/config.toml).
A default config is created when you first run timewall set.
Sun position-based wallpapers require your approximate location.
By default, GeoClue 2 is used unless manually configured (see below).
Disable GeoClue by setting geoclue.enable = false.
If GeoClue cannot retrieve your location (e.g., offline), timewall uses the last known location by default.
Disable this fallback with geoclue.cache_fallback = false.
geoclue.prefer determines whether GeoClue is prioritized over manual location when both are available.
This is useful if you prefer automatic detection but want to fall back to manual configuration if GeoClue is unavailable.
geoclue.timeout sets the maximum time (milliseconds) to wait for GeoClue.
If exceeded, timewall falls back to manual location or fails, depending on geoclue.prefer.
Example:
[geoclue]
enable = true
cache_fallback = true
prefer = false
timeout = 1000Important
You may need to grant timewall access to location data in GeoClue configuration.
/etc/geoclue/geoclue.conf:
[timewall]
allowed=true
system=false
users=
On NixOS:
services.geoclue2.appConfig.timewall = {
  isAllowed = true;
  isSystem = false;
}Set your location manually in the location section.
By default, manual configuration is prioritized over GeoClue.
[location]
lat = 51.11
lon = 17.02lat and lon specify latitude and longitude.
If the default wallpaper setting does not work for your setup, or you wish to customize it, specify a custom command:
Example using feh:
[setter]
command = ['feh', '--bg-fill', '%f']
quiet = true
overlap = 0%f is replaced with the absolute path to the image.
Commands are NOT passed through the shell. To use shell features (e.g., environment variables, chaining), call the shell explicitly:
[setter]
command = ['bash', '-c', 'command_1 %f && command_2 %f']See also: Wallpaper setting commands.
By default, stdout and stderr are suppressed.
Set setter.quiet = false to change this.
setter.overlap defines the time (milliseconds) between starting a new command and terminating the old one.
Useful for commands that continue running after setting the wallpaper (e.g., swaybg), ensuring a smooth transition.
Set the update interval (seconds):
[daemon]
update_interval_seconds = 600- Original macOS dynamic wallpapers: If you have access to a Mac, you can copy the dynamic wallpapers directly. These files can also be found online, but links are omitted for legal reasons.
- Dynamic Wallpaper Club: Many user-created wallpapers, though quality varies. Few use sun position schedules effectively.
- Jetson Creative: Three free wallpapers and additional bundles for purchase.
- mczachurski/wallpaper: Two high-quality custom wallpapers.
Useful commands for setting wallpapers in various desktop environments.
%f is a placeholder for the image path.
# Light mode wallpaper
gsettings set org.gnome.desktop.background picture-uri file://%f
# Dark mode wallpaper
gsettings set org.gnome.desktop.background picture-uri-dark file://%f
# Lockscreen background
gsettings set org.gnome.desktop.screensaver picture-uri file://%f# Wallpaper
plasma-apply-wallpaperimage %f
# Lockscreen background
kwriteconfig6 --file kscreenlockerrc --group Greeter --group Wallpaper --group org.kde.image --group General --key Image %fUse kwriteconfig5 for Plasma 5.
The following resources were invaluable during timewall development:
