automatic wallpaper rotation on ubuntu 25.10

published: September 22, 2025

tl;dr

Quick Install:

mkdir -p ~/.local/bin && curl -o ~/.local/bin/wallpaper-rotate.sh https://michaelbommarito.com/wiki/wallpaper-rotate.sh && chmod +x ~/.local/bin/wallpaper-rotate.sh

Platform:Ubuntu 25.10 (Plucky Puffin) with GNOME Shell
Dependencies:None - uses only system utilities
Resource Impact:Minimal - runs once per hour
Features:Theme-aware, persistent state, systemd integration

rotate desktop wallpapers automatically on ubuntu 25.10 using a lightweight bash script and systemd timer - no external dependencies required.

overview

automatic wallpaper rotation keeps your desktop fresh and dynamic. this solution provides:

  • zero dependencies - uses only bash, gsettings, and systemd
  • theme awareness - supports both light and dark gnome themes
  • persistent state - continues rotation sequence across reboots
  • minimal resources - ~0% cpu, negligible memory usage
  • flexible scheduling - easily customize rotation frequency

perfect for ubuntu 25.10 (development branch) but compatible with any gnome shell 3.36+ system.

quick start

# 1. download and setup the rotation script
mkdir -p ~/.local/bin
curl -o ~/.local/bin/wallpaper-rotate.sh https://michaelbommarito.com/wiki/wallpaper-rotate.sh
chmod +x ~/.local/bin/wallpaper-rotate.sh

# 2. create wallpaper directory
mkdir -p ~/Pictures/Backgrounds
# add your images (png, jpg, etc)

# 3. download systemd units
mkdir -p ~/.config/systemd/user
curl -o ~/.config/systemd/user/wallpaper-rotate.service https://michaelbommarito.com/wiki/wallpaper-rotate.service
curl -o ~/.config/systemd/user/wallpaper-rotate.timer https://michaelbommarito.com/wiki/wallpaper-rotate.timer

# 4. enable automatic rotation
systemctl --user daemon-reload
systemctl --user enable --now wallpaper-rotate.timer

# 5. verify it's working
systemctl --user status wallpaper-rotate.timer

Info: the timer runs every hour by default. to change frequency, edit ~/.config/systemd/user/wallpaper-rotate.timer

how it works

rotation logic

the script maintains rotation state in ~/.wallpaper_rotate_state:

  1. discovers images in ~/Pictures/Backgrounds/ (png, jpg, jpeg, bmp)
  2. reads current index from state file (starts at 0 if missing)
  3. sets wallpaper for both light and dark themes
  4. increments index with modulo wrap-around
  5. saves state for next rotation

gnome integration

gnome 42+ maintains separate wallpaper settings:

  • picture-uri - light/default theme wallpaper
  • picture-uri-dark - dark theme wallpaper

the script updates both to ensure consistency across theme switches.

systemd scheduling

two systemd user units handle automation:

  • service (wallpaper-rotate.service) - executes the rotation script
  • timer (wallpaper-rotate.timer) - schedules hourly execution

Warning: ubuntu 25.10 note: this is the development branch. wallpaper rotation works identically to 24.04 lts but may encounter beta-related quirks.

installation

download files

all configuration files are available for download:

manual installation

  1. create the rotation script:
mkdir -p ~/.local/bin
vim ~/.local/bin/wallpaper-rotate.sh
# paste content from download link above
chmod +x ~/.local/bin/wallpaper-rotate.sh
  1. add your wallpapers:
mkdir -p ~/Pictures/Backgrounds
# copy your images here
  1. setup systemd units:
mkdir -p ~/.config/systemd/user
# create service and timer files (see downloads)
systemctl --user daemon-reload
  1. enable automation:
systemctl --user enable wallpaper-rotate.timer
systemctl --user start wallpaper-rotate.timer

configuration

change rotation frequency

edit ~/.config/systemd/user/wallpaper-rotate.timer:

# every 30 minutes
OnUnitActiveSec=30min

# every 2 hours
OnUnitActiveSec=2h

# daily at 9am
OnCalendar=daily
OnCalendar=09:00

# every hour during work hours
OnCalendar=Mon..Fri *-*-* 09..17:00:00

reload after changes:

systemctl --user daemon-reload
systemctl --user restart wallpaper-rotate.timer

change image directory

edit ~/.local/bin/wallpaper-rotate.sh:

WALLPAPER_DIR="$HOME/Pictures/MyWallpapers"

random selection

replace sequential logic with random selection in the script:

# instead of index-based selection
WALLPAPER="${IMAGES[$RANDOM % ${#IMAGES[@]}]}"

multiple profiles

create work/personal profiles with different schedules:

# work wallpapers (weekday business hours)
cp ~/.local/bin/wallpaper-rotate.sh ~/.local/bin/wallpaper-work.sh
# edit to use: WALLPAPER_DIR="$HOME/Pictures/Work"

# personal wallpapers (evenings/weekends)
cp ~/.local/bin/wallpaper-rotate.sh ~/.local/bin/wallpaper-personal.sh
# edit to use: WALLPAPER_DIR="$HOME/Pictures/Personal"

# create separate timers with OnCalendar scheduling

management commands

essential operations

actioncommand
rotate now~/.local/bin/wallpaper-rotate.sh
check statussystemctl --user status wallpaper-rotate.timer
view logsjournalctl --user -u wallpaper-rotate.service
stop rotationsystemctl --user stop wallpaper-rotate.timer
start rotationsystemctl --user start wallpaper-rotate.timer
disable permanentlysystemctl --user disable wallpaper-rotate.timer

monitoring

view next scheduled rotation:

systemctl --user list-timers wallpaper-rotate.timer

follow logs in real-time:

journalctl --user -f -u wallpaper-rotate.service

check rotation history:

# add logging to script first
echo "$(date): $WALLPAPER" >> ~/.wallpaper_history.log
tail -20 ~/.wallpaper_history.log

troubleshooting

wallpaper not changing

  1. verify timer is active:
systemctl --user is-active wallpaper-rotate.timer
  1. check for errors:
journalctl --user -u wallpaper-rotate.service -e
  1. test manually:
~/.local/bin/wallpaper-rotate.sh
  1. verify environment variables in script:
export DISPLAY=":0"
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus"

common issues

problemsolution
no such key 'picture-uri'gnome desktop schemas not installed
cannot autolaunch d-busadd display and dbus variables to script
permission deniedmake script executable: chmod +x
no images foundcheck wallpaper directory path and image formats
dark theme not updatingensure both picture-uri and picture-uri-dark are set

after system sleep

timers with Persistent=true catch up missed runs after wake. for immediate execution after wake:

# add to timer unit
OnActiveSec=30s  # run 30 seconds after wake

advanced features

notifications

add desktop notifications on wallpaper change:

# add to script after setting wallpaper
notify-send "Wallpaper Changed" "$(basename "$WALLPAPER")" \
    --icon=preferences-desktop-wallpaper

weather-based selection

choose wallpapers based on current weather:

weather=$(curl -s wttr.in/?format="%C" | tr '[:upper:]' '[:lower:]')
case "$weather" in
    *sunny*|*clear*)
        WALLPAPER_DIR="$HOME/Pictures/Sunny"
        ;;
    *rain*|*cloud*)
        WALLPAPER_DIR="$HOME/Pictures/Cloudy"
        ;;
esac

transition effects

gnome doesn’t support native transitions, but you can adjust display options:

# picture options: none, wallpaper, centered, scaled, stretched, zoom, spanned
gsettings set org.gnome.desktop.background picture-options 'zoom'

system validation

run complete system check:

# verify all components
for item in ~/.local/bin/wallpaper-rotate.sh \
            ~/.config/systemd/user/wallpaper-rotate.service \
            ~/.config/systemd/user/wallpaper-rotate.timer \
            ~/Pictures/Backgrounds; do
    [ -e "$item" ] && echo "✓ $(basename $item)" || echo "✗ $(basename $item) missing"
done

# count images
echo "images: $(find ~/Pictures/Backgrounds -type f \( -iname "*.jpg" -o -iname "*.png" \) | wc -l)"

# check timer
systemctl --user is-active wallpaper-rotate.timer && echo "✓ timer active" || echo "✗ timer inactive"

# show next run
systemctl --user list-timers wallpaper-rotate.timer --no-pager

compatibility

supported systems

  • ubuntu 20.04+ with gnome shell
  • fedora 33+ with gnome shell
  • debian 11+ with gnome shell
  • any distribution with gnome shell 3.36+

not compatible

  • kde plasma (use plasma-apply-wallpaperimage)
  • xfce (use xfconf-query)
  • other desktop environments (different apis)

alternative approaches

cron instead of systemd

add to crontab (crontab -e):

0 * * * * DISPLAY=:0 DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$(id -u)/bus" $HOME/wallpaper-rotate.sh

gnome extensions

  • wallpaper slideshow - native gnome extension
  • variety - feature-rich but heavier on resources

python implementation

for advanced features using gobject introspection:

import gi
gi.require_version('Gio', '2.0')
from gi.repository import Gio

settings = Gio.Settings.new('org.gnome.desktop.background')
settings.set_string('picture-uri', f'file://{wallpaper_path}')

performance impact

  • cpu: none (runs once per hour for <100ms)
  • memory: <1mb (bash script)
  • disk i/o: one read per rotation
  • battery: no measurable impact

resources

summary

this wallpaper rotation system provides a lightweight, reliable solution for keeping your ubuntu desktop fresh. with zero external dependencies and minimal resource usage, it’s the perfect set-and-forget enhancement for gnome shell users.

key benefits:

  • simple bash script with systemd integration
  • supports gnome’s dual-theme wallpaper system
  • maintains state across reboots
  • easily customizable scheduling and behavior
  • compatible with ubuntu 25.10 development branch
on this page