Skip to content

Instantly share code, notes, and snippets.

@hydren
Last active October 27, 2023 00:03
Show Gist options
  • Save hydren/e5ce82a79c2a4c4203491534613a6915 to your computer and use it in GitHub Desktop.
Save hydren/e5ce82a79c2a4c4203491534613a6915 to your computer and use it in GitHub Desktop.
Modified version of Hans Möller's stitchWP.sh to specify different wallpaper image per monitor.
#!/usr/bin/env bash
# 2018 Hans P. Möller <[email protected]>
################################################################################
# This script is a workaround for the lack of support from pcfman-qt
# for differenct wallpaper images for each display environment. pcmanfm-qt handle
# all the monitors as only one big monitor. This script takes the configuration
# from pcfman-qt and replicate it in all the monitors creating a big canvas
# and stitching a different image to it. The steps are
# 1) Takes the pxfman-qt configuration
# 2) Reads information about the images passed as argument to this script.
# 2) It takes current display configuration from xrandr.
# 3) Create new wallpaper image joining specified images for each monitor
# 4) Updates the wallpaper with the created image
#
# To use it, specify any wallpaper as you usually do (to set a wallpaper mode),
# then run this script.
# Usage: stitchWPmod.sh [wallpaperImage]
# You need to specify one wallpaper per monitor.
################################################################################
PROFILE="lxqt" #profile used when running pcmanfm-qt --desktop
wpNew="$HOME/.config/pcmanfm-qt/$PROFILE/stitchWP.jpg" #where wallpaper is saved
settingsFile="$HOME/.config/pcmanfm-qt/$PROFILE/settings.conf"
changeWP="pcmanfm-qt --set-wallpaper" #command to use to change the wallpaper
#########################################################################
#Get actual wallpaper configuration
#wpFile=$(grep 'Wallpaper=' $settingsFile)
#wpFile=${wpFile:10}
wpM=$(grep 'WallpaperMode=' $settingsFile)
wpM=${wpM:14}
wpBg=$(grep 'BgColor=' $settingsFile)
wpBg=${wpBg:8}
#if [ $wpFile == $wpNew ]; then
# exit
#fi
if [ $# -eq 0 ]; then
echo "No images provided, stop"
exit
fi
wImage=()
hImage=()
for (( i=1; i <= "$#"; i++ )); do
#Get dimensions of each image file specified in cmd line arguments
imageFile="${!i}"
imageInfo=$(identify "$imageFile" | grep -o '[1-9][0-9]*x[1-9][0-9]* ')
IFS='x'
j=0
for STRING in $imageInfo; do
case $j in
0)
wImage[$i]=$STRING;;
1)
hImage[$i]=$STRING;;
esac
j=$((j + 1))
done
done
for ((i=1; i <= $# ; i++)); do
echo ${wImage[$i]}
done
case $wpM in
tile)
exit;;
none)
exit;;
esac
################################################################################
# Get current display configurator
# xrandr regex, + don't have to be escaped in grep.
XOUT=$(xrandr | grep -oe 'current [1-9][0-9]* x [1-9][0-9]*' -oe '[1-9][0-9]*x[1-9][0-9]*+[0-9]*+[0-9]*')
IFS=$'\n' #separate to lines with internal field separator
dispNumber=0
for LINE in $XOUT; do
array[$dispNumber]=$LINE
dispNumber=$((dispNumber + 1))
done
dispNumber=$((dispNumber - 1)) #number of displays used
#parse the total screen xinerama size.
IFS=' ' #separate to lines with internal field separator
i=0
for STRING in ${array[0]}; do
case $i in
1)
canvasW=$STRING;;
3)
canvasH=$STRING;;
esac
i=$((i + 1))
done
#Parse each screen size and position
for ((i=1; i <= $dispNumber ; i++)); do
IFS='x'
j=0
for STRING in ${array[$i]}; do
case $j in
0)
w[$i]=$STRING
;;
1)
IFS='+'
k=0
for CHUNK in $STRING; do
case $k in
0)
h[$i]=$CHUNK;;
1)
x[$i]=$CHUNK;;
2)
y[$i]=$CHUNK;;
esac
k=$((k + 1))
done
esac
j=$((j + 1))
done
done
case $wpM in
stretch)
newImage="convert -size "$canvasW"x"$canvasH" xc:"$wpBg""
for ((i=1; i <= $dispNumber ; i++)); do
newImage="$newImage -draw \"image over ${x[$i]},${y[$i]} ${w[$i]},${h[$i]} '"${!i}"'\""
done
newImage="$newImage $wpNew"
echo $newImage
eval $newImage
;;
fit)
#mantain aspect ratio, fit the screen from the inside,
#could not cover the whole screen background color could be seen.
newImage="convert -size "$canvasW"x"$canvasH" xc:"$wpBg" "
for ((i=1; i <= $dispNumber ; i++)); do
wRatio[$i]=$((${w[$i]} * 100 / wImage[$i]))
#echo ${wRatio[$i]}
hRatio[$i]=$((${h[$i]} * 100 / hImage[$i]))
#echo ${hRatio[$i]}
if [ ${wRatio[$i]} -lt ${hRatio[$i]} ]; then #fit horizontal, space up and down.
Y=$((hImage[$i] * wRatio[$i] / 100))
Y=$((${h[$i]} - $Y))
Y=$(($Y / 2 + y[i]))
W=$((wImage[$i] * wRatio[$i] / 100))
H=$((hImage[$i] * wRatio[$i] / 100))
newImage="$newImage -draw \"image over ${x[$i]},$Y $W,$H '"${!i}"'\""
else #fit vertical, space on sides
X=$((wImage[$i] * hRatio[$i] / 100))
X=$((${w[$i]} - $X))
X=$(($X / 2 + x[i]))
W=$((wImage[$i] * hRatio[$i] / 100))
H=$((hImage[$i] * hRatio[$i] / 100))
newImage="$newImage -draw \"image over $X,${y[$j]} $W,$H '"${!i}"'\""
fi
done
newImage="$newImage $wpNew"
echo $newImage
eval $newImage
;;
center) #image is NOT scaled. If image is not cropped n+1 could superpose x<n+1 image
#TODO
;;
zoom) #image is scaled maintaining ratio, MUST cover the whole screen, pieces of image could be of of screen; if image is not cropped n+1 could superpose x<n+1 image
IFS=' '
newImage="convert -respect-parenthesis -size "$canvasW"x"$canvasH" xc:"$wpBg" "
for ((i=1; i <= $dispNumber ; i++)); do
#echo "i=$i, !i=${!i}, w[i]=${w[$i]}, h[i]=${h[$i]}, x[i]=${x[$i]}, y[i]=${y[$i]}"
newImage="$newImage \( '"${!i}"' -resize ${w[$i]}x${h[$i]}^ -gravity center -extent ${w[$i]}x${h[$i]} \) -geometry +${x[$i]}+${y[$i]} -composite "
#echo $newImage
done
newImage="$newImage $wpNew"
echo $newImage
eval $newImage
;;
#tile) #not needed
#none) #not needed
esac
#Set another wallpaper to force update
prechangeWP="$changeWP \"$1\""
eval $prechangeWP
#Set New Wallpaper
changeWP="$changeWP $wpNew"
echo $changeWP
eval $changeWP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment