#!/usr/bin/env bash # Description: # Change the desktop wallpaper and generate a blurred version. # # Requirs: # - zenity (for file selection dialog) # - imagemagick (for image processing) # - swww (wallpaper daemon) # - notify-send (for notifications) # - change-colortheme (from scripts/change-colortheme) # - flock (usually part of util-linux) set -euo pipefail # Lock exec {LOCK_FD}>/tmp/"$(basename "$0")".lock flock -n "$LOCK_FD" || { echo "Another instance is running. Exiting." # notify-send -a "change-wallpaper" "Error" "Another instance is running. Exiting." exit 1 } # Open a file selection dialog if no argument is provided if [ -z "${1-}" ]; then image=$(zenity --file-selection --title="Open File" --file-filter="*.jpg *.jpeg *.png *.webp *.bmp *.jfif *.tiff *.avif *.heic *.heif") else image="$1" fi [ -z "$image" ] && exit 1 [ ! -f "$image" ] && exit 1 # Obtain screen resolution screen_width=${2-} screen_height=${3-} [ -z "$screen_width" ] && { if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then screen_width=$(hyprctl -j monitors | jq '.[0].resolution.x') elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then screen_width=$(niri msg focused-output | grep 'Current mode' | awk '{print $3}' | cut -d'x' -f1) fi } [ -z "$screen_height" ] && { if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then screen_height=$(hyprctl -j monitors | jq '.[0].resolution.y') elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then screen_height=$(niri msg focused-output | grep 'Current mode' | awk '{print $3}' | cut -d'x' -f2) fi } ## Default to 2k screen_width=${screen_width:-2560} screen_height=${screen_height:-1440} # $HOME/.config/wallpaper-chooser/config.json: # ```json # "sort": { # "type": "date", # "reverse": true # } # ``` # So in order to let the most recently used wallpapers appear first: touch "$image" 2>/dev/null || true # ignore errors # Copy image to local wallpaper directory ## Format of current and cached wallpaper wallpaper_ext="png" ## Generate a random name for the current wallpaper set +o pipefail # SIGPIPE is expected here random_name=$(tr -dc 'a-zA-Z0-9' /dev/null 2>/dev/null fi # notify-send -a "change-wallpaper" "Blurred Wallpaper Applied" "$blurred_image" -i "$blurred_image" } ### Check if cached blurred image exists if [ -f "$blurred_cache_image" ]; then # sleep 1 # Some ugly workaround if ! cp -f "$blurred_cache_image" "$blurred_image"; then echo "Could not copy cached blurred image" # exit 1 # Non-critical error else apply_blured exit 0 fi fi sigma=$(magick identify -format "%w %h" "$wallpaper_image" | awk -v f=0.01 '{ m=($1>$2)?$1:$2; s=m*f; if(s<2) s=2; if(s>200) s=200; printf "%.2f", s }') ### Batch processing using a temporary file to avoid incomplete file being used temp_blurred=$(mktemp --suffix=."$wallpaper_ext") || exit 1 trap 'rm -f "${temp_blurred}"' EXIT magick "$wallpaper_image" -blur 0x"$sigma" "$temp_blurred" || { echo "Could not create blurred image" exit 1 } mv -f "$temp_blurred" "$blurred_image" || { echo "Could not move blurred image to cache directory" exit 1 } cp -f "$blurred_image" "$blurred_cache_image" || { echo "Could not cache blurred image" # exit 1 # Non-critical error } apply_blured ) & # Apply wallpaper skip_colortheme=0 if [ "${4-}" = "--skip-colortheme" ]; then skip_colortheme=1 fi if [ "$XDG_CURRENT_DESKTOP" = "Hyprland" ]; then swww img -n background "$wallpaper_image" --transition-type fade --transition-duration 2 >/dev/null 2>/dev/null # notify-send -a "change-wallpaper" "Wallpaper Changed" "$image" -i "$wallpaper_image" if [ "$skip_colortheme" = 0 ]; then change-colortheme -i "$wallpaper_image" || exit 1 fi elif [ "$XDG_CURRENT_DESKTOP" = "niri" ]; then ### Handled in wallpaper-daemon # swww img -n background "$wallpaper_image" --transition-type fade --transition-duration 2 > /dev/null 2> /dev/null # notify-send -a "change-wallpaper" "Wallpaper Changed" "$image" -i "$wallpaper_image" if [ "$skip_colortheme" = 0 ]; then change-colortheme -i "$wallpaper_image" || exit 1 fi else echo "Unsupported desktop environment: $XDG_CURRENT_DESKTOP" exit 1 fi