randpaper - lightweight wallpaper & theme utility
A minimalist, high-performance wallpaper daemon for Wayland. randpaper keeps
your workspace fresh by assigning unique, randomized backgrounds to each of your
monitors at regular intervals and optionally syncing your terminal theme to
match the image pallete.
๐ Features
-
โก Performance: Written in Rust using
tokio. Scans your image directory once into memory (caching paths) to prevent disk I/O spikes, even with massive wallpaper collections. -
๐จ Dynamic Theming: Automatically extracts dominant colors from the current wallpaper and generates config files for Ghostty, Kitty, and Foot, keeping your terminal in sync with your desktop.
-
๐ฅ๏ธ Multi-Monitor: Assigns a unique random image to every active output simultaneously.
-
๐ ๏ธ Modular Backends: Works seamlessly with Sway and Hyprland (via
hyprctlor Sway IPC) and supports bothswaybgandswwwrenderers.
๐ Installation
Prerequisits
You need swaybg or (swww / awww) installed as the renderer.
# From source
# crates.io
Nix
Add as a flake input:
inputs = {
randpaper.url = "github:saylesss88/randpaper";
};
Install in environment.systemPackages or home.packages:
environment.systemPackages = {
inputs.randpaper.packages.${pkgs.stdenv.hostPlatform.system}.default
};
And add an exec for either hyprland or sway:
Hyprland Example:
wayland.windowManager.hyprland = {
settings = {
exec-once = [
# Standard Usage
"randpaper --time 15m /home/your-user/Pictures/wallpapers --backend hyprland --renderer swww"
# UWSM Usage
"uwsm app -- randpaper --time 15m /home/your-user/Pictures/wallpapers --backend hyprland"
];
};
}
Sway Example:
wayland.windowManager.sway = {
extraConfig = ''
# Default backend is Sway, default time is 30m
exec randpaper /home/your-user/wallpapers
'';
};
Note:
randpapermanages the renderer process for you. You do not need a separateexec-once = swaybg ...line in your config.
๐งพ Usage
# Defaults to changing every 30m using swaybg
# Custom: change every 5 minutes using Hyprland detection + SWWW transitions
swww/awww Transitions:
# Use fade transitions
# Use wipe transitions
Advanced Options
| Flag | Description | Default |
|---|---|---|
[DIR] |
Directory containing images | . |
-t, --time |
Time between changes(e.g., 15m, 1h) | 30m |
-b, --backend |
Detection backend: sway or hyprland |
sway |
-o, --outputs |
Specific outputs to target (Sway only) | Auto-discover |
-r, --renderer |
Renderer tool: swaybg or swww |
swaybg |
--transition-type |
swww transition: fade, wipe, outer |
simple |
-s, --transition-step |
swww transition step (0-100) | 90 |
-f, --transition-fps |
swww target frame rate for transitions | 30 |
--transition-type: Choose between (simple,fade,wipe,outer,inner,random)
NOTE: All transition options are ignored when using
--renderer swaybg.
๐จ Automatic Terminal Theming
randpaper automatically extracts a 16-color palette from your wallpaper and
generates theme files in ~/.config/randpaper/themes/.
To use them, add the include line to your terminal config:
Ghostty
File: ~/.config/ghostty/config
config-file = ~/.config/randpaper/themes/ghostty.config
Foot
File: ~/.config/foot/foot.ini (Place near end of file)
[main]
include=~/.config/randpaper/themes/foot.ini
Kitty
File: ~/.config/kitty/kitty.conf
include ~/.config/randpaper/themes/kitty.conf
Note:
randpaperattempts to live-reloadfoot(viaSIGUSR1) andkitty(viakitten) automatically when the wallpaper changes.
โญ๏ธ Cycling Wallpapers
You can force randpaper to cycle to the next image immediately by sending it
the SIGUSR1 signal.
Hyprland Config:
bind = $mainMod, N, exec, pkill -USR1 randpaper
Sway Config:
bindsym $mod+n exec pkill -USR1 randpaper
Shell:
โ๏ธ How it Works
- Startup: Caches all valid image paths (
jpg,png,bmp,webp) from the target directory into memory.
2 Loop: Every interval (e.g., 30m):
-
Queries active monitors via IPC.
-
Picks a random image for the primary monitor and extracts its color palette.
-
Generates theme files and triggers terminal reloads.
-
Spawns a non-blocking background process (
swaybgdaemon orswwwclient) to update the display. -
Sleeps efficiently until the next cycle.