This is a script (tool for selecting an image to be used as permanent wallpaper on the Desktop) which was used as a testbed for learning how to use YAD (Zenity fork) and how to fine tune the application of the various option flags.
It aso has the benefit of being useful ! For greater discussion and some snapshots, please refer to this.
Script: LOGIN__ChangeWallpaper.sh
#!/bin/bash
# This script lets the user select an image and
# set it as the desktop background on Ubuntu MATE. It copies
# the image to the /usr/share/backgrounds directory,
# updates the background setting, and recompiles the schemas.
# Philippe734 @ 2025
#
# REF: https://ubuntu-mate.community/t/changing-wallpaper-login-screen/29222
#
# REVISED:
# by Eric Marceau
# Version 1 - Expanded logic added and dialog presentation modified
# Version 2 - Revised logic to make identification of relevant schema file more robust
# Version 3 - Revised logic to identify locale and created file allowing language-specific customization
# Version 4 - Corrected error of omission to load locale-driven language-specific customization
# Version 5 - Final error correction to make language-specfic customization work as intended
#
setupLang()
{
scriptName=$0
scriptLocn=$( dirname "$0" )
scriptBase=$( basename "$0" ".sh" )
msgStrng=( \
"Login Screen Wallpaper" \
" Choose different image?" \
"Keep Old" \
"Choose New" \
"Current Login Wallpaper" \
"Chosen Replacement" \
"Confirm Choice To Replace" \
"Retain Current" \
"Confirm Change" \
"Login configuration updated." \
"You should confirm the change by performing logout." )
thisLocale=$( env | grep 'LANG=' | cut -f2- -d"=" | cut -f1 -d":" | cut -f1 -d"." | cut -f1 -d"_" )
scriptLang="${scriptLocn}/${scriptBase}.${thisLocale}"
if [ -s "${scriptLang}" ]
then
if [ -n "$( diff "${scriptLocn}/${scriptBase}.en" "${scriptLang}" | head -1 )" ]
then
echo "differences" >&2
indx=0
while read line
do
msgStrng[${indx}]="${line}"
indx=$(expr ${indx} + 1 )
done <"${scriptLang}"
else
echo -e "\n Please note that you can use prompt strings in your own language by replacing the strings for each line in file intended for your locale:"
{ ls -l "${scriptLocn}/${scriptBase}.en"
ls -l "${scriptLang}"
} | awk '{ printf("\t %s\n", $0 ) ; }'
echo -e "\n The '${scriptLocn}/${scriptBase}.en' file has been provided as a baseline for the meaning of those strings.\n"
fi
else
if [ ! -s "${scriptLocn}/${scriptBase}.en" ]
then
count=${#msgStrng[@]}
indx=0
while [ ${indx} -lt ${count} ]
do
echo "${msgStrng[${indx}]}"
indx=$(expr ${indx} + 1 )
done >"${scriptLocn}/${scriptBase}.en"
fi
if [ ! -s "${scriptLang}" ]
then
cp -p "${scriptLocn}/${scriptBase}.en" "${scriptLang}"
fi
fi
}
getThumb()
{
local imageIn="$1"
local imageOut="$2"
convert ${imageIn} -resize 15% ${imageOut}
}
#########################################################################################
#########################################################################################
if [ "$1" = "--verbose" ] ; then dbg=1 ; else dbg=0 ; fi
destDir="/usr/share/backgrounds"
setupLang
###
### Ensuring required functionality is available
###
if [ -z "$(which yad 2>>/dev/null)" ]
then
echo -e "\n The required 'YAD' utility is missing. Install? [y|N] => \c" ; read ans
test -n "${ans}" || { ans="N" ; }
case "${ans}" in
y* | Y* ) ;;
* ) echo "\n Abandonning attempt to change the Login wallpaper.\n" ; exit 1 ;;
esac
pkexec bash -c "apt install yad -y"
fi
###
### Identify system's active login greeter
###
method1()
{
###
### Approach which would be more generic and suited to both X-Window and Wayland
###
sysGreeter=$( grep "session" /var/log/syslog | head -40 | grep 'greeter' | head -1 |
awk '{
pos=index( $0, "comm=" ) ;
if( pos > 0 ){
rem=substr( $0, pos ) ;
n=split( rem, val, "\"" ) ;
print val[2] ;
exit ;
#substr( rem, pos+6, psp-2 ) ;
} ;
}' | sed 's+[ ]$++' )
sysGreeter=$( basename "${sysGreeter}" )
}
method1
method2()
{
###
### Alternate approach, but X-windows specific
###
if [ ! -s /var/log/lightdm/seat0-greeter.log ]
then
echo -e "\n\t LightDM does not appear to be the active Display Manager. Unable to proceed.\n" ; exit 1
fi
#[+3.90s] DEBUG: arctica-greeter.vala:937: Starting main loop
sysGreeter=$( grep '[:][ ]Starting main loop' /var/log/lightdm/seat0-greeter.log | awk '{ print $3 }' | cut -f1 -d"." )
}
#method2()
test ${dbg} -eq 1 && echo "${sysGreeter}"
###
### Allow for local extra schema override file being distinct from default file
###
greetMatch=$( grep "${sysGreeter}" /usr/share/glib-2.0/schemas/*.gschema.override | sort -r | head -1 )
test ${dbg} -eq 1 && echo "${greetMatch}"
#schemaFile="$(ls -r /usr/share/glib-2.0/schemas/*_ubuntu-mate.gschema.override | head -1 )"
schemaFile="$( echo "${greetMatch}" | cut -f1 -d":" )"
test ${dbg} -eq 1 && echo "${schemaFile}"
###
### Identify fullpathname to current Login Greeter background image
###
greeterSchema=$( gsettings list-schemas | grep ${sysGreeter} )
if [ -z "${greeterSchema}" ] ; then echo -e "\n\t Unable to identify schema for greeter '${sysGreeter}'. Unable to proceed.\n" ; exit 1 ; fi
current="$( gsettings get "${greeterSchema}" background | cut -f2 -d\' | sed 's+^file://++' )"
test ${dbg} -eq 1 && echo ${current}
tCurrent="/tmp/$$.orig" ; rm -f "${tCurrent}"
getThumb "${current}" "${tCurrent}"
test $? -eq 0 || { echo "\t Failed to create thumbnail for existing wallpaper.\n" ; exit 1 ; }
test ${dbg} -eq 1 && eom "${tCurrent}"
###
### Prompt for selection of new wallpaper image
###
yad --width=500 \
--height=200 \
--borders=20 \
--title="${msgStrng[0]}" \
--fixed \
--text="<span foreground='orange'><b><big><big>\n${msgStrng[1]}</big></big></b></span>" \
--text-align=left \
--center \
--button="${msgStrng[2]}":1 \
--button="${msgStrng[3]}":0 \
--image="${tCurrent}"
if [ $? -ne 0 ]
then
echo -e "Login configuration specifying existing wallpaper not modified."
exit 0
fi
while true
do
# Let the user select an image
newImg=$(yad --file --center --title="Select an image" --width=1000 --height=500)
# If no image is selected, exit
test -z "${newImg}" && exit 1
# Check if the selected file is an image
mimeType=$(file --mime-type -b "${newImg}")
if [[ ${mimeType} =~ ^image/ ]]
then
break # Exit the loop if the file is a valid image
else
yad --title "Error" --width=400 --height=100 --center --button=OK:0 \
--text "The selected file is not an image. Please select a valid image file."
fi
done
newImg="${newImg}"
tNewImg="/tmp/$$.new" ; rm -f "${tNewImg}"
getThumb "${newImg}" "${tNewImg}"
test $? -eq 0 || { echo "\t Failed to create thumbnail for selected new wallpaper.\n" ; exit 1 ; }
test ${dbg} -eq 1 && eom "${tNewImg}"
###
### Setting up compound yad pane with 2 panels, to confirm choices and final action
###
# Generate a unique key for the plug mechanism
assemblyPlugPrivKey="${RANDOM}987"
test ${dbg} -eq 1 && echo ${assemblyPlugPrivKey}
# Panel dialog for first image in plug mode in background
yad --plug=${assemblyPlugPrivKey} \
--tabnum=1 \
--picture \
--filename="${tCurrent}" \
--size=fit \
--text-align=center \
--text="<span foreground='orange'><b><big>\n${msgStrng[4]}</big></b></span>" &
# Panel dialog for second image in plug mode in background
yad --plug=${assemblyPlugPrivKey} \
--tabnum=2 \
--picture \
--filename="${tNewImg}" \
--size=fit \
--text-align=center \
--text="<span foreground='orange'><b><big>\n${msgStrng[5]}</big></b></span>" &
# Display combined two-paned dialog using the background dialog plugs
yad --title="${msgStrng[6]}" \
--paned \
--key=${assemblyPlugPrivKey} \
--center \
--orient=Horizontal \
--splitter=275 \
--width=550 \
--height=300 \
--buttons-layout=spread \
--button="${msgStrng[7]}":1 \
--button="${msgStrng[8]}":0
if [ $? -ne 0 ]
then
echo -e "Login configuration specifying existing wallpaper not modified."
exit 0
fi
###
### Update the Login Greeter configuration to apply the selected change
###
# Get the file name without modification
imageName=$(basename "${newImg}")
# Final path in /usr/share/backgrounds
finalNewImg="${destDir}/${imageName}"
# Escape the apostrophes in the image path before running pkexec
# NOTE: maintaining single quotes in filenames is not recommended.
escapedNewImg=$(echo "${finalNewImg}" | sed "s/'/'\\\\''/g")
# Call pkexec to execute commands as root
pkexec bash -c "
# Copy the image and modify the schema
cp -f \"${newImg}\" \"${finalNewImg}\"
# Change permissions of the copied image to make it readable by others
chmod 644 "${finalNewImg}"
# Modify the schema file to set the new background image path
sed -i \"s|^background=.*|background='${escapedNewImg}'|\" \"${schemaFile}\"
# Compile the schemas
glib-compile-schemas /usr/share/glib-2.0/schemas/
"
# Display the final result
echo -e "\n Summary of applied changes:"
echo -e "\t File: '${schemaFile}'"
echo -e "\t Revised: $( grep "^background=" "${schemaFile}" ) \n"
notify-send "${msgStrng[9]}" "${msgStrng[10]}"
exit 0