You are not logged in.
Lets just go with a yad version. I just updated the one I have to work in X and wayland, tested on openbox and labwc.
#!/usr/bin/env bash # (c) Copyright 2024 Mick Amadio <01micko@gmail.com> GPL3 # set the image set_wall() { echo setting $1 WALL='' if [[ -n "$WAYLAND_DISPLAY" ]];then if [[ -f "$HOME/.config/bunsen/wwall.conf" ]];then . $HOME/.config/bunsen/wwall.conf OLDWALL=$WALL fi else if [[ -f "$HOME/.config/bunsen/xwall.conf" ]];then . $HOME/.config/bunsen/xwall.conf OLDWALL=$WALL fi fi wall=${1##*/} oldwall=${WALL##*/} if [[ "$wall" == "$oldwall" ]];then yad --title="Icons" --window-icon=dialog-warning --name=dialog-warning \ --image=dialog-warning --button="Ok!gtk-ok!" --text="Wallpapers are the same!" \ >/dev/null 2>&1 exit fi # swaybg modes: stretch, fit, fill, center, tile # feh modes: --bg-scale, --bg-center[ --image-bg=$color], --bg-fill, --bg-max[ --image-bg=$color], --bg-tile BG="--image-bg=black" COMMAND="$IMGV $1" yad --title="Confirm" --window-icon=dialog-question --name=dialog-question \ --image=dialog-question \ --text="Do you want to change wallpapers from $oldwall to $wall?\Choose a sizing option below." \ --button='Stretch!!scale or stretch:2' \ --button='Fill!!fill:3' \ --button='Center!!center:4' \ --button='Tile!!tile:5!' \ --button="Preview!image-viewer!:sh -c '$COMMAND'" \ --button='Cancel!gtk-cancel!:1' \ >/dev/null 2>&1 case $? in 0);; 1)exit;; 2)OPT=stretch;; 3)OPT=fill;; 4)OPT=center;; 5)OPT=tile;; esac # set now and write to config if [[ -n "$WAYLAND_DISPLAY" ]];then echo "WALL=$1" > $HOME/.config/bunsen/wwall.conf killall swaybg >/dev/null 2>&1 swaybg -i "$1" -m "$OPT" 1>/dev/null 2>&1 & else echo "WALL=$1" > $HOME/.config/bunsen/xwall.conf case $OPT in stretch)feh --bg-scale "$1" &;; fill)feh --bg-fill "$1" &;; center)feh --bg-center --image-bg=$BG "$1" &;; tile)feh --bg-tile "$1" &;; esac fi } MSG="" if [[ -n "$WAYLAND_DISPLAY" ]];then if pidof labwc >/dev/null >/dev/null 2>&1 ;then MSG="You are running labwc\n" elif pidof sway >/dev/null >/dev/null 2>&1 ;then MSG="You are running sway\n" else MSG="You are running wayland\n" fi else if pidof openbox >/dev/null >/dev/null 2>&1 ;then MSG="You are running openbox\n" elif pidof xfwm4 >/dev/null >/dev/null 2>&1 ;then MSG="You are running xfce\n" else MSG="You are running Xorg\n" fi fi # MAIN # kill parent if exists read BPID b c <<<$(pidof yad) [[ -n "$BPID" ]] && kill -KILL $BPID >/dev/null 2>&1 # set image viewer if wanted IMGV= ####ristretto [[ -z "$IMGV" ]] && IMGV=bl-image-viewer # find the image cd $HOME/Pictures/wallpapers/wallpapers/default OUT=$(yad --title="Wallpaper" --window-icon=preferences-desktop-wallpaper \ --name=preferences-desktop-wallpaper --image=preferences-desktop-wallpaper \ --width=550 --height=375 \ --image-on-top --text="$MSG<big><big>Select a wallpaper and press OK</big></big>" \ --file) cd - [[ -n "$OUT" ]] && set_wall $OUT
Yes, I did run into a couple of issues, and have a few enhancement suggestions, if we decide to use this, or something derived from it.
1) Big one first. This code is problematic:
# kill parent if exists
read BPID b c <<<$(pidof yad)
[[ -n "$BPID" ]] && kill -KILL $BPID >/dev/null 2>&1
Yad is a popular application and there's a reasonable chance that another Yad process is running. This will kill a random member of all the currently running yad instances.
What is this "parent" of which you speak, anyway?
Is it a problem if there is more than one instance of this script running? If so, there are ways of handling that, eg with flock.
https://www.baeldung.com/linux/bash-ens … ce-running
https://mywiki.wooledge.org/BashFAQ/045
1a) In nearly every case, read should have the -r option. Also, what are the b c
variables intended to collect?
2)
OLDWALL=$WALL
OLDWALL is not used anywhere.
3)
# find the image
cd $HOME/Pictures/wallpapers/wallpapers/default
This path should be '$HOME/Pictures/wallpapers/bunsen/default' It's safer to check the return value of a cd command:
cd "$some_path" || exit-with-error-message
https://www.shellcheck.net/wiki/SC2164
It's neater to cd inside a subshell but you can't do it in this case because you'd lose the $OUT variable.
But anyway one suggestion I have is that we should look for existing nitrogen config and try to discover the directory from there.
4)
[[ -n "$OUT" ]] && set_wall $OUT
It's quite common for filenames to have spaces, so $OUT must be quoted in set_wall "$OUT"
. Looks like a typo though.
Possible enhancements:
1) How is the chosen wallpaper set after the next login?
2) Do we need separate files for the X11 and Wayland wallpapers?
3) Import existing settings from Nitrogen if this is a first-time run?
4) Find a way to display all the wallpapers in a directory ala Nitrogen? (The "preview" option does work however.)
5) If wallpaper has been set by some other app eg Nitrogen or pcmanfm the script has no way of knowing about it.
---
BLOB does a bit of wallpaper setting using nitrogen, feh, xfce4-desktop or pcmanfm. I don't know if any of that code is any use?
https://github.com/BunsenLabs/bunsen-bl … hemes#L910
https://github.com/BunsenLabs/bunsen-bl … emes#L1976
https://github.com/BunsenLabs/bunsen-bl … emes#L2070
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Sorry, one more I missed. (Quoting/escaping might be the most infuriating part of shell scripting.)
COMMAND="$IMGV $1"
--button="Preview!image-viewer!:sh -c '$COMMAND'" \
The preview breaks if the image filename (or path) has a space in it.
This seems to work:
--button="Preview!image-viewer!:sh -c '\"$IMGV\" \"$1\"'" \
Like I said, quoting in shell scripts...
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Find a way to display all the wallpapers in a directory ala Nitrogen?
Don't know how useful it will be, but there's an image viewer for Wayland called swayimg on Debian. It has a "gallery" mode - I played with it for a few minutes, added this ~/.config/swayimg/config
[general]
mode = gallery
[keys.gallery]
MouseRight = exec echo "%" > ~/image.txt
( https://github.com/artemsen/swayimg/blo … /swayimgrc )
So it's possible to get the image path from it to send to micko's wallpaper setter. But there might be other hurdles.
---
pqiv might be worth looking at too. It has a huge list of config options, and does a nice-looking gallery with --auto-montage-mode
.
https://github.com/phillipberndt/pqiv
Last edited by johnraff (2024-11-18 07:52:42)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Maybe time to look at Azote again. I plan to check once more if those dependency issues have been raised on Debian, and if not to send in bug reports.
Done.
They've arrived already: https://bugs.debian.org/cgi-bin/pkgrepo … t=unstable
Last edited by johnraff (2024-11-23 12:56:27)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
I've been working on a totally new wallpaper setter.
It's designed from the ground up using gtk3dialog and is useful in X and wayland and looks almost identical in both. Multiple monitors are supported, but may need work on the X side as I only have 2 outputs.
It demonstrates the capabilities of gtk3dialog
in quite a complex graphical application that has to make many decisions based on different conditions, as any program.
It also illustrates the XML style language that gtk3dialog
uses. It does support one line comments and IIRC there are one or two in the following code.
NOTE: gtk3dialog (linked above) is suitable for carbon/trixie/sid only. Of course it can be built/packaged in boron/bookworm which I may do at a later date.
So here it is, called wallswxw
(the name may change )
#!/bin/bash
# choose a wallpaper for wayland or X
# (c) Michael Amadio (@01micko) 2024 GPL2 (/usr/share/common-licenses/GPL-2)
# this changes walls for wayland wlroots compositors and simple X window mangaers
# requires 'swaybg', 'wlr-randr', 'gtk3dialog' for wayland
# requires 'feh', 'xrandr', 'gtk3dialog' for X
export V=0.1.0
export GTK3DIALOG
[[ -z $GTK3DIALOG ]] && GTK3DIALOG=gtk3dialog
export BGDIR=${BGDIR:-$HOME/Pictures/wallpapers/bunsen/default}
export TEMP=/tmp/wallswxw
mkdir -p $TEMP
export CONFDIR=${XDG_CONFIG_HOME:-$HOME/.config}/wallswxw
mkdir -p $CONFDIR
CONF=$CONFDIR/wallswxw.conf
if [[ ! -f "$CONF" ]];then
echo "BGDIR=$BGDIR" > $CONF
fi
. $CONF
case "$1" in
--restore)
if [[ -f "$CONFDIR/cmd" ]]; then
. $CONFDIR/cmd && exit 0
else
exit 1
fi
;;
-*v|-*version)
echo -e "\t${0##*\/} $V\n\t\tGPL-2.0+ licence\n"
exit 0
;;
-*h|-*help)
echo -e "\t${0##*\/} -h|--help\n\t\tshow this help and exit.\n"
echo -e "\t${0##*\/} -v|--version\n\t\tprint version and exit.\n"
echo -e "\t${0##*\/} --restore\n\t\trestore backgrounds at session start.\n"
echo -e "\ttry \"man ${0##*\/}\" for more information."
exit 0
;;
esac
# sort out the monitors and positions
if [[ -n "$WAYLAND_DISPLAY" ]]; then
b=0
c=1
MON=''
pos=''
WSTATS="$(wlr-randr)"
printf "$WSTATS" | while read -r l m n o p q
do
case "${l:0:3}" in
Pos|Mak|Mod|Ser|Phy|Ena|Tra|Sca|Ada)
if [[ "${l:0:3}" == 'Pos' ]];then
export pos
pos=${m%,*}; echo POS=$pos >> $TEMP/Wmonitor-$(($c-1))
else
continue
fi
;;
[a-zA-Z][a-zA-Z][a-zA-Z0-9])MON=$l;;
esac
case "$q" in
current*)res=$l;;
*)continue;;
esac
resX=${res%x*}
resY=${res#*x}
echo OUTPUT=$MON >> $TEMP/Wmonitor-$c
echo X=$resX >> $TEMP/Wmonitor-$c
echo Y=$resY >> $TEMP/Wmonitor-$c
c=$(($c+1))
b=$(($b+1))
echo $b > $TEMP/number
done
export POPT='edge="top" dist="100"'
export SOPT='layer="top"'
export CONFILE=$CONFDIR/Wconf
export M=10
else
k=0
n=1
MON=''
XSTATS="$(xrandr --listmonitors | tail -n2)"
printf "%s\n" "$XSTATS" | while read a b c d z
do
echo $a
#[[ "${a:0:8}" == 'Monitors' ]] && n=0
MON=$d
resX=${c/\/[0-9]*/}
resY=${c#*x}
resY=${resY/\/[0-9]*/}
pos=${c#*+}
pos=${pos/+/ }
[[ "${pos%\ *}" == '0' ]] && n=0 # 'xx' position
pos=${pos%\ *}
echo Xmonitor-$n
echo $MON
echo $resX
echo $resY
echo $pos
echo OUTPUT=$MON >> $TEMP/Xmonitor-$n
echo X=$resX >> $TEMP/Xmonitor-$n
echo Y=$resY >> $TEMP/Xmonitor-$n
echo POS=$pos >> $TEMP/Xmonitor-$n
n=$(($n+1))
k=$(($k+1))
echo $k > $TEMP/number
done
export POPT='decorated="false"'
export SOPT=$POPT
export CONFILE=$CONFDIR/Xconf
export M=1
export WOPT='window-position="1"'
fi
#CSS
echo 'window {
background: rgba(0,0,0,0.0);
}
#port {
background: @theme_bg_color;
border-radius: 10px;
padding: 2px;
}
#splash {
background: #5E003E;
color: #ffffff;
border-radius: 10px;
padding: 2px;
}
' > $TEMP/win.css
# get the primary output
e=0
if [[ -n "$WAYLAND_DISPLAY" ]]; then
for i in $TEMP/Wmonitor*
do
#echo "$i is being sourced"
. $i
[[ "$POS" == '0' ]] && echo "$OUTPUT = primary" && cp $i $TEMP/ww0
[[ "$POS" == "$X" ]] && echo "$OUTPUT = secondary" && cp $i $TEMP/ww1
[[ $POS -gt $X ]] && echo "$OUTPUT = extra" && cp $i $TEMP/ww2$e && e=$(($e+1))
done
rm $TEMP/Wmonitor* # finished with these
read NUM < $TEMP/number
export NUM
echo $NUM outputs
. $TEMP/ww0
export W=$(($X / 9))
export H=$(($Y / 10))
else
for f in $TEMP/Xmonitor*
do
#echo "$f is being sourced"
. $f
[[ "$POS" == '0' ]] && echo "$OUTPUT = primary" && cp $f $TEMP/xx0
[[ "$POS" == "$X" ]] && echo "$OUTPUT = secondary" && cp $f $TEMP/xx1
[[ $POS -gt $X ]] && echo "$OUTPUT = extra" && cp $i $TEMP/xx2$e && e=$(($e+1))
done
rm $TEMP/Xmonitor* # finished with these
export NUM
read NUM < $TEMP/number
echo $NUM outputs
. $TEMP/xx0
export W=$(($X / 9))
export H=$(($Y / 10))
fi
######################## functions ##############################
# splash window
_splash() {
[[ "$SPLASH" == 'no' && "$2" == '0' ]] && return
[[ -z "$1" ]] && return
case $2 in
0)DIS='
<button tooltip-text="Do not show again">
<input file icon="window-close"></input>
<label>Dismiss</label>
<action>echo SPLASH=no >> '$CONF'</action>
<action>exit:DISMISS</action>
</button>'
;;
2);;
*)ACT='<action>exit:OK</action>';;
esac
echo '<window '$POPT' '$WOPT' width-request="360">
<vbox name="splash">
<hbox name="splash">
<pixmap name="splash"><width>42</width><input file icon="gtk-info"></input></pixmap>
<timer interval="8" visible="false"><action>exit:SPLASH</action><action>exit:BYE</action></timer>
<text name="splash">
<label>'"$1"'</label>
</text>
</hbox>
<hbox name="splash">
'$DIS'
<button>
<label>OK</label>
<input file icon="gtk-ok"></input>
'$ACT'
</button>
</hbox>
</vbox>
</window>' | $GTK3DIALOG -s --styles=$TEMP/win.css
[[ "$2" == '1' ]] && exit $2
}; export -f _splash
# sort selections
_selections() {
echo '<hbox>' > $TEMP/ret
cat $TEMP/selected | while read -r sel
do
echo ' <pixmap>
<height>120</height>
<input file>'$sel'</input>
</pixmap>' >> $TEMP/ret
done
echo '</hbox>' >> $TEMP/ret
}; export -f _selections
# set each background
confirm_gui() {
_selections
PIX=$(cat $TEMP/ret)
export CON='<window icon-name="background" '$WOPT' title="Confirm selection" '$POPT' margin="'$M'">
<vbox name="port">
<hbox>
<vseparator name="port" space-expand="true" space-fill="true"></vseparator>
<text use-markup="true" width-chars="30">
<label>"<big>Confirm Selection</big>"</label>
</text>
<vseparator name="port" space-expand="true" space-fill="true"></vseparator>
<button><input file icon="window-close"></input><action>exit:abort</action></button>
</hbox>
<hbox space-expand="true" space-fill="true">
<text><label>Please confirm that the image below is correct.</label></text>
</hbox>
<hbox space-expand="true" space-fill="true">
'$PIX'
</hbox>
<hbox>
<button yes></button><button no></button>
</hbox>
</vbox>
</window>'
eval $($GTK3DIALOG -p CON --styles=$TEMP/win.css)
case $EXIT in
Yes)_build_command;;
*)return 1;;
esac
}; export -f confirm_gui
# populate the main GUI
button_gui() {
# populate main gui
WALLS=$(ls -1 $BGDIR)
c=0
echo "$WALLS" | while read WALL
do
file -b --mime-type "$BGDIR/$WALL" | grep -q 'image' || continue # test mime
# we take advantage of bash math here
# for a nicish GUI width *must* be consistent
i=$((c/4))
echo ' <button image-position="top" tooltip-text="Set '"${WALL##*/}"'">
<input file>'$BGDIR'/'"$WALL"'</input>
<height>'$W'</height>
<width>'$W'</width>
<!--action>echo '$BGDIR'/'"\"$WALL\""' > '$TEMP/choice'</action-->
<action>_output '$BGDIR'/'"\"$WALL\""'</action>
</button>' >> $TEMP/buttonsx$i
c=$((${c}+1))
done
for j in $(ls $TEMP | grep buttonsx[0-9]*)
do echo "<hbox>
$(cat $TEMP/$j)
</hbox>" >> $TEMP/buttons
done
}
# sub GUI
sub_gui() {
COM=$(cat $TEMP/OP)
if [[ -n "$WAYLAND_DISPLAY" ]]; then
SS='Wset'
ACTION='<action>echo -e " -o $OUT -m $MODE \\ \n\t -i '$1' \\" >> '$TEMP/$SS'</action>'
else
# feh modes: --bg-scale, --bg-center[ --image-bg=$color], --bg-fill, --bg-max[ --image-bg=$color], --bg-tile
SS='Xwset'
ACTION='<action>if [[ "$MODE" == "stretch" || "$MODE" == "fill" ]];then MODE=fill;fi; echo -e " --bg-$MODE \\ \n\t'$1' \\" >> '$TEMP/$SS'</action>'
fi
[[ $NUM -gt 1 ]] && XTRA='Choose output display and '
[[ -r "$TEMP/increment" ]] || echo -n 1 > $TEMP/increment
INC=$(cat $TEMP/increment)
# set default for comboboxtext
case $INC in
1)DEFAULT=$(sed '1s/item/default/g' < $TEMP/OP | sed -n 1p) ;;
2)DEFAULT=$(sed '2s/item/default/g' < $TEMP/OP | sed -n 2p) ;;
3)DEFAULT=$(sed '3s/item/default/g' < $TEMP/OP | sed -n 3p) ;;
4)DEFAULT=$(sed '4s/item/default/g' < $TEMP/OP | sed -n 4p) ;;
5)DEFAULT=$(sed '5s/item/default/g' < $TEMP/OP | sed -n 5p) ;;
6)DEFAULT=$(sed '6s/item/default/g' < $TEMP/OP | sed -n 6p) ;;
esac
if [[ $INC -gt $NUM ]]; then
_splash "You are at your monitor limit. Confirm?" 3
else
export SUBGUI='<window icon-name="background" title="Selection" '$SOPT' margin="'$M'">
<vbox name="port">
<hbox>
<vseparator name="port" space-expand="true" space-fill="true"></vseparator>
<text use-markup="true" width-chars="30">
<label>"<big>Selection</big>"</label>
</text>
<vseparator name="port" space-expand="true" space-fill="true"></vseparator>
<button><input file icon="window-close"></input><action>exit:abort</action></button>
</hbox>
<hbox space-expand="true" space-fill="true">
<text><label>'$XTRA'Press image</label></text>
</hbox>
<hbox space-expand="true" space-fill="false">
<text use-markup="true"><label>"<big>Mode:</big>"</label></text>
<comboboxtext>
<variable>MODE</variable>
<item>stretch</item>
<item>center</item>
<item>tile</item>
<item>fit</item>
</comboboxtext>
</hbox>
<hbox space-expand="true" space-fill="false">
<text use-markup="true"><label>"<big>Output:</big>"</label></text>
<comboboxtext>
<variable>OUT</variable>
'$DEFAULT'
'$COM'
</comboboxtext>
</hbox>
<hbox space-expand="true" space-fill="true">
<button tooltip-text="Press image to confirm or No to reject and confinue.">
<variable>CBG</variable>
<input file>'$1'</input>
<width>320</width>
<!--action>if [[ '$INC' -gt '$NUM' ]];then exit:SPLASH;fi</action-->
<action>echo -n '$(($INC+1))' > $TEMP/increment</action>
<action>if grep -q $OUT '$TEMP'/'$SS' >/dev/null 2>&1; then _splash "Only 1 wall per monitor. Maybe you have reached the monitor limit?." 3;fi;</action>
<action>echo '$1' >> '$TEMP'/selected</action>
'$ACTION'
<action>sed -i "s% $%%g" '$TEMP/$SS'</action>
<action>exit:CBG</action>
</button>
</hbox>
<hbox>
<text label="'$INC'"></text>
<button no></button>
</hbox>
</vbox>
</window>'
echo "$SUBGUI" > $TEMP/sub.xml
$GTK3DIALOG -p SUBGUI -c --styles=$TEMP/win.css
fi
}; export -f sub_gui
# populate the main GUI
main_gui() {
BUTTONS=$(cat $TEMP/buttons)
export GUI='<window icon-name="background" title="Background Choice" '$SOPT'>
<vbox name="port">
<hbox>
<vseparator name="port" space-expand="true" space-fill="true"></vseparator>
<text use-markup="true" width-chars="50">
<label>"<big>Background Choice</big>"</label>
</text>
<vseparator name="port" space-expand="true" space-fill="true"></vseparator>
<button><width>16</width><input file icon="window-close"></input><action>kill '$PID'</action><action>exit:abort</action></button>
</hbox>
<hbox space-expand="true" space-fill="true">
<text use-markup="true"><label>"<b>Select an image for your wallpaper by pressing the image.</b>"</label></text>
</hbox>
<hseparator name="port" space-expand="true" space-fill="true"></hseparator>
<hbox width-request="'$(($X / 2))'" height-request="'$(($Y / 2))'">
<vbox scrollable="true">
'$BUTTONS'
</vbox>
</hbox>
<hbox space-expand="true" space-fill="true">
<hseparator name="port" space-expand="true" space-fill="true"></hseparator>
<text label="Press Confirm when you are ready."></text>
<hseparator name="port" space-expand="true" space-fill="true"></hseparator>
<button>
<label>Confirm</label>
<input file icon="gtk-help"></input>
<action>confirm_gui</action>
<action>exit:CONFIRM</action>
</button>
</hbox>
</vbox>
</window>'
echo "$GUI" > $TEMP/gui.xml
$GTK3DIALOG -p GUI -c --styles=$TEMP/win.css
}
# build options for output
_output() {
[[ -n "$WAYLAND_DISPLAY" ]] && fff=ww || fff=xx
rm -f $TEMP/OP
for output in $TEMP/${fff}*
do
. $output
export OUTPUT
export FBG=$1
echo "<item>$OUTPUT</item>" >> $TEMP/OP
done
sub_gui $FBG
}; export -f _output
_build_command() {
if [[ -n "$WAYLAND_DISPLAY" ]]; then
echo 'killall swaybg >/dev/null 2>&1' > $TEMP/cmd
echo 'swaybg \' >> $TEMP/cmd
cat $TEMP/Wset >> $TEMP/cmd
echo '>/dev/null 2>&1 &' >> $TEMP/cmd
# run it
. $TEMP/cmd
cat $TEMP/cmd > $CONFDIR/cmd # you can put this in your startuo file
else
# this builds ~/.fehbg with the command below.
echo 'killall feh >/dev/null 2>&1' > $TEMP/cmd
echo 'feh \' >> $TEMP/cmd
cat $TEMP/Xwset >> $TEMP/cmd
echo '>/dev/null 2>&1 &' >> $TEMP/cmd
# run it
. $TEMP/cmd
fi
}; export -f _build_command
_dependencies() { # adapted from bl-includes
# Usage: _dependencies command [command...]
local missing_commands=()
i=
for i in "$@"
do
hash "$i" 2>/dev/null || missing_commands+=(" $i")
done
if [[ ${missing_commands[0]} ]];then
ERR_MSG="This script requires the following commands: \"${missing_commands[*]}\" .\
Please install the packages containing the missing commands and re-run the script."
_splash "${ERR_MSG}" 3
exit
fi
}
trap_exit() {
trap "rm -rf $TEMP" EXIT
}; export -f trap_exit
######################## main ##############################
### required programs ###
declare -a APPS
if [[ -n "$WAYLAND_DISPLAY" ]]; then
APPS=( "gtk3dialog" "wlr-randr" "swaybg" )
else
APPS=( "gtk3dialog" "xrandr" "feh" )
fi
_dependencies "${APPS[@]}"
trap_exit
export PID=$$
rm -f $TEMP/buttons*
if [[ "$NUM" != '1' ]]; then
_splash "You have $NUM monitors connected. Carefully choose an image for each of them." 0
fi
echo ================
button_gui
main_gui
EDIT: maybe call it yaws - Yet Another Wallpaper Setter
Last edited by micko01 (2024-12-08 07:18:45)
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
Nice!
Looks pretty and does the job.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Nice!
Looks pretty and does the job.
Thanks
X, Wayland or both?
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
Only tested on X so far, though there's a Wayland session available here so I'll check that too.
A couple of small enhancement requests might be coming up, but nothing earthshaking.
You might consider installing shellcheck - geany will put it in the menu as "Lint" and it spouts a lonnng list of nitpicking issues you could spend a happy hour ironing out. Many (most?) of them can be safely ignored but especially with long scripts like this I think it's worth a checkover.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
I'll check it on Gnome Wayland tomorrow. Looks sweet!
No, he can't sleep on the floor. What do you think I'm yelling for?!!!
Offline
Amazing demonstration of what gtk3dialog can do! Looks really professional and does what it claims.
Also, demonstrates how complex scripting with gtk3dialog will be, requiring lots of xml to be piped in. This is nowhere near the tinkerability of yad for general scripters. Maybe BL could make some functions ala yad-includes that do the heavy lifting so scripters can call eg 'g3d-info' for a generic info box?
Unfortunately it's hard for me to dive deep into some of the code because I only have one monitor, but I have found a few issues and possible enhancements:
1) The section where wlr-randr or xrandr are parsed to get monitor info (lines 44-116) might need some attention. On X (not Wayland) a popup comes up saying there are multiple monitors, and to be sure to choose the right one. This is on a VM with only one monitor. It's coming because the output of 'xrandr --listmonitors' looks like this:
Monitors: 1
0: +*Virtual-1 1024/271x768/203+0+0 Virtual-1
which is parsed with 'read'. The two lines are parsed separately and cause the script to think there are two monitors, although with no resolution etc. I tried adding a line to skip the 'Monitors: 1' line before parsing, which gets rid of the issue, but I don't know if it's the way you want to fix it (from #86):
printf "%s\n" "$XSTATS" | while read -r a b c d z
do
echo "$a"
#[[ "${a:0:8}" == 'Monitors' ]] && n=0
[[ "${a}" == 'Monitors:' ]] && continue
It's your code, but I might have fed the data to read with a herestring instead of piping the output of printf:
while read -r a b c d z
do
echo "$a"
#[[ "${a:0:8}" == 'Monitors' ]] && n=0
MON=$d
resX=${c/\/[0-9]*/}
resY=${c#*x}
resY=${resY/\/[0-9]*/}
pos=${c#*+}
pos=${pos/+/ }
[[ "${pos%\ *}" == '0' ]] && n=0 # 'xx' position
pos=${pos%\ *}
echo Xmonitor-$n
echo "$MON"
echo "$resX"
echo "$resY"
echo "$pos"
echo "OUTPUT=$MON" >> "$TEMP"/Xmonitor-$n
echo "X=$resX" >> "$TEMP"/Xmonitor-$n
echo "Y=$resY" >> "$TEMP"/Xmonitor-$n
echo "POS=$pos" >> "$TEMP"/Xmonitor-$n
n=$((n+1))
k=$((k+1))
echo $k > $TEMP/number
done <<< "$XSTATS"
Saves a call to printf and avoids read running in a subshell, so the variables written are still available after the loop. (This would probably apply to other places where things are being piped to 'read'.)
I don't know whether the subshell was the reason you wrote the data to files instead of storing it in arrays.
2) On X the wallpaper setting is not persistent. By comparing with Wayland, seems there's a line missing to save the command to CONFDIR. Adding this after ~#440 seems to fix it:
. "$TEMP"/cmd
cat "$TEMP"/cmd > "$CONFDIR"/cmd # add this line
3) Choose image, instead of pressing image in popup, mistakenly press "Confirm" in main dialogue - app freezes. I don't know how this should be fixed.
4) Image names with spaces will not be set. (With variable escaping they will display in the dialogue OK.) I found that if you escape $1 in line 295 in sub_gui() thus:
ACTION='<action>if [[ "$MODE" == "stretch" || "$MODE" == "fill" ]];then MODE=fill;fi; echo -e " --bg-$MODE \\ \n\t'\'$1\'' \\" >> '"$TEMP/$SS"'</action>'
it seems to work, but haven't tested extensively.
enhancements?
a) I'd like a "Cancel" button on the main window.
b) It would be nice to display all wallpapers recursively from ~/Pictures/wallpapers down, as Nitrogen does.
In button_gui() if 'ls' is replaced by a recursive shell glob then it can be done. A little editing was needed:
button_gui() {
# populate main gui
c=0
shopt -s globstar
for WALL in "$BGDIR"/*{,/**}
do
file -b --mime-type "$WALL" | grep -q 'image' || continue # test mime
# we take advantage of bash math here
# for a nicish GUI width *must* be consistent
i=$((c/4))
echo ' <button image-position="top" tooltip-text="Set '"${WALL##*/}"'">
<input file>'"\"$WALL\""'</input>
<height>'$W'</height>
<width>'$W'</width>
<!--action>echo '"\"$WALL\""' > '$TEMP/choice'</action-->
<action>_output '"\"$WALL\""'</action>
</button>' >> $TEMP/buttonsx$i
c=$((c+1))
done
shopt -u globstar
for j in $(ls "$TEMP" | grep buttonsx[0-9]*)
do echo "<hbox>
$(cat "$TEMP/$j")
</hbox>" >> $TEMP/buttons
done
}
c) The window cannot be dragged around the screen by its title bar like other X windows. Would be nice. Haven't tested in Wayland.
In spite of all the above, it really is a magnificent piece of work!
EDIT: fixed button_gui()because it was temporarily broken for testing.
Last edited by johnraff (2024-12-14 06:42:32)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Just a quick reply for now. It's Friday here and been a big week! (new job).
@hhh
This will only work in wlroots
compositors so I have to devise a test so that it will fail gracefully in KDE/gnome etc.
--------------------------------------------
a) I'd like a "Cancel" button on the main window.
b) It would be nice to display all wallpapers recursively from ~/Pictures/wallpapers down, as Nitrogen does.
c) The window cannot be dragged around the screen by its title bar like other X windows. Would be nice. Haven't tested in Wayland.
a) Easy and shall do. However it will completely exit the program, as does the 'X' (abort) button top right.
b) Sure, that's possible, but could result in a lot of junk being churned out for wallpapers. Jury is out on that one so requires further thought/ideas etc. The 'BGDIR' is configurable, so maybe I should add a menubar with some options, or at least a button to an 'options' GUI.
c) There is a reason windows are fixed and that is that the appearance of the GUI is consistent between wayland an X, so it's by design.
With GTK in general, in X you can request a window position. That is most of the time respected.
In wayland, you can't as all the different wlroots based compositors use a different engine to place windows. There are similar tools to 'xdotool' and such available for wayland but they vary in reliability so I use the most stable protocol which is called the 'layer-shell' protocol and this is baked into any recent wlroots compositor (labwc, sway, hyprland, river etc - the light weight ones). GTK and QT have their own versions, based on upstream 'layer-shell' (maybe other toolkits too) and in our case I use 'gtk-layer-shell' (which is baked into gtk3dialog
at compile time).
There is no title bar per sé. It's just a GTK box widget with an 'X' placed RHS and the title roughly centred. In X it cant be 'grabbed' but maybe it can moved with alt + drag
. In wayland the window is 'anchored' and I'm reluctant to change that.
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
johnraff wrote:a) I'd like a "Cancel" button on the main window.
b) It would be nice to display all wallpapers recursively from ~/Pictures/wallpapers down, as Nitrogen does.
c) The window cannot be dragged around the screen by its title bar like other X windows. Would be nice. Haven't tested in Wayland.a) Easy and shall do. However it will completely exit the program, as does the 'X' (abort) button top right.
Sure, "Cancel" on the main window would be expected to exit, like the 'X'. I just feel the X is "unofficial".
b) Sure, that's possible, but could result in a lot of junk being churned out for wallpapers. Jury is out on that one so requires further thought/ideas etc. The 'BGDIR' is configurable, so maybe I should add a menubar with some options, or at least a button to an 'options' GUI.
The replacement button_gui() I posted above under b) (but note today's edit) seems to do the job, at least on Xorg. I didn't see any garbage in the output, though it should be easy to add other filters after the mimetype test if necessary. I'll test with Wayland today. Yes default BGDIR should be set to ~/Pictures/wallpapers for that to work like in current BL with Nitrogen.
c) There is a reason windows are fixed and that is that the appearance of the GUI is consistent between wayland an X, so it's by design.
...
There is no title bar per sé. It's just a GTK box widget with an 'X' placed RHS and the title roughly centred. In X it cant be 'grabbed' but maybe it can moved withalt + drag
. In wayland the window is 'anchored' and I'm reluctant to change that.
OK fair enough.
Last edited by johnraff (2024-12-14 06:44:23)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
issue 5):
On Wayland there is no icon in the tasktray and the app window is always on top, with no way of hiding it. On Xorg with tint2 it works normally.
enhancement d):
On Wayland the sub-windows that pop up have no border, making them hard to distinguish from the main window. Fine on Xorg, except that the round corners have square edges.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
issue 5):
On Wayland there is no icon in the tasktray and the app window is always on top, with no way of hiding it. On Xorg with tint2 it works normally..
This is how 'layer-shell' works and it's unlikely to change. If I don't use layer-shell the GUI will pop up in any old place depending on what placement policy the user chooses. I don't think the icon in the systray is important, nor being on top. Use it and then it gets out of the way. It's not intended for long running.
enhancement d):
On Wayland the sub-windows that pop up have no border, making them hard to distinguish from the main window. Fine on Xorg, except that the round corners have square edges.
I can easily add a border around wayland sub GUI. Round corners work fine on X here (bare metal, compositor 'picom', may not work in VM)
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
Here's the next. You can call it whatever you like as PROG=${0##*\/}
now and everything related goes to '$PROG"
Has the globbing but I notice that fails to follow symlinked directories. Works fine if subdirs aren't links. Sorry mised that fix!
Refactored the calls to respective 'randr' progs for W and X, using 'here' syntax now (was trying to use #!/usr/bin/busybox ash
as shebang - faster)
added preferences GUI for BGDIR and splash option at startup.
various other little cleanups (like quoting some variables and adding said wayland border for sub gui)
EDIT: removed. See next post.
EDIT: fixed the globbing
I reckon this is faster with a bunch of images than Azote
. I always find efficient shell is better than python (probably more opining really!)
Last edited by micko01 (2024-12-14 22:38:33)
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
I have restored the natural window decorations for X and wayland so in labwc the GUI can potentially pop up wherever there is space, unless you use the 'center' placement policy in rc.xml. The only exception is the splash window.
#!/bin/bash
export V=0.1.0
export GTK3DIALOG
[[ -z "$GTK3DIALOG" ]] && GTK3DIALOG=gtk3dialog
export BGDIR="${BGDIR:-$HOME/Pictures/wallpapers/bunsen/default}"
export PROG=${0##*\/}
export TEMP=/tmp/$PROG
#export TEMP=$HOME/tmp/$PROG # for testing
mkdir -p "$TEMP"
export CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}/$PROG"
mkdir -p "$CONFDIR"
CONF="$CONFDIR/$PROG.conf"
if [[ ! -f "$CONF" ]];then
echo "BGDIR=$BGDIR" > "$CONF"
fi
. "$CONF"
case "$1" in
--restore)
if [[ -f "$CONFDIR/cmd" ]]; then
. "$CONFDIR/cmd" && exit 0
else
exit 1
fi
;;
-*v|-*version)
echo -e "\t$PROG $V\n\t\tGPL-2.0+ licence\n"
exit 0
;;
-*h|-*help)
echo -e "\t$PROG -h|--help\n\t\tshow this help and exit.\n"
echo -e "\t$PROG -v|--version\n\t\tprint version and exit.\n"
echo -e "\t$PROG --restore\n\t\trestore backgrounds at session start.\n"
echo -e "\ttry \"man $PROG\" for more information."
exit 0
;;
esac
# sort out the monitors and positions
if [[ -n "$WAYLAND_DISPLAY" ]]; then
b=0
c=1
MON=''
pos=''
while read -r l m n o p q
do
case "${l:0:3}" in
Pos|Mak|Mod|Ser|Phy|Ena|Tra|Sca|Ada)
if [[ "${l:0:3}" == 'Pos' ]];then
export pos
pos=${m%,*}; echo POS=$pos >> "$TEMP/Wmonitor-$((c-1))"
else
continue
fi
;;
[a-zA-Z][a-zA-Z][a-zA-Z0-9])MON=$l;;
esac
case "$q" in
current*)res=$l;;
*)continue;;
esac
resX=${res%x*}
resY=${res#*x}
echo OUTPUT=$MON >> "$TEMP/Wmonitor-$c"
echo X=$resX >> "$TEMP/Wmonitor-$c"
echo Y=$resY >> "$TEMP/Wmonitor-$c"
c=$((c+1))
b=$((b+1))
echo $b > $TEMP/number
done <<<$(wlr-randr)
export POPT='edge="top" dist="100"'
export SOPT='layer="top"'
export CONFILE="$CONFDIR/Wconf"
else
k=0
n=1
MON=''
while read -r a b c d z
do
echo $a
[[ "${a}" == 'Monitors:' ]] && continue
MON=$d
resX=${c/\/[0-9]*/}
resY=${c#*x}
resY=${resY/\/[0-9]*/}
pos=${c#*+}
pos=${pos/+/ }
[[ "${pos%\ *}" == '0' ]] && n=0 # 'xx' position
pos=${pos%\ *}
echo Xmonitor-$n
echo $MON
echo $resX
echo $resY
echo $pos
echo OUTPUT=$MON >> "$TEMP/Xmonitor-$n"
echo X=$resX >> "$TEMP/Xmonitor-$n"
echo Y=$resY >> "$TEMP/Xmonitor-$n"
echo POS=$pos >> "$TEMP/Xmonitor-$n"
n=$((n+1))
k=$((k+1))
echo $k > $TEMP/number
done <<<$(xrandr --listmonitors)
export POPT='decorated="false"'
export SOPT=$POPT
export CONFILE="$CONFDIR/Xconf"
fi
#CSS
echo 'window#splash {
background: rgba(0,0,0,0.0);
}
#splash {
background: #5E003E;
color: #ffffff;
border-radius: 10px;
padding: 2px;
}
' > "$TEMP/win.css"
# get the primary output
e=0
if [[ -n "$WAYLAND_DISPLAY" ]]; then
for i in $TEMP/Wmonitor*
do
#echo "$i is being sourced"
. "$i"
[[ "$POS" == '0' ]] && echo "$OUTPUT = primary" && cp $i $TEMP/ww0
[[ "$POS" == "$X" ]] && echo "$OUTPUT = secondary" && cp $i $TEMP/ww1
[[ $POS -gt $X ]] && echo "$OUTPUT = extra" && cp $i $TEMP/ww2$e && e=$((e+1))
done
rm $TEMP/Wmonitor* # finished with these
read -r NUM < "$TEMP/number"
export NUM
echo $NUM outputs
. $TEMP/ww0
export W=$((X / 9))
export H=$((Y / 10))
else
for f in $TEMP/Xmonitor*
do
#echo "$f is being sourced"
. "$f"
[[ "$POS" == '0' ]] && echo "$OUTPUT = primary" && cp $f $TEMP/xx0
[[ "$POS" == "$X" ]] && echo "$OUTPUT = secondary" && cp $f $TEMP/xx1
[[ $POS -gt $X ]] && echo "$OUTPUT = extra" && cp $i $TEMP/xx2$e && e=$((e+1))
done
rm $TEMP/Xmonitor* # finished with these
export NUM
read NUM < $TEMP/number
echo $NUM outputs
. $TEMP/xx0
export W=$((X / 9))
export H=$((Y / 10))
fi
######################## functions ##############################
# splash window
_splash() {
[[ -z "$1" ]] && return
case $2 in
0)[[ "$SPLASH" == 'false' ]] && return
DIS='
<button tooltip-text="Do not show again">
<input file icon="window-close"></input>
<label>Dismiss</label>
<action>if grep -q "SPLASH" '$CONF'; then sed -i "s/^SPLASH.*$/SPLASH=false/" '$CONF';else echo SPLASH=false >> '$CONF'; fi</action>
<action>exit:DISMISS</action>
</button>'
;;
2);;
5)ACT='<action>kill '$PID'</action><action>exit:OK</action>';;
*)ACT='<action>exit:OK</action>';;
esac
echo '<window '$POPT' name="splash" width-request="360">
<vbox name="splash">
<hbox name="splash">
<hbox space-expand="false" space-fill="false">
<pixmap name="splash"><width>42</width><input file icon="gtk-info"></input></pixmap>
<timer interval="8" visible="false"><action>exit:SPLASH</action><action>exit:BYE</action></timer>
</hbox>
<hbox space-expand="true" space-fill="true">
<text name="splash">
<label>'"$1"'</label>
</text>
</hbox>
</hbox>
<hbox name="splash">
'$DIS'
<button>
<label>OK</label>
<input file icon="gtk-ok"></input>
'$ACT'
</button>
</hbox>
</vbox>
</window>' | $GTK3DIALOG -s --styles=$TEMP/win.css
[[ "$2" == '1' ]] && exit $2
}; export -f _splash
# sort selections
_selections() {
echo '<hbox>' > $TEMP/ret
cat $TEMP/selected | while read -r sel
do
echo ' <pixmap>
<height>120</height>
<input file>'$sel'</input>
</pixmap>' >> $TEMP/ret
done
echo '</hbox>' >> $TEMP/ret
}; export -f _selections
# set each background
confirm_gui() {
_selections
PIX=$(cat $TEMP/ret)
export CON='<window icon-name="background" title="Confirm selection">
<vbox>
<hbox space-expand="true" space-fill="true">
<text><label>Please confirm that the image below is correct.</label></text>
</hbox>
<hbox space-expand="true" space-fill="true">
'$PIX'
</hbox>
<hbox>
<button yes></button><button no></button>
</hbox>
</vbox>
</window>'
eval "$($GTK3DIALOG -p CON --styles=$TEMP/win.css)"
case $EXIT in
Yes)_build_command;;
*)return 1;;
esac
}; export -f confirm_gui
# populate the main GUI
button_gui() {
# populate main gui
c=0
shopt -s globstar
for WALL in "$BGDIR"/*{,/**}
do
file -b --mime-type "$WALL" | grep -q 'image' || continue # test mime
# we take advantage of bash math here
# for a nicish GUI width *must* be consistent
i=$((c/4))
echo ' <button image-position="top" tooltip-text="Set '"${WALL##*/}"'">
<input file>'"\"$WALL\""'</input>
<height>'$W'</height>
<width>'$W'</width>
<!--action>echo '"\"$WALL\""' > '$TEMP/choice'</action-->
<action>_output '"\"$WALL\""'</action>
</button>' >> $TEMP/buttonsx$i
c=$((c+1))
done
shopt -u globstar
for j in $(ls "$TEMP" | grep buttonsx[0-9]*)
do echo "<hbox>
$(cat "$TEMP/$j")
</hbox>" >> $TEMP/buttons
done
}
# sub GUI
sub_gui() {
COM=$(cat $TEMP/OP)
if [[ -n "$WAYLAND_DISPLAY" ]]; then
SS='Wset'
ACTION='<action>echo -e " -o $OUT -m $MODE \\ \n\t -i '$1' \\" >> '$TEMP/$SS'</action>'
else
# feh modes: --bg-scale, --bg-center[ --image-bg=$color], --bg-fill, --bg-max[ --image-bg=$color], --bg-tile
SS='Xwset'
ACTION='<action>if [[ "$MODE" == "stretch" || "$MODE" == "fill" ]];then MODE=fill;fi; echo -e " --bg-$MODE \\ \n\t'$1' \\" >> '$TEMP/$SS'</action>'
fi
[[ $NUM -gt 1 ]] && XTRA='Choose output display and '
[[ -r "$TEMP/increment" ]] || echo -n 1 > $TEMP/increment
INC=$(cat $TEMP/increment)
# set default for comboboxtext
case $INC in
1)DEFAULT=$(sed '1s/item/default/g' < $TEMP/OP | sed -n 1p) ;;
2)DEFAULT=$(sed '2s/item/default/g' < $TEMP/OP | sed -n 2p) ;;
3)DEFAULT=$(sed '3s/item/default/g' < $TEMP/OP | sed -n 3p) ;;
4)DEFAULT=$(sed '4s/item/default/g' < $TEMP/OP | sed -n 4p) ;;
5)DEFAULT=$(sed '5s/item/default/g' < $TEMP/OP | sed -n 5p) ;;
6)DEFAULT=$(sed '6s/item/default/g' < $TEMP/OP | sed -n 6p) ;;
esac
if [[ $INC -gt $NUM ]]; then
_splash "You are at your monitor limit. Confirm?" 3
else
export SUBGUI='<window icon-name="background" title="Selection">
<vbox>
<hbox space-expand="true" space-fill="true">
<text><label>'$XTRA'Press image</label></text>
</hbox>
<hbox space-expand="true" space-fill="false">
<text use-markup="true"><label>"<big>Mode:</big>"</label></text>
<comboboxtext>
<variable>MODE</variable>
<item>stretch</item>
<item>center</item>
<item>tile</item>
<item>fit</item>
</comboboxtext>
</hbox>
<hbox space-expand="true" space-fill="false">
<text use-markup="true"><label>"<big>Output:</big>"</label></text>
<comboboxtext>
<variable>OUT</variable>
'$DEFAULT'
'$COM'
</comboboxtext>
</hbox>
<hbox space-expand="true" space-fill="true">
<button tooltip-text="Press image to confirm or No to reject and confinue.">
<variable>CBG</variable>
<input file>'$1'</input>
<width>320</width>
<!--action>if [[ '$INC' -gt '$NUM' ]];then exit:SPLASH;fi</action-->
<action>echo -n '$((INC+1))' > $TEMP/increment</action>
<action>if grep -q $OUT '$TEMP'/'$SS' >/dev/null 2>&1; then _splash "Only 1 wall per monitor. Maybe you have reached the monitor limit?." 3;fi;</action>
<action>echo '$1' >> '$TEMP'/selected</action>
'$ACTION'
<action>sed -i "s% $%%g" '$TEMP/$SS'</action>
<action>exit:CBG</action>
</button>
</hbox>
<hbox>
<text label="Output: '$INC'"></text>
<button no></button>
</hbox>
</vbox>
</window>'
echo "$SUBGUI" > $TEMP/sub.xml
$GTK3DIALOG -p SUBGUI -c --styles=$TEMP/win.css
fi
}; export -f sub_gui
# populate the main GUI
main_gui() {
BUTTONS=$(cat $TEMP/buttons)
export GUI='<window icon-name="background" title="Background Choice">
<vbox>
<hbox space-expand="true" space-fill="true">
<text use-markup="true"><label>"<b>Select an image for your wallpaper by pressing the image.</b>"</label></text>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox width-request="'$((X / 2))'" height-request="'$((Y / 2))'">
<vbox scrollable="true">
'$BUTTONS'
</vbox>
</hbox>
<hbox space-expand="true" space-fill="true">
<hbox space-expand="false" space-fill="false">
<button tooltip-text="Preferences"><width>16</width><input file icon="preferences-desktop-wallpaper"></input>
<action>exit:PREFS</action>
</button>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<text label="Press Confirm when you are ready."></text>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="false" space-fill="false">
<button>
<label>Cancel</label>
<input file icon="gtk-cancel"></input>
<action>kill '$PID'</action>
<action>exit:abort</action>
</button>
<button>
<label>Confirm</label>
<input file icon="gtk-help"></input>
<action>confirm_gui</action>
<action>exit:CONFIRM</action>
</button>
</hbox>
</hbox>
</vbox>
</window>'
echo "$GUI" > $TEMP/gui.xml
eval "$($GTK3DIALOG -p GUI -c --styles=$TEMP/win.css)"
if [[ "$EXIT" == "PREFS" ]]; then
_pref
fi
}
# preferences
_pref() {
. $CONF
[[ "$SPLASH" == 'false' ]] && CDEF=false || CDEF=true
export PGUI='<window icon-name="gtk-preferences" title="Preferences" width-request="400">
<vbox>
<hbox space-expand="true" space-fill="true">
<text use-markup="true"><label>"<b>Select your preferences.</b>"</label></text>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="true" space-fill="true">
<text><label>"Press Save and '$PROG' will restart when you are ready."</label></text>
</hbox>
<hbox space-expand="true" space-fill="true">
<text><label>"Just choose any image file in your chosen directory."</label></text>
</hbox>
<hbox space-expand="true" space-fill="true">
<hbox space-expand="true" space-fill="true">
<entry>
<default>'$BGDIR'</default>
<variable>BACKGROUNDS</variable>
</entry>
</hbox>
<hbox space-expand="false" space-fill="false">
<button>
<input file icon="directory-open"></input>
<action function="fileselect">BACKGROUNDS</action>
</button>
</hbox>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="true" space-fill="true">
<hbox space-expand="true" space-fill="true">
<checkbox>
<label>enable initial splash screen.</label>
<variable>SPL</variable>
<default>'$CDEF'</default>
</checkbox>
</hbox>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="false" space-fill="false">
<button>
<label>Cancel</label>
<input file icon="gtk-cancel"></input>
<action>kill '$PID'</action>
<action>exit:abort</action>
</button>
<button>
<label>Save</label>
<input file icon="gtk-save"></input>
<action>exit:SAVE</action>
</button>
</hbox>
</vbox>
</window>'
eval "$($GTK3DIALOG -p PGUI -c --styles=$TEMP/win.css)"
echo $SPL
if [[ ! -d "$BACKGROUNDS" ]]; then
BACKGROUNDS="${BACKGROUNDS%\/*}"
sed -i "s%^BGDIR.*$%BGDIR=\"$BACKGROUNDS\"%" $CONF
fi
if grep -q 'SPLASH' $CONF; then
sed -i "s/^SPLASH.*$/SPLASH=$SPL/" $CONF
else
echo "SPLASH=$SPL" >> $CONF
fi
if [[ "$EXIT" == 'SAVE' ]]; then
exec $PROG
fi
}; export -f _pref
# build options for output
_output() {
[[ -n "$WAYLAND_DISPLAY" ]] && fff=ww || fff=xx
rm -f $TEMP/OP
for output in $TEMP/${fff}*
do
. $output
export OUTPUT
export FBG=$1
echo "<item>$OUTPUT</item>" >> $TEMP/OP
done
sub_gui $FBG
}; export -f _output
_build_command() {
if [[ -n "$WAYLAND_DISPLAY" ]]; then
echo 'killall swaybg >/dev/null 2>&1' > $TEMP/cmd
echo 'swaybg \' >> $TEMP/cmd
cat $TEMP/Wset >> $TEMP/cmd
echo '>/dev/null 2>&1 &' >> $TEMP/cmd
# run it
. "$TEMP/cmd"
cat $TEMP/cmd > $CONFDIR/cmd # you can put this in your startup file
else
# this builds ~/.fehbg with the command below.
echo 'killall feh >/dev/null 2>&1' > $TEMP/cmd
echo 'feh \' >> $TEMP/cmd
cat $TEMP/Xwset >> $TEMP/cmd
echo '>/dev/null 2>&1 &' >> $TEMP/cmd
# run it
. "$TEMP/cmd"
fi
}; export -f _build_command
trap_exit() {
trap "rm -rf $TEMP" EXIT
}; export -f trap_exit
######################## main ##############################
trap_exit
export PID=$$
if [[ -n "$WAYLAND_DISPLAY" ]]; then
case "$XDG_CURRENT_DESKTOP" in
wlroots|labwc|sway*|river|niri|hyprland)echo "$XDG_CURRENT_DESKTOP";; # this can be expanded later
*)_splash "Unfortunately your desktop $XDG_CURRENT_DESKTOP is unsupported" 5 ;;
esac
fi
if [[ ! -d "$BGDIR" ]]; then
_splash "Please set a background directory" 3
_pref
fi
if [[ "$NUM" != '1' ]]; then
_splash "You have $NUM monitors connected. Carefully choose an image for each of them." 0
fi
echo ================
button_gui
main_gui
The basic engine is the same and it's also less code.
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
This most recent version (below) supports a configurable background color if you choose 'center' in feh (X) or swaybg (Wayland)
The color is chosen in the Preferences GUI (bottom left in Main GUI) via a gtk-color-chooser widget. Only 1 color is supported, seems a bit complicated to add custom colors for each image but is possible. Not sure if I'll do that yet. If I do I may as well support just a solid color for BG as well.
#!/bin/bash
export V=0.1.0
export GTK3DIALOG
[[ -z "$GTK3DIALOG" ]] && GTK3DIALOG=gtk3dialog
export BGDIR="${BGDIR:-$HOME/Pictures/wallpapers/bunsen/default}"
export PROG=${0##*\/}
export TEMP=/tmp/$PROG
#export TEMP=$HOME/tmp/$PROG # for testing
mkdir -p "$TEMP"
export CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}/$PROG"
mkdir -p "$CONFDIR"
export CONF="$CONFDIR/$PROG.conf"
if [[ ! -f "$CONF" ]];then
echo "BGDIR=$BGDIR" > "$CONF"
fi
. "$CONF"
case "$1" in
--restore)
if [[ -f "$CONFDIR/cmd" ]]; then
. "$CONFDIR/cmd" && exit 0
else
exit 1
fi
;;
-*v|-*version)
echo -e "\t$PROG $V\n\t\tGPL-2.0+ licence\n"
exit 0
;;
-*h|-*help)
echo -e "\t$PROG -h|--help\n\t\tshow this help and exit.\n"
echo -e "\t$PROG -v|--version\n\t\tprint version and exit.\n"
echo -e "\t$PROG --restore\n\t\trestore backgrounds at session start.\n"
echo -e "\ttry \"man $PROG\" for more information."
exit 0
;;
esac
# sort out the monitors and positions
if [[ -n "$WAYLAND_DISPLAY" ]]; then
b=0
c=1
MON=''
pos=''
while read -r l m n o p q
do
case "${l:0:3}" in
Pos|Mak|Mod|Ser|Phy|Ena|Tra|Sca|Ada)
if [[ "${l:0:3}" == 'Pos' ]];then
export pos
pos=${m%,*}; echo POS=$pos >> "$TEMP/Wmonitor-$((c-1))"
else
continue
fi
;;
[a-zA-Z][a-zA-Z][a-zA-Z0-9])MON=$l;;
esac
case "$q" in
current*)res=$l;;
*)continue;;
esac
resX=${res%x*}
resY=${res#*x}
echo OUTPUT=$MON >> "$TEMP/Wmonitor-$c"
echo X=$resX >> "$TEMP/Wmonitor-$c"
echo Y=$resY >> "$TEMP/Wmonitor-$c"
c=$((c+1))
b=$((b+1))
echo $b > $TEMP/number
done <<<$(wlr-randr)
export POPT='edge="top" dist="100"'
export SOPT='layer="top"'
export CONFILE="$CONFDIR/Wconf"
else
k=0
n=1
MON=''
while read -r a b c d z
do
echo $a
[[ "${a}" == 'Monitors:' ]] && continue
MON=$d
resX=${c/\/[0-9]*/}
resY=${c#*x}
resY=${resY/\/[0-9]*/}
pos=${c#*+}
pos=${pos/+/ }
[[ "${pos%\ *}" == '0' ]] && n=0 # 'xx' position
pos=${pos%\ *}
echo Xmonitor-$n
echo $MON
echo $resX
echo $resY
echo $pos
echo OUTPUT=$MON >> "$TEMP/Xmonitor-$n"
echo X=$resX >> "$TEMP/Xmonitor-$n"
echo Y=$resY >> "$TEMP/Xmonitor-$n"
echo POS=$pos >> "$TEMP/Xmonitor-$n"
n=$((n+1))
k=$((k+1))
echo $k > $TEMP/number
done <<<$(xrandr --listmonitors)
export POPT='decorated="false"'
export SOPT=$POPT
export CONFILE="$CONFDIR/Xconf"
fi
#CSS
echo 'window#splash {
background: rgba(0,0,0,0.0);
}
#splash {
background: #5E003E;
color: #ffffff;
border-radius: 10px;
padding: 2px;
}
' > "$TEMP/win.css"
# get the primary output
e=0
if [[ -n "$WAYLAND_DISPLAY" ]]; then
for i in $TEMP/Wmonitor*
do
#echo "$i is being sourced"
. "$i"
[[ "$POS" == '0' ]] && echo "$OUTPUT = primary" && cp $i $TEMP/ww0
[[ "$POS" == "$X" ]] && echo "$OUTPUT = secondary" && cp $i $TEMP/ww1
[[ $POS -gt $X ]] && echo "$OUTPUT = extra" && cp $i $TEMP/ww2$e && e=$((e+1))
done
rm $TEMP/Wmonitor* # finished with these
read -r NUM < "$TEMP/number"
export NUM
echo $NUM outputs
. $TEMP/ww0
export W=$((X / 9))
export H=$((Y / 10))
else
for f in $TEMP/Xmonitor*
do
#echo "$f is being sourced"
. "$f"
[[ "$POS" == '0' ]] && echo "$OUTPUT = primary" && cp $f $TEMP/xx0
[[ "$POS" == "$X" ]] && echo "$OUTPUT = secondary" && cp $f $TEMP/xx1
[[ $POS -gt $X ]] && echo "$OUTPUT = extra" && cp $i $TEMP/xx2$e && e=$((e+1))
done
rm $TEMP/Xmonitor* # finished with these
export NUM
read NUM < $TEMP/number
echo $NUM outputs
. $TEMP/xx0
export W=$((X / 9))
export H=$((Y / 10))
fi
######################## functions ##############################
# splash window
_splash() {
[[ -z "$1" ]] && return
case $2 in
0)[[ "$SPLASH" == 'false' ]] && return
DIS='
<button tooltip-text="Do not show again">
<input file icon="window-close"></input>
<label>Dismiss</label>
<action>if grep -q "SPLASH" '$CONF'; then sed -i "s/^SPLASH.*$/SPLASH=false/" '$CONF';else echo SPLASH=false >> '$CONF'; fi</action>
<action>exit:DISMISS</action>
</button>'
;;
2);;
5)ACT='<action>kill '$PID'</action><action>exit:OK</action>';;
*)ACT='<action>exit:OK</action>';;
esac
echo '<window '$POPT' name="splash" width-request="360">
<vbox name="splash">
<hbox name="splash">
<hbox space-expand="false" space-fill="false">
<pixmap name="splash"><width>42</width><input file icon="gtk-info"></input></pixmap>
<timer interval="8" visible="false"><action>exit:SPLASH</action><action>exit:BYE</action></timer>
</hbox>
<hbox space-expand="true" space-fill="true">
<text name="splash">
<label>'"$1"'</label>
</text>
</hbox>
</hbox>
<hbox name="splash">
'$DIS'
<button>
<label>OK</label>
<input file icon="gtk-ok"></input>
'$ACT'
</button>
</hbox>
</vbox>
</window>' | $GTK3DIALOG -s --styles=$TEMP/win.css
[[ "$2" == '1' ]] && exit $2
}; export -f _splash
# sort selections
_selections() {
echo '<hbox>' > $TEMP/ret
cat $TEMP/selected | while read -r sel
do
echo ' <pixmap>
<height>120</height>
<input file>'$sel'</input>
</pixmap>' >> $TEMP/ret
done
echo '</hbox>' >> $TEMP/ret
}; export -f _selections
# set each background
confirm_gui() {
_selections
PIX=$(cat $TEMP/ret)
export CON='<window icon-name="background" title="Confirm selection">
<vbox>
<hbox space-expand="true" space-fill="true">
<text><label>Please confirm that the image below is correct.</label></text>
</hbox>
<hbox space-expand="true" space-fill="true">
'$PIX'
</hbox>
<hbox>
<button yes></button><button no></button>
</hbox>
</vbox>
</window>'
eval "$($GTK3DIALOG -p CON --styles=$TEMP/win.css)"
case $EXIT in
Yes)_build_command;;
*)return 1;;
esac
}; export -f confirm_gui
# populate the main GUI
button_gui() {
# populate main gui
c=0
shopt -s globstar
for WALL in "$BGDIR"/*{,/**}
do
file -b --mime-type "$WALL" | grep -q 'image' || continue # test mime
# we take advantage of bash math here
# for a nicish GUI width *must* be consistent
i=$((c/4))
echo ' <button image-position="top" tooltip-text="Set '"${WALL##*/}"'">
<input file>'"\"$WALL\""'</input>
<height>'$W'</height>
<width>'$W'</width>
<!--action>echo '"\"$WALL\""' > '$TEMP/choice'</action-->
<action>_output '"\"$WALL\""'</action>
</button>' >> $TEMP/buttonsx$i
c=$((c+1))
done
shopt -u globstar
for j in $(ls "$TEMP" | grep buttonsx[0-9]*)
do echo "<hbox>
$(cat "$TEMP/$j")
</hbox>" >> $TEMP/buttons
done
}
# sub GUI
sub_gui() {
COM=$(cat $TEMP/OP)
if [[ -n "$WAYLAND_DISPLAY" ]]; then
CCOL="-c $COLOR"
SS='Wset'
ACTION='<action>echo -e " -o $OUT -m $MODE '$CCOL' \\ \n\t -i '$1' \\" >> '$TEMP/$SS'</action>'
else
# feh modes: --bg-scale, --bg-center[ --image-bg=$color], --bg-fill, --bg-max[ --image-bg=$color], --bg-tile
XCOL=" --image-bg=#${COLOR}"
SS='Xwset'
ACTION='<action>if [[ "$MODE" == "stretch" || "$MODE" == "fit" ]];then MODE=fill;fi; echo -e " --bg-$MODE '${XCOL}' \\ \n\t'$1' \\" >> '$TEMP/$SS'</action>'
fi
[[ $NUM -gt 1 ]] && XTRA='Choose output display and '
[[ -r "$TEMP/increment" ]] || echo -n 1 > $TEMP/increment
INC=$(cat $TEMP/increment)
# set default for comboboxtext
case $INC in
1)DEFAULT=$(sed '1s/item/default/g' < $TEMP/OP | sed -n 1p) ;;
2)DEFAULT=$(sed '2s/item/default/g' < $TEMP/OP | sed -n 2p) ;;
3)DEFAULT=$(sed '3s/item/default/g' < $TEMP/OP | sed -n 3p) ;;
4)DEFAULT=$(sed '4s/item/default/g' < $TEMP/OP | sed -n 4p) ;;
5)DEFAULT=$(sed '5s/item/default/g' < $TEMP/OP | sed -n 5p) ;;
6)DEFAULT=$(sed '6s/item/default/g' < $TEMP/OP | sed -n 6p) ;;
esac
if [[ $INC -gt $NUM ]]; then
_splash "You are at your monitor limit. Confirm?" 3
else
export SUBGUI='<window icon-name="background" title="Selection">
<vbox>
<hbox space-expand="true" space-fill="true">
<text><label>'$XTRA'Press image</label></text>
</hbox>
<hbox space-expand="true" space-fill="false">
<text use-markup="true"><label>"<big>Mode:</big>"</label></text>
<comboboxtext>
<variable>MODE</variable>
<item>stretch</item>
<item>center</item>
<item>tile</item>
<item>fit</item>
</comboboxtext>
</hbox>
<hbox space-expand="true" space-fill="false">
<text use-markup="true"><label>"<big>Output:</big>"</label></text>
<comboboxtext>
<variable>OUT</variable>
'$DEFAULT'
'$COM'
</comboboxtext>
</hbox>
<hbox space-expand="true" space-fill="true">
<button tooltip-text="Press image to confirm or No to reject and confinue.">
<variable>CBG</variable>
<input file>'$1'</input>
<width>320</width>
<!--action>if [[ '$INC' -gt '$NUM' ]];then exit:SPLASH;fi</action-->
<action>echo -n '$((INC+1))' > $TEMP/increment</action>
<action>if grep -q $OUT '$TEMP'/'$SS' >/dev/null 2>&1; then _splash "Only 1 wall per monitor. Maybe you have reached the monitor limit?." 3;fi;</action>
<action>echo '$1' >> '$TEMP'/selected</action>
'$ACTION'
<action>sed -i "s% $%%g" '$TEMP/$SS'</action>
<action>exit:CBG</action>
</button>
</hbox>
<hbox>
<text label="Output: '$INC'"></text>
<button no></button>
</hbox>
</vbox>
</window>'
$GTK3DIALOG -p SUBGUI -c --styles=$TEMP/win.css
fi
}; export -f sub_gui
# populate the main GUI
main_gui() {
BUTTONS=$(cat $TEMP/buttons)
export GUI='<window icon-name="background" title="Background Choice">
<vbox>
<hbox space-expand="true" space-fill="true">
<text use-markup="true"><label>"<b>Select an image for your wallpaper by pressing the image.</b>"</label></text>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox width-request="'$((X / 2))'" height-request="'$((Y / 2))'">
<vbox scrollable="true">
'$BUTTONS'
</vbox>
</hbox>
<hbox space-expand="true" space-fill="true">
<hbox space-expand="false" space-fill="false">
<button tooltip-text="Preferences"><width>16</width><input file icon="preferences-desktop-wallpaper"></input>
<action>exit:PREFS</action>
</button>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<text label="Press Confirm when you are ready."></text>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="false" space-fill="false">
<button>
<label>Cancel</label>
<input file icon="gtk-cancel"></input>
<action>kill '$PID'</action>
<action>exit:abort</action>
</button>
<button>
<label>Confirm</label>
<input file icon="gtk-help"></input>
<action>confirm_gui</action>
<action>exit:CONFIRM</action>
</button>
</hbox>
</hbox>
</vbox>
</window>'
eval "$($GTK3DIALOG -p GUI -c --styles=$TEMP/win.css)"
if [[ "$EXIT" == "PREFS" ]]; then
_pref
fi
}
# preferences
_pref() {
. $CONF
[[ "$SPLASH" == 'false' ]] && CDEF=false || CDEF=true
[[ -n "$COLOR" ]] && DEFCOL=#${COLOR} || DEFCOL=#cccccc
echo $DEFCOL
export PGUI='<window icon-name="gtk-preferences" title="Preferences" width-request="400">
<vbox>
<hbox space-expand="true" space-fill="true">
<text use-markup="true"><label>"<b>Select your preferences.</b>"</label></text>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="true" space-fill="true">
<text><label>"Press Save and '$PROG' will restart when you are ready."</label></text>
</hbox>
<hbox space-expand="true" space-fill="true">
<text><label>"Just choose any image file in your chosen directory."</label></text>
</hbox>
<hbox space-expand="true" space-fill="true">
<hbox space-expand="true" space-fill="true">
<entry>
<default>'$BGDIR'</default>
<variable>BACKGROUNDS</variable>
</entry>
</hbox>
<hbox space-expand="false" space-fill="false">
<button>
<input file icon="directory-open"></input>
<action function="fileselect">BACKGROUNDS</action>
</button>
</hbox>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="true" space-fill="true">
<hbox space-expand="true" space-fill="true">
<checkbox>
<label>enable initial splash screen.</label>
<variable>SPL</variable>
<default>'$CDEF'</default>
</checkbox>
</hbox>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="true" space-fill="true">
<hbox space-expand="true" space-fill="true">
<entry editable="false">
<default>Choose a background color</default>
</entry>
</hbox>
<hbox space-expand="false" space-fill="false">
<colorbutton>
<default>'$DEFCOL'</default>
<variable>CLB0</variable>
</colorbutton>
</hbox>
</hbox>
<hseparator space-expand="true" space-fill="true"></hseparator>
<hbox space-expand="false" space-fill="false">
<button>
<label>Cancel</label>
<input file icon="gtk-cancel"></input>
<action>kill '$PID'</action>
<action>exit:abort</action>
</button>
<button>
<label>Save</label>
<input file icon="gtk-save"></input>
<action>exit:SAVE</action>
</button>
</hbox>
</vbox>
</window>'
eval "$($GTK3DIALOG -p PGUI -c --styles=$TEMP/win.css)"
echo $SPL
if [[ ! -d "$BACKGROUNDS" ]]; then
BACKGROUNDS="${BACKGROUNDS%\/*}"
sed -i "s%^BGDIR.*$%BGDIR=\"$BACKGROUNDS\"%" $CONF
fi
if grep -q 'SPLASH' $CONF; then
sed -i "s/^SPLASH.*$/SPLASH=$SPL/" $CONF
else
echo "SPLASH=$SPL" >> $CONF
fi
if grep -q 'COLOR' $CONF; then
sed -i "s/^COLOR.*$/COLOR=${CLB0:1:6}/" $CONF
else
echo "COLOR=${CLB0:1:6}" >> $CONF
fi
if [[ "$EXIT" == 'SAVE' ]]; then
exec $0
fi
}; export -f _pref
# build options for output
_output() {
[[ -n "$WAYLAND_DISPLAY" ]] && fff=ww || fff=xx
rm -f $TEMP/OP
for output in $TEMP/${fff}*
do
. $output
export OUTPUT
export FBG=$1
echo "<item>$OUTPUT</item>" >> $TEMP/OP
done
. $CONF
#echo $COLOR
sub_gui $FBG
}; export -f _output
_build_command() {
if [[ -n "$WAYLAND_DISPLAY" ]]; then
echo 'killall swaybg >/dev/null 2>&1' > $TEMP/cmd
echo 'swaybg \' >> $TEMP/cmd
cat $TEMP/Wset >> $TEMP/cmd
echo '>/dev/null 2>&1 &' >> $TEMP/cmd
# run it
. "$TEMP/cmd"
cat $TEMP/cmd > $CONFDIR/cmd # you can put this in your startup file
else
# this builds ~/.fehbg with the command below.
echo 'killall feh >/dev/null 2>&1' > $TEMP/cmd
echo 'feh \' >> $TEMP/cmd
cat $TEMP/Xwset >> $TEMP/cmd
echo '>/dev/null 2>&1 &' >> $TEMP/cmd
# run it
. "$TEMP/cmd"
fi
}; export -f _build_command
trap_exit() {
trap "rm -rf $TEMP" EXIT
}; export -f trap_exit
######################## main ##############################
trap_exit
export PID=$$
if [[ -n "$WAYLAND_DISPLAY" ]]; then
case "$XDG_CURRENT_DESKTOP" in
wlroots|labwc|sway*|river|niri|hyprland)echo "$XDG_CURRENT_DESKTOP";; # this can be expanded later
*)_splash "Unfortunately your desktop $XDG_CURRENT_DESKTOP is unsupported" 5 ;;
esac
fi
if [[ ! -d "$BGDIR" ]]; then
_splash "Please set a background directory" 3
_pref
fi
if [[ "$NUM" != '1' ]]; then
_splash "You have $NUM monitors connected. Carefully choose an image for each of them." 0
fi
echo ================
button_gui
main_gui
This new feature also allows a transparent image with your choice of background color. Below is a transparent smiley SVG, centered, over a solid color.
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline
3) Choose image, instead of pressing image in popup, mistakenly press "Confirm" in main dialogue - app freezes. I don't know how this should be fixed.
This issue still exists. After choosing an image, click anywhere on the main window and the app freezes completely. Xorg or Wayland.
( Still checking out the other new features. )
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Need to set default colour when user has not yet hit the preferences button. Otherwise the options sent to swaybg are
'-m <mode> -c -i <file>'
swaybg chokes on the -c with no color declared.
I couldn't figure out whether to set COLOR or DEFCOL to the default #cccccc
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Need to set default colour when user has not yet hit the preferences button. Otherwise the options sent to swaybg are
'-m <mode> -c -i <file>'
swaybg chokes on the -c with no color declared.
I couldn't figure out whether to set COLOR or DEFCOL to the default #cccccc
This patch should fix that issue (not tested)
--- bin/blwall 2024-12-15 12:00:57.087643449 +1000
+++ ./blwall 2024-12-15 17:39:18.611332158 +1000
@@ -270,6 +270,7 @@
# sub GUI
sub_gui() {
COM=$(cat $TEMP/OP)
+ [[ -z "$COLOR" ]] && COLOR=cccccc
if [[ -n "$WAYLAND_DISPLAY" ]]; then
CCOL="-c $COLOR"
SS='Wset'
--------
3) Choose image, instead of pressing image in popup, mistakenly press "Confirm" in main dialogue - app freezes. I don't know how this should be fixed.
As for the '3)' issue - which I missed - the program will will need a refactor. Sorry about that.
#!/bin/sh
echo '#include <stdio.h>\nvoid main() { printf("Hi, bunsenlabs\\n"); return; }' > bunsen.c
gcc bunsen.c -o bunsen
./bunsen
Offline