Setting wallpaper from cron/systemd in X11 and Wayland…

I have a bash script (see below) that sets the wallpaper on X11/Waland. This script works fine from the command line.

However, running it from cron gets me the error:

I need either X11 or Wayland, got XDG_SESSION_TYPE="unspecified". WOT?

How do I make it detect that the main user is logged in on a graphical display?

The script:

#!/bin/bash

# Where you top level wallpaper directory is. Note that this work for sub directories too!
WALLPAPER_DIRECTORY=~/Pictures/wallpapers
WALLPAPER=$(find "$WALLPAPER_DIRECTORY" -type f | shuf -n 1)

# X11 code.
if [[ "$XDG_SESSION_TYPE" == "x11" ]]; then
    if ! command -v feh &> /dev/null; then
        echo "Command feh not found: go install it"
        exit 2
    fi
    /usr/bin/feh --bg-scale "$WALLPAPER"

# Wayland code.
elif [[ "$XDG_SESSION_TYPE" == "wayland" ]]; then
    # This requiers https://github.com/JaKooLit/Hyprland-Dots
    for cmd in "wallust swww"; do
        if ! command -v $cmd &> /dev/null; then
            echo "Command $cmd not found: go install it"
            exit 2
        fi
    done
    wallust run -q -s "$WALLPAPER" > /dev/null
    swww query || swww-daemon && swww img "$WALLPAPER" --transition-type random
    $HOME/.config/hypr/scripts/RefreshNoWaybar.sh

# Err… something went catastrophically wrong.
else
    echo "I need either X11 or Wayland, got XDG_SESSION_TYPE"=\"${XDG_SESSION_TYPE}\". WOT?""
    exit 1
fi
1 Like

Yes, I am aware that I could wrap the script with a while true; do … sleep 10m; done. This is not what I want. I want this to run via cron.

Why? Why not ¯\_(ツ)_/¯

1 Like

Try running as a systemd user timer and service.

That should be running in your login session and allow access to set the wall paper.

1 Like

I tried with these:

In /home/yg/.config/systemd/user/wallpaper-setter.service:

[Unit]
Description=Randomly changes the wallpaper for X11/Waland

[Service]
ExecStart=/home/yg/bin/wallpaper-setter.bash

The script is the same as above, no changes there.

In /home/yg/.config/systemd/user/wallpaper-setter.timer:

[Unit]
Description=Start wallpaper-setter.service

[Timer]
OnCalendar=10min

[Install]
WantedBy=timers.target

I ran the following commands:

✓ ; systemctl --user daemon-reload
✓ ; systemctl --user start wallpaper-setter.service
✓ ; journalctl --user --unit wallpaper-setter.service
Jul 07 10:36:46 nightwatch systemd[14052]: Started wallpaper-setter.service - Randomly changes the wallpaper for X11/Waland..
Jul 07 10:36:46 nightwatch wallpaper-setter.bash[226857]: I need either X11 or Wayland, got XDG_SESSION_TYPE="". WOT?
Jul 07 10:36:46 nightwatch systemd[14052]: wallpaper-setter.service: Main process exited, code=exited, status=1/FAILURE
Jul 07 10:36:46 nightwatch systemd[14052]: wallpaper-setter.service: Failed with result 'exit-code'.

Instead of XDG_SESSION_TYPE="unspecified", the environment variable has no value.

:thinking:

You could try adding systemctl --user import-environment XDG_SESSION_TYPE to your script for the systemd service.

1 Like

Thank you! This worked.