update: enhanced loop function through notification tray icon control
update: updated to work with XFCE 4.10 and Cinnamon 1.9.1; the line testing for "Cinnamon 1.9.1" will have to be changed manually with each new version until I figure out how to handle that.
update: improved reliability of XFCE 4.10 detection.
To use it, just save it to your ~/bin directory, then cd to ~/bin and run
Code: Select all
chmod +x ./rwall
Let me know what you think!
Code: Select all
#!/bin/bash
#===============================================================================
#
# FILE: rwall
#
# USAGE: rwall [-h] [-v] [-d1] [-d2] [-d3] [-dd] [-l] | IMAGE DIRECTORY
#
# DESCRIPTION:
# rWall automatically detects the current user's environment then selects a
# random image from a directory. The script applies that image as a background.
# It supports GNOME3 (Gnome Shell, Unity, Cinnamon, Mate), KDE4, XFCE 4.10,
# and Openbox.
#
# KDE support requires some trivial setup via "Default Desktop Settings".
# Use the slideshow option, set "Change images every" to lowest, and select
# appropriate monitor folder created in the "set_kde" function.
#
# rWall may also work with other environments capable of using feh.
#
# TODO: fuse with pixwalker.sh to enable file traversing, Yad notification menu
# OPTIONS: see function ’usage’ below
# REQUIREMENTS: feh for Openbox usage, and yad (ppa:webupd8team/y-ppa-manager)
# BUGS: ---
# NOTES: when running KDE, a template folder is created as ~/.config/rwall
# AUTHOR: rockhazard, rockhazardz@gmail.com
# COMPANY: ---
# VERSION: 2.2 "Apu"
# CREATED: Thursday, Aug 7, 2013 12:30 AM
# REVISION: ---
# LICENSE: GPL 2.0
#===============================================================================
# CHANGELOG
# 2.2, Apu: XFCE 4.10 support, Cinnamon 2.0 support, updated KDE support
# 2.0, Krusty: Desktop environment auto-detection, KDE support, Mate 1.4 support
# 1.8, Lisa: Mate support, Yad support, multiple alternate image directories
# 1.5, Bart: GNOME3 support, wallpaper loop function
# 1.0, Homer: Change image directory via commandline
#===============================================================================
declare VERSION
declare BGDIR # result of wallpaper commandline argument test
declare WALLPAPER # result of randomized image selection
declare SETWALL # command to change background of current desktop
declare USERDIR # default image directory
declare INTERVAL # number of times to loop background
declare SPEED # number of seconds between background changes
declare LOOPDIR # directory returned by loop dialog
declare -a loopForm # array returned from yad loop request form
declare loopID # the slideshow's background process
declare DE # tag for current desktop environment
VERSION="v2.2 \"Apu\" (c) 2014, by rockhazard"
#HELP
usage() {
echo " rwall [-h] [-v] [-d1] [-d2] [-d3] [-dd] [-l] | IMAGE DIRECTORY"
echo
echo " --help .................. prints this help"
echo " --version, -v ........... prints version number"
echo " --directory1, -d1 ....... use first alternate image directory"
echo " --directory2, -d2 ....... use second alternate image directory"
echo " --directory3, -d3 ....... use third alternate image directory"
echo " --dir-dialog, -dd ......... choose an image directory via a GTK dialog"
echo " --file-dialog, -fd ......... choose an image via a GTK dialog"
echo " --loop, -l .............. loop background a given number of times"
echo " every given number of seconds"
echo
echo " KDE users: Please manually set wallpaper 'slideshow' option to the"
echo " ~/.config/rwall/kde/mon1 after first run. If you wish to use different"
echo " backgrounds on your monitors, just set each desktop to a different"
echo " template image from inside the rwall directory."
echo
}
# PRE-DEFINED DIRECTORIES
# change the directory below to the desired default image directory
USERDIR="$HOME/Pictures"
if [[ ! -d $USERDIR ]]; then
echo "Please choose a valid default image directory!"
exit
fi
dir_test() {
if [[ ! -d $BGDIR ]]; then
echo "Please provide a valid alternate image directory!"
exit
fi
}
# set alternate image directories below, then use options "-d1" through "-d3"
set_directory1() {
BGDIR="$HOME/Pictures"
dir_test
}
set_directory2() {
BGDIR="$HOME/Pictures"
dir_test
}
set_directory3() {
BGDIR="$HOME/Pictures"
# BGDIR="$HOME/Pictures/wallbase/sexy/emma.mae"
dir_test
}
set_lockscreen() {
# breaks BGDIR pattern to avoid conflict with loop
# and keep lockscreen separate from background image.
LOCKDIR="$HOME/Pictures"
if [[ ! -d $LOCKDIR ]]; then
echo "Please provide a valid lockscreen image directory!"
exit
fi
}
# GUI DIALOGS
test_dialog() {
if [[ ! -x /usr/bin/yad || ! -x /usr/bin/zenity ]]; then
echo "Please install either yad or zenity to employ gui dialogs."
exit
fi
}
cancel_dialog() {
if [[ $BGDIR == '' ]]; then
exit
fi
}
# Zenity dialog for choosing image directory
call_zenity_dialog() {
test_dialog
BGDIR=$(zenity --file-selection --directory
--title='Pick Your Wallpaper Directory' \
--width=600 --height=500 \
--filename="$HOME/Pictures/")
cancel_dialog
}
# Yad GTK dialog for choosing image directory
call_dir_dialog() {
test_dialog
BGDIR=$(yad --file --directory \
--title='Pick Your Wallpaper Directory' \
--add-preview --borders=3 --width=600 --height=500 \
--filename="$HOME/Pictures/*")
cancel_dialog
}
# Yad GTK dialog for picking image file
call_file_dialog() {
test_dialog
BGDIR=$(yad --file \
--title='Pick Your Wallpaper Image' \
--add-preview --borders=10 --width=700 --height=500 \
--filename="$HOME/Pictures/*")
cancel_dialog
}
# SET DESKTOP ENVIRONMENTS
set_kde() {
# create rWall settings folders, if they don't exist
if [[ ! -d $HOME/.config/rwall/kde ]]; then
mkdir -p $HOME/.config/rwall/kde/mon1 &> /dev/null
mkdir -p $HOME/.config/rwall/kde/mon2 &> /dev/null
fi
if [[ ! -e $HOME/.config/rwall/rwall.log ]]; then
touch $HOME/.config/rwall/rwall.log &> /dev/null
fi
LOG="$HOME/.config/rwall/rwall.log"
# first monitor
# set KDE wallpaper to path below
cp $WALLPAPER $HOME/.config/rwall/kde/mon1/rwall-kde.jpg
echo -e "$(date):\nMonitor1\n$WALLPAPER" >> $LOG
# second monitor
# uncomment a set_directory for different image directory
# than the first monitor
# set_directory1
# set_directory2
# set_directory3
random_sort ; cp $WALLPAPER $HOME/.config/rwall/kde/mon2/rwall-monitor2-kde.jpg
echo -e "$(date):\nMonitor2\n$WALLPAPER" >> $LOG
# lockscreen
# to use, uncomment cp line, run once, then set lockscreen to file shown below
set_lockscreen ; lockscreen_random_sort
# cp $LOCKSCREEN $HOME/.config/rwall/kde/rwall-lockscreen-kde.jpg
echo -e "$(date):\nLockscreen\n$LOCKSCREEN\n#####################" >> $LOG
}
set_openbox() {
# feh --bg-center "$WALLPAPER"
# feh --bg-scale "$WALLPAPER"
# feh --bg-tile "$WALLPAPER"
feh --bg-fill "$WALLPAPER"
}
set_gnome3() {
# options: centered, none, scaled, spanned, stretched, wallpaper, zoom
gsettings set org.gnome.desktop.background picture-options 'scaled'
# change "set" to "get" and delete option to return current background image
gsettings set org.gnome.desktop.background picture-uri file://"$WALLPAPER"
}
set_cinnamon() {
# used for Cinnamon 1.9.1
# options: centered, none, scaled, spanned, stretched, wallpaper, zoom
gsettings set org.cinnamon.background picture-options 'scaled'
# change "set" to "get" and delete option to return current background image
gsettings set org.cinnamon.background picture-uri file://"$WALLPAPER"
}
set_cinnamon2() {
# used for Cinnamon 2.0
# options: centered, none, scaled, spanned, stretched, wallpaper, zoom
gsettings set org.gnome.desktop.background picture-options 'scaled'
# change "set" to "get" and delete option to return current background image
gsettings set org.gnome.desktop.background picture-uri file://"$WALLPAPER"
}
set_mate14() {
mateconftool-2 -t str --set /desktop/mate/background/picture_filename "$WALLPAPER"
# options; "none", "wallpaper" (tiled), "centered", "scaled", "stretched"
mateconftool-2 -t str --set /desktop/mate/background/picture_options "scaled"
}
set_mate() {
# options: centered, none, scaled, spanned, stretched, wallpaper, zoom
gsettings set org.mate.background picture-options 'scaled'
# change "set" to "get" and delete option to return current background image
gsettings set org.mate.background picture-filename "$WALLPAPER"
}
set_xfce() {
# set STYLE to one fo the following numbers
# 0 - Auto, 1 - Centered, 2 - Tiled, 3 - Stretched, 4 - Scaled, 5 - Zoomed
# STYLE="4"
# xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitor0/image-style -s "$STYLE"
xfconf-query -c xfce4-desktop -p /backdrop/screen0/monitor0/image-path -s "$WALLPAPER"
}
# randomize wallpaper list and select one image. The purpose of the script.
random_sort() {
WALLPAPER=$(find "$BGDIR" -type f -iregex ".*\.\(jpg\|png\|jpeg\)$" \
| sort --random-sort | head --lines=1)
2> /dev/null
}
lockscreen_random_sort() {
LOCKSCREEN=$(find "$LOCKDIR" -type f -iregex ".*\.\(jpg\|png\|jpeg\)$" \
| sort --random-sort | head --lines=1)
2> /dev/null
}
# LOOP WALLPAPER
loop() {
kill_loop() {
# escape infinite loop by left-clicking tray notification icon
loopID=$!
yad --notification --image="preferences-desktop-wallpaper" \
--text="Left click stopss rWall's slideshow. Middle-click closes tray icon" \
--command="kill $loopID" --listen
exit
}
# loop parameter requester
loopForm=($(yad --form --title="Background Slideshow!" --separator=" " \
--borders=3 --width=400 --height=100 \
--field="Intervals"':NUM' '0!0..50!1' \
--field="Speed in Seconds"':NUM' '20!0..3600!1' \
--field="Pick Image Directory":DIR))
# form array elements assigned for clarity
INTERVAL=${loopForm[0]%.*}
SPEED=${loopForm[1]%.*}
LOOPDIR=${loopForm[2]}
# determine image directory
if [[ $LOOPDIR == "/" ]]; then
if [[ -d "$2" ]]; then
BGDIR="$2"
else
BGDIR="$USERDIR"
fi
else
BGDIR="${loopForm[2]}"
fi
echo
# default background swap speed
if [[ -z $SPEED ]]; then
$SPEED=10
fi
# starts infinite looping background if INTERVAL nill or zero
if [[ -z $INTERVAL || $INTERVAL == 0 ]]; then
echo " Press Ctrl+C to cancel the loop."
echo
while [[ true ]]; do
random_sort
$SETWALL
sleep $SPEED
done & #places loop in background, giving it a PID killable by the script
kill_loop
exit
else
echo " You have chosen to loop the background $INTERVAL times."
echo " Press Ctrl+C to cancel the loop, or wait for the count to reach 0."
echo " You can also left-click rWall's notification icon."
echo
echo " $(($INTERVAL - 1)) changes left."; echo
while [[ $INTERVAL > 0 ]]; do
random_sort
$SETWALL
sleep $SPEED
let --INTERVAL
if [[ $INTERVAL > 1 ]]; then
echo " $(($INTERVAL - 1)) changes left."; echo
elif [[ $INTERVAL == 1 ]]; then
echo " Last change complete."; echo
else
echo " Goodbye."; echo; exit 0
fi
done &
kill_loop
fi
}
cd /
# automatically set desktop environment function and variable for current user
if [[ $(w -sh | grep gnome-session | wc -l) == "1" ]]; then
if [[ $(cinnamon --version) == "Cinnamon 1.9.1" ]]; then
SETWALL=set_cinnamon
ENV="cinnamon"
elif [[ -x /usr/bin/gsettings ]]; then
SETWALL=set_gnome3
ENV="gnome3"
fi
elif [[ $(w -sh | grep cinnamon-session | wc -l) == "1" ]]; then
SETWALL=set_cinnamon2
ENV="cinnamon2"
elif [[ $(w -sh | grep gnome-session | wc -l) == "1" ]]; then
if [[ -x /usr/bin/gconftool-2 ]]; then
SETWALL=set_gnome2
ENV="gnome2"
fi
elif [[ $(xprop -root _DT_SAVE_MODE | grep xfce4 | wc -l) == "1" ]]; then
SETWALL=set_xfce
ENV="xfce"
elif [[ $(w -sh | grep mate | wc -l) == "1" ]]; then
if [[ -x /usr/bin/mateconftool-2 ]]; then
SETWALL=set_mate14
ENV="mate14"
elif [[ -x /usr/bin/gsettings ]]; then
SETWALL=set_mate
ENV="mate"
fi
elif [[ $(w -sh | grep kdeinit | wc -l) == "1" ]]; then
SETWALL=set_kde
ENV="kde"
elif [[ -x /usr/bin/feh ]]; then
# feh can be used for many environments, so we set variable to "other"
SETWALL=set_openbox
ENV="other"
else
echo "Missing components! Please ensure GNOME, KDE, XFCE, or feh is installed."
fi
# establish image directory, includes provision for accepting options for $1
if [[ -d "$2" ]]; then
BGDIR="$2"
elif [[ -d "$1" ]]; then
BGDIR="$1"
else
BGDIR="$USERDIR"
fi
random_sort
# OPTIONS
if [[ -d $2 || -z $2 ]]; then
case $1 in
"--help" ) usage;;
"--version" | "-v" ) echo "$VERSION";;
"--directory1" | "-d1" ) set_directory1 ; random_sort ; $SETWALL;;
"--directory2" | "-d2" ) set_directory2 ; random_sort ; $SETWALL;;
"--directory3" | "-d3" ) set_directory3 ; random_sort ; $SETWALL;;
"--dir-dialog" | "-dd" ) call_dir_dialog ; random_sort ; $SETWALL;;
"--file-dialog" | "-fd") call_file_dialog ; random_sort ; $SETWALL;;
"--zen-dialog" | "-zd" ) call_zenity_dialog ; random_sort ; $SETWALL;;
"" ) $SETWALL;;
"$BGDIR" ) $SETWALL;;
"--loop" | "-l" ) loop;;
"--redpill" ) echo "Why oh why didn't I take the BLUE pill?";;
"--bluepill" ) echo "Never send a human to do a machine's job.";;
* ) echo "\"$1\" is invalid. Type \"rwall --help.\""
esac
fi
exit 0