Persistent Wallpapers in Wayland
This guide explains how to set up persistent wallpapers (both video and static images) that automatically restore after reboot or login in Wayland.
This guide explains how to set up persistent wallpapers (both video and static images) that automatically restore after reboot or login in Wayland.
Overview
Unlike X11, Wayland doesn't have a built-in wallpaper system. Wallpapers are managed by compositor-specific tools or utilities like gSlapper. To make wallpapers persistent across reboots, you need to configure automatic startup.
Methods for Persistent Wallpapers
Method 1: Systemd User Service (Recommended)
Best for: Automatic restoration, process management, integration with system lifecycle
Advantages:
- ✅ Automatic startup on login
- ✅ Automatic restart on failure
- ✅ State restoration (video position, pause state)
- ✅ Process lifecycle management
- ✅ Logging via journalctl
- ✅ Proper Wayland environment handling
Setup:
- Create environment file:
mkdir -p ~/.config/gslapper
echo "WAYLAND_DISPLAY=$WAYLAND_DISPLAY" > ~/.config/gslapper/environment- Set initial wallpaper (saves state):
# Video wallpaper
gslapper -o "loop" DP-1 /path/to/video.mp4
# Press Ctrl+C to stop (state is saved automatically)
# Static image
gslapper -o "fill" DP-1 /path/to/image.jpg
# Press Ctrl+C to stop- Create service file:
mkdir -p ~/.config/systemd/userCopy the example service file:
cp /usr/lib/systemd/user/gslapper.service ~/.config/systemd/user/gslapper.serviceOr create manually (~/.config/systemd/user/gslapper.service):
[Unit]
Description=gSlapper Wallpaper Service
After=graphical-session.target
Wants=graphical-session.target
[Service]
Type=notify
ExecStart=/usr/bin/gslapper --systemd --restore '*'
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
EnvironmentFile=%h/.config/gslapper/environment
Environment=XDG_RUNTIME_DIR=%t
[Install]
WantedBy=default.target- Enable and start:
systemctl --user daemon-reload
systemctl --user enable --now gslapper.serviceFor per-monitor wallpapers:
Use the template service (gslapper@.service):
systemctl --user enable --now gslapper@DP-1.service
systemctl --user enable --now gslapper@DP-3.serviceSee also: Systemd Service Setup for detailed instructions.
Method 2: Shell Script in Startup Files
Best for: Simple setup, no systemd knowledge required, quick configuration
Advantages:
- ✅ Simple - just add to shell config
- ✅ Works on systems without systemd
- ✅ Full control over startup timing
Disadvantages:
- ❌ No automatic restart on failure
- ❌ No process management
- ❌ Manual state restoration needed
- ❌ Environment variables must be set manually
Setup:
- Add to shell config (
~/.bashrc,~/.zshrc, or~/.config/fish/config.fish):
For bash/zsh:
# Start gSlapper on login
if [ -z "$WAYLAND_DISPLAY" ]; then
export WAYLAND_DISPLAY=wayland-0 # Adjust if needed
fi
# Restore wallpaper (requires state file to exist)
gslapper --restore DP-1 &For fish:
# Start gSlapper on login
if not set -q WAYLAND_DISPLAY
set -gx WAYLAND_DISPLAY wayland-0
end
# Restore wallpaper
gslapper --restore DP-1 &- Set initial wallpaper first:
gslapper -o "loop" DP-1 /path/to/video.mp4
# Press Ctrl+C (saves state)Note: This method requires you to manually set the wallpaper once to create the state file.
Method 3: Compositor-Specific Startup
Best for: Integration with compositor configuration
Hyprland
Add to ~/.config/hypr/hyprland.conf:
exec-once = gslapper --restore DP-1Or with a delay to ensure Wayland is ready:
exec-once = sleep 1 && gslapper --restore DP-1Sway
Add to ~/.config/sway/config:
exec gslapper --restore DP-1River
Add to ~/.config/river/init:
gslapper --restore DP-1 &Niri
Add to ~/.config/niri/config.kdl:
spawn-at-startup {
gslapper --restore DP-1
}Or with a delay to ensure Wayland is ready:
spawn-at-startup {
sleep 1 && gslapper --restore DP-1
}Other Compositors
Check your compositor's documentation for how to run commands on startup. Most support exec, exec-once, or spawn-at-startup directives.
Advantages:
- ✅ Integrated with compositor
- ✅ Starts with compositor session
- ✅ Simple configuration
Disadvantages:
- ❌ Compositor-specific (not portable)
- ❌ No automatic restart on failure
- ❌ Limited process management
Method 4: Manual Restoration
Best for: Testing, one-time setup, troubleshooting
Usage:
# Restore from saved state
gslapper --restore DP-1
# Or set new wallpaper
gslapper -o "loop" DP-1 /path/to/video.mp4When to use:
- Testing wallpaper settings
- One-time wallpaper changes
- Troubleshooting state restoration
- Temporary wallpapers
State Management
How State Files Work
gSlapper automatically saves wallpaper state when you stop it (Ctrl+C) or when it exits:
State file location:
~/.local/state/gslapper/state-DP-1.txt
~/.local/state/gslapper/state-DP-3.txt
~/.local/state/gslapper/state.txt (for '*' output)Override with XDG_STATE_HOME:
# If set, uses $XDG_STATE_HOME/gslapper/ instead
export XDG_STATE_HOME="$HOME/.local/state"State File Format
State files use simple key=value text format (human-readable):
version=1
output=DP-1
path=/path/to/wallpaper.mp4
is_image=false
options=loop panscan=0.8
position=123.45
paused=0Key descriptions:
version- State file format version (currently 1)output- Monitor name (e.g., "DP-1", "HDMI-1")path- Full path to video or image fileis_image- Type indicator (0 = video, 1 = static image)options- GStreamer options string (e.g., "loop panscan=0.8")position- Video position in seconds (0.0 for images)paused- Pause state for videos (0 = playing, 1 = paused)
State File Security
gSlapper uses multiple mechanisms to ensure state file integrity and security:
Atomic Writes
State is written to a temporary file first, then renamed:
- Write to
state-<output>.txt.tmp - Verify write completed successfully
- Atomic rename:
state-<output>.txt.tmp→state-<output>.txt
Benefit: Prevents partial/corrupted state files if power loss or crash occurs during write.
File Locking
State operations use file locking (flock()):
- Exclusive lock during writes
- Prevents concurrent writes from multiple processes
- Blocks until lock is available
Benefit: Prevents state corruption when multiple gSlapper instances access same file.
File Permissions
State files are set to 0600 (user read/write only):
- Owner: Read/Write
- Group: No access
- Others: No access
Benefit: Protects wallpaper paths from other users on shared systems.
Manual State Management
Save state manually:
# Save for current wallpaper and exit
gslapper --save-stateRestore from state:
# Restore for specific output
gslapper --restore DP-1
# Restore from custom state file
gslapper --restore --state-file /tmp/my-state.txt DP-1Disable state saving:
# Prevent automatic state saving on exit
gslapper --no-save-state -o "loop" DP-1 /path/to/video.mp4Note: The --save-state flag is useful for:
- Testing state persistence
- Backing up current configuration
- Integrating with custom scripts
- Debugging state file issues
Multi-Monitor Setup
Same Wallpaper on All Monitors
Systemd service:
ExecStart=/usr/bin/gslapper --systemd --restore '*'Shell script:
gslapper --restore '*' &Different Wallpapers per Monitor
Systemd template service:
# Set wallpapers
gslapper -o "loop" DP-1 /path/to/video1.mp4 # Ctrl+C
gslapper -o "fill" DP-3 /path/to/image.jpg # Ctrl+C
# Enable services
systemctl --user enable --now gslapper@DP-1.service
systemctl --user enable --now gslapper@DP-3.serviceShell script:
gslapper --restore DP-1 &
gslapper --restore DP-3 &Comparison of Methods
| Method | Auto-start | Auto-restart | State Restore | Process Mgmt | Complexity |
|---|---|---|---|---|---|
| Systemd Service | ✅ | ✅ | ✅ | ✅ | Medium |
| Shell Script | ✅ | ❌ | ✅ | ❌ | Low |
| Compositor Config | ✅ | ❌ | ✅ | ❌ | Low |
| Manual | ❌ | ❌ | ✅ | ❌ | Very Low |
Troubleshooting
Wallpaper Not Restoring
Check state file exists:
ls ~/.local/state/gslapper/Verify state file content:
cat ~/.local/state/gslapper/state-DP-1.txtCheck if path still exists:
# From state file, verify the path is valid
test -f /path/to/wallpaper.mp4 && echo "Path exists" || echo "Path missing"Service Not Starting
Check service status:
systemctl --user status gslapper.serviceView logs:
journalctl --user -u gslapper.service -fVerify environment file:
cat ~/.config/gslapper/environment
# Should contain: WAYLAND_DISPLAY=wayland-0 (or wayland-1)Wayland Connection Issues
Find your WAYLAND_DISPLAY:
echo $WAYLAND_DISPLAYUpdate environment file:
echo "WAYLAND_DISPLAY=$WAYLAND_DISPLAY" > ~/.config/gslapper/environmentFor shell scripts, export before running:
export WAYLAND_DISPLAY=wayland-0
export XDG_RUNTIME_DIR=/run/user/$UID
gslapper --restore DP-1Best Practices
- Always set wallpaper manually first - This creates the state file
- Use systemd service for production - Best reliability and management
- Test state restoration - Verify
gslapper --restoreworks before enabling service - Keep wallpaper paths stable - Moving files breaks state restoration
- Use absolute paths - Relative paths may not resolve correctly
- Check logs regularly -
journalctl --user -u gslapper.servicefor issues
See Also
- Systemd Service Setup - Detailed systemd configuration
- Video Wallpapers - Video wallpaper guide
- Static Images - Static image guide
- Multi-Monitor Setup - Multi-monitor configuration
- Command Line Options - All available options
