Openbox: One wallpaper on every desktop

If you have several desktops and use them for specific tasks you may think how great would be to have a dedicated wallpaper on each, right? Sadly, Openbox doesn’t has this feature out of the box but there is a workaround.

You will need:

  • The feh package. Should be included in Mabox but if you need it then issue a:

    sudo pacman -S feh
    
  • A Shell Script (credit to damo at bunsenlab’s forum)

    #!/bin/bash
    #
    # Script to enable different wallpapers on each workspace and monitor.
    # Written by damo <damo@bunsenlabs.org> November 2015
    #
    # When first run, the script writes a configuration file template. The user can
    # then edit this and add the image filepaths.
    #
    # To run while logged in, add "wallpapersd &" to your autostart
    #
    # REQUIRES: 'feh'
    ###############################################################################
    
    WALLS_FILE="$HOME/.config/wallpapers.cfg"
    FEH_CMD="feh --bg-fill" # edit this, or wallpapers.cfg, to use a different feh command
    
    TXT=$(echo -e "# Add filepaths to the images to be set as backgrounds on each workspace."
        echo -e "# You can have an image set for each monitor."
        echo -e "#\n# Commands should be in the form:\n#"
        echo -e "#  $FEH_CMD 'path/to/image1(monitor 1)' 'path/to/image2(monitor 2)' etc\n#"
        echo -e "############################################################################"
        )
    
    if ! hash feh;then
        echo "feh is required to set the backgrounds. Install the feh package then re-run the script"
        exit 1
    fi
    
    if [[ ! -f $WALLS_FILE ]];then
        echo -e "$TXT\n" > "$WALLS_FILE"
        NUM_DESKTOPS=$(xprop -root _NET_NUMBER_OF_DESKTOPS | tail -c -2)
        for (( i=0; i < $NUM_DESKTOPS; i++ ));do
            echo "[DESKTOP_$i] $FEH_CMD " >> "$WALLS_FILE"
        done
        xdg-open "$WALLS_FILE"  # open cfg file for editing. Script must be restarted afterwards.
        exit
    else
        xprop -root -spy _NET_CURRENT_DESKTOP | (   # <-- this is the watching process
        while read -r;do
            CURR_DESKTOP=${REPLY:${#REPLY}-1:1}
            while read DTOP CMD;do
                VAL="[DESKTOP_$CURR_DESKTOP]"
                if [[ "$DTOP" = "$VAL" ]];then
                    eval $CMD
                fi
            done < "$WALLS_FILE"
        done
        )
    fi
    

    Copy/paste the code and save it in a know folder; don’t forget the execute permission, something like:

    chmod +x /myfolder/myscripts/wallpapers.sh

  • A config file. The script will create a template the first time you execute it but you can also create it yourself.

    The file must be ~/.config/wallpapers.cfg and the content made of one line for every desktop you have specifying the feh command and the wallpaper location and name. So, if you have three desktops it would be like, ie:

    [DESKTOP_0] feh --bg-fill '/usr/share/backgrounds/WallpaperForDesktop1.jpg'
    [DESKTOP_1] feh --bg-fill '/usr/share/backgrounds/WallpaperForDesktop2.jpg'
    [DESKTOP_2] feh --bg-fill '/usr/share/backgrounds/WallpaperForDesktop3.jpg'
    

    And so on.

  • Make the script run on every boot. Edit ~/.config/openbox/autostart and add the relevant line at the end, ie:

    /myfolder/myscripts/wallpapers.sh &

  • Close session or reboot your computer and you are done. Enjoy.

Being using this myself with zero issues for months; the wallpaper change is very fast .

7 Likes

Hi @M0nst3r

Nice to see someone else working with more than 1 display and setting wallpapers.
I tweaked mbwallpaper for this. Feh is great, indeed quick.

Why i tweaked mbwallpaper, because now i can also use jgwallpaperchanger for slideshow for all display’s. (me freak, with ton’s of anim pix).

Thought for your script :

What if you use the config from mabox mbwallpaper.conf to get image path.

Mbwallpaper :
CONFIG_DIR="$HOME/.config/mbwallpaper"
CONFIG_FILE="$CONFIG_DIR/mbwallpaper.conf"

if [ ! -f $CONFIG_FILE ]; then
cat <<EOF > ${CONFIG_FILE}
# Directory with wallpapers
wallpaper_dir=~/wallpapers
# Rotate time in seconds
interval=10
# Wallpaper setter program: nitrogen or feh
setter=feh
EOF
fi

From your script, it could randomly pick images from $wallpaper_dir for each monitor.

$setter instead of FEH_CMD=“feh --bg-fill”

from mbwallpaper:

case “$setter” in
nitrogen) command=“nitrogen --head=0 --set-scaled --save”;;
feh) command=“feh --bg-fill” ;;
pcmanfm) command=“pcmanfm -w” ;;
*) echo “Unknown wallpaper setter. Please check your config file $CONFIG_FILE”;exit 1;;
esac

feh $Image1 $image2 $image3 $image4 $etc...
When there are, for example 2 monitors, feh uses the first two images.


I don’t think feh needs to know how many display’s there are. It will find them in order.
(i only can test 2 monitors, don’t know if this is the same with more than 2)
Just feh $Image1 $image2 $image3 $image4 $etc... seems enough.


It’s a bit a quick response, but you probably get the picture…

:bird:

2 Likes

Hi @m0nster,

Sorry I couldn’t let go. Wonder what you think of it.


Reads wallpaper dir from mbwallpaper.conf.

The script can provide wallpaper to max 8 monitors. Random images.

The order of monitors depends on the X server settings.

#!/bin/bash
#
# Modified to read image paths from mbwallpaper configuration file.
# Config file: $HOME/.config/mbwallpaper/mbwallpaper.conf
#
# To run while logged in, add cript to your autostart in Openbox
#
# REQUIRES: 'feh'
#
###############################################################################

CONFIG_FILE="$HOME/.config/mbwallpaper/mbwallpaper.conf"
source "$CONFIG_FILE"

if ! hash feh; then
    echo "feh is required to set the backgrounds. Install the feh package then re-run the script"
    exit 1
fi

# Check if the wallpaper directory is specified in the configuration file
if [ -z "$wallpaper_dir" ]; then
    echo "Error: 'wallpaper_dir' is not specified in the configuration file."
    exit 1
fi

# Check if the wallpaper directory exists
if [ ! -d "$wallpaper_dir" ]; then
    echo "Error: Wallpaper directory '$wallpaper_dir' does not exist."
    exit 1
fi

# Pick 8 random images from the wallpaper directory
images=("$wallpaper_dir"/*)
selected_images=($(shuf -e "${images[@]}" -n 8))

# Set wallpapers using feh
feh --bg-fill "${selected_images[@]}"

:bird:

2 Likes

Another approuch. Fixed image for monitors.

I hope you appreaciate my input… :penguin:


How to use.

The first time, and to set images next time, use :

script.sh -set

It asks the full path to image for every image.

after that just run the script.


Adapt mbwallpaper.conf, Add IMAGEx.

$HOME/.config/mbwallpaper/mbwallpaper.conf

# Directory with wallpapers
wallpaper_dir=/path/to/image
interval=30
#interval2=10
# Wallpaper setter program: nitrogen or feh
setter=feh
IMAGE1=
IMAGE2=
IMAGE3=
IMAGE4=

script.sh

#!/bin/bash
#
# Modified to read image paths from a configuration file.
# Config file: $HOME/.config/mbwallpaper/mbwallpaper.conf
#
# To run while logged in, add script to your autostart in Openbox
#
# REQUIRES: 'feh'
#
###############################################################################

CONFIG_FILE="$HOME/.config/mbwallpaper/mbwallpaper.conf"
source "$CONFIG_FILE"

if ! hash feh; then
    echo "feh is required to set the backgrounds. Install the feh package then re-run the script"
    exit 1
fi

# Function to change image path interactively
change_image_path() {
    read -p "Enter path for $1 (current: ${!1}): " new_path
    if [ -n "$new_path" ]; then
        sed -i "s|^$1=.*|$1=$new_path|" "$CONFIG_FILE"
    fi
}

# Check if the user wants to change image paths
if [ "$1" = "-set" ]; then
    for var in IMAGE1 IMAGE2 IMAGE3 IMAGE4; do
        change_image_path "$var"
    done
    echo "Image paths updated. Run the script without -set to apply the changes."
else
    # Set wallpapers using feh
    feh --bg-fill "$IMAGE1" "$IMAGE2" "$IMAGE3" "$IMAGE4"
fi

:bird:

2 Likes

@muzqs Yes, I’m still chewing the idea of adapting that code with some changes (continuous file reading and full commands per line, for example, don’t fly in my book). I would start by defining desktops vs screens and how to approach it in the script. In my case I only have one physical screen with two virtual desktops. :thinking:

1 Like

Could I just clarify something please?

When sourcing the config file with these parameters below, then running the script in the background via autostart:

Rotate time in seconds

interval=nn

Is the wallpaper meant to change every nn seconds? I’ve tried this by manually running the script in the background and it changes the wallpapers once. Does a log out/log in change the behaviour or shall I run this script in a wrapper with a sleep interval?

Thanks for your efforts BTW.

Maybe he forgot the variable because, effectively, was imported (sourced) but not referred later on. :thinking: