dotfiles/.config/hypr/UserScripts/WallpaperSelect.sh
2026-05-13 21:22:17 +02:00

262 lines
No EOL
8.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# ==================================================
# KoolDots (2026)
# Project URL: https://github.com/LinuxBeginnings
# License: GNU GPLv3
# SPDX-License-Identifier: GPL-3.0-or-later
# ==================================================
# This script for selecting wallpapers (SUPER W)
# WALLPAPERS PATH
terminal=kitty
PICTURES_DIR="$(xdg-user-dir PICTURES 2>/dev/null || echo "$HOME/Pictures")"
wallDIR="$PICTURES_DIR/wallpapers"
SCRIPTSDIR="$HOME/.config/hypr/scripts"
# shellcheck source=/dev/null
. "$SCRIPTSDIR/WallpaperCmd.sh"
wallpaper_current="$HOME/.config/hypr/wallpaper_effects/.wallpaper_current"
wallpaper_link="$HOME/.config/rofi/.current_wallpaper"
# Directory for swaync
iDIR="$HOME/.config/swaync/images"
iDIRi="$HOME/.config/swaync/icons"
# swww/awww transition config
FPS=60
TYPE="any"
DURATION=2
BEZIER=".43,1.19,1,.4"
if [[ "$WWW_CMD" == "swww" || "$WWW_CMD" == "awww" ]]; then
SWWW_PARAMS="--transition-fps $FPS --transition-type $TYPE --transition-duration $DURATION --transition-bezier $BEZIER"
else
SWWW_PARAMS=""
fi
# Check if package bc exists
if ! command -v bc &>/dev/null; then
notify-send -i "$iDIR/error.png" "bc missing" "Install package bc first"
exit 1
fi
# Variables
rofi_theme="$HOME/.config/rofi/config-wallpaper.rasi"
focused_monitor=$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')
per_monitor_wallpaper_current="$HOME/.config/hypr/wallpaper_effects/.wallpaper_current_${focused_monitor}"
per_monitor_wallpaper_link="$HOME/.config/rofi/.current_wallpaper_${focused_monitor}"
# Ensure focused_monitor is detected
if [[ -z "$focused_monitor" ]]; then
notify-send -i "$iDIR/error.png" "E-R-R-O-R" "Could not detect focused monitor"
exit 1
fi
# Monitor details
scale_factor=$(hyprctl monitors -j | jq -r --arg mon "$focused_monitor" '.[] | select(.name == $mon) | .scale')
monitor_height=$(hyprctl monitors -j | jq -r --arg mon "$focused_monitor" '.[] | select(.name == $mon) | .height')
icon_size=$(echo "scale=1; ($monitor_height * 3) / ($scale_factor * 150)" | bc)
adjusted_icon_size=$(echo "$icon_size" | awk '{if ($1 < 15) $1 = 20; if ($1 > 25) $1 = 25; print $1}')
rofi_override="element-icon{size:${adjusted_icon_size}%;}"
# Kill existing wallpaper daemons for video
kill_wallpaper_for_video() {
"$WWW_CMD" kill 2>/dev/null
pkill mpvpaper 2>/dev/null
pkill swaybg 2>/dev/null
pkill hyprpaper 2>/dev/null
}
# Kill existing wallpaper daemons for image
kill_wallpaper_for_image() {
pkill mpvpaper 2>/dev/null
pkill swaybg 2>/dev/null
pkill hyprpaper 2>/dev/null
}
# Retrieve wallpapers (both images & videos)
mapfile -d '' PICS < <(find -L "${wallDIR}" -type f \( \
-iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.gif" -o \
-iname "*.bmp" -o -iname "*.tiff" -o -iname "*.webp" -o \
-iname "*.mp4" -o -iname "*.mkv" -o -iname "*.mov" -o -iname "*.webm" \) -print0)
RANDOM_PIC="${PICS[$((RANDOM % ${#PICS[@]}))]}"
RANDOM_PIC_NAME="$(basename "$RANDOM_PIC")"
CURRENT_MON_PIC_PATH=$("$WWW_CMD" query 2>/dev/null | grep "$focused_monitor" | awk '{print $NF}')
if [[ -z "$CURRENT_MON_PIC_PATH" ]]; then
if [[ -L "$wallpaper_link" ]]; then
CURRENT_MON_PIC_PATH="$(readlink -f "$wallpaper_link")"
elif [[ -f "$wallpaper_link" ]]; then
CURRENT_MON_PIC_PATH="$wallpaper_link"
elif [[ -f "$wallpaper_current" ]]; then
CURRENT_MON_PIC_PATH="$wallpaper_current"
fi
fi
CURRENT_MON_PIC_NAME=$(basename "$CURRENT_MON_PIC_PATH")
# Rofi command
rofi_command="rofi -i -show -dmenu -config $rofi_theme -theme-str $rofi_override"
# Sorting Wallpapers
menu() {
IFS=$'\n' sorted_options=($(sort <<<"${PICS[*]}"))
printf "%s\x00icon\x1f%s\n" "Random: $RANDOM_PIC_NAME" "$RANDOM_PIC"
if [[ -n "$CURRENT_MON_PIC_PATH" ]]; then
printf "%s\x00icon\x1f%s\n" "Current: $CURRENT_MON_PIC_NAME" "$CURRENT_MON_PIC_PATH"
fi
for pic_path in "${sorted_options[@]}"; do
pic_name=$(basename "$pic_path")
if [[ "$pic_name" =~ \.gif$ ]]; then
cache_gif_image="$HOME/.cache/gif_preview/${pic_name}.png"
if [[ ! -f "$cache_gif_image" ]]; then
mkdir -p "$HOME/.cache/gif_preview"
magick "$pic_path[0]" -resize 1920x1080 "$cache_gif_image"
fi
printf "%s\x00icon\x1f%s\n" "$pic_name" "$cache_gif_image"
elif [[ "$pic_name" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
cache_preview_image="$HOME/.cache/video_preview/${pic_name}.png"
if [[ ! -f "$cache_preview_image" ]]; then
mkdir -p "$HOME/.cache/video_preview"
ffmpeg -v error -y -i "$pic_path" -ss 00:00:01.000 -vframes 1 "$cache_preview_image"
fi
printf "%s\x00icon\x1f%s\n" "$pic_name" "$cache_preview_image"
else
printf "%s\x00icon\x1f%s\n" "$pic_name" "$pic_path"
fi
done
}
modify_startup_config() {
local selected_file="$1"
local startup_config="$HOME/.config/hypr/UserConfigs/Startup_Apps.conf"
# Check if it's a live wallpaper (video)
if [[ "$selected_file" =~ \.(mp4|mkv|mov|webm)$ ]]; then
# For video wallpapers:
sed -i '/^\s*exec-once\s*=\s*\$scriptsDir\/WallpaperDaemon\.sh\s*$/s/^/\#/' "$startup_config"
sed -i '/^\s*exec-once\s*=\s*swww-daemon\s*--format\s*xrgb\s*$/s/^/\#/' "$startup_config"
sed -i '/^\s*#\s*exec-once\s*=\s*mpvpaper\s*.*$/s/^#\s*//;' "$startup_config"
# Update the livewallpaper variable with the selected video path (using $HOME)
selected_file="${selected_file/#$HOME/\$HOME}" # Replace /home/user with $HOME
sed -i "s|^\$livewallpaper=.*|\$livewallpaper=\"$selected_file\"|" "$startup_config"
echo "Configured for live wallpaper (video)."
else
# For image wallpapers:
sed -i '/^\s*#\s*exec-once\s*=\s*\$scriptsDir\/WallpaperDaemon\.sh\s*$/s/^\s*#\s*//;' "$startup_config"
sed -i '/^\s*#\s*exec-once\s*=\s*swww-daemon\s*--format\s*xrgb\s*$/s/^\s*#\s*//;' "$startup_config"
sed -i '/^\s*exec-once\s*=\s*mpvpaper\s*.*$/s/^/\#/' "$startup_config"
echo "Configured for static wallpaper (image)."
fi
}
# Apply Image Wallpaper
apply_image_wallpaper() {
local image_path="$1"
kill_wallpaper_for_image
if ! pgrep -x "$WWW_DAEMON" >/dev/null; then
echo "Starting $WWW_DAEMON..."
"$WWW_DAEMON" "${WWW_DAEMON_ARGS[@]}" &
fi
# Wait for daemon to be ready before applying
for _ in {1..20}; do
"$WWW_CMD" query >/dev/null 2>&1 && break
sleep 0.1
done
"$WWW_CMD" img -o "$focused_monitor" "$image_path" $SWWW_PARAMS || {
sleep 0.2
"$WWW_CMD" img -o "$focused_monitor" "$image_path" $SWWW_PARAMS
}
"$WWW_CMD" img -o "$focused_monitor" "$image_path" $SWWW_PARAMS
# Persist per-monitor wallpaper selection
mkdir -p "$(dirname "$per_monitor_wallpaper_current")" "$(dirname "$per_monitor_wallpaper_link")"
ln -sf "$image_path" "$per_monitor_wallpaper_link" || true
cp -f "$image_path" "$per_monitor_wallpaper_current" || true
# Run additional scripts (pass the image path to avoid cache race conditions)
"$SCRIPTSDIR/WallustSwww.sh" "$image_path"
sleep 2
"$SCRIPTSDIR/Refresh.sh"
sleep 1
}
apply_video_wallpaper() {
local video_path="$1"
# Check if mpvpaper is installed
if ! command -v mpvpaper &>/dev/null; then
notify-send -i "$iDIR/error.png" "E-R-R-O-R" "mpvpaper not found"
return 1
fi
kill_wallpaper_for_video
# Apply video wallpaper using mpvpaper
mpvpaper '*' -o "load-scripts=no no-audio --loop" "$video_path" &
}
# Main function
main() {
choice=$(menu | $rofi_command)
choice=$(echo "$choice" | xargs)
RANDOM_PIC_NAME=$(echo "$RANDOM_PIC_NAME" | xargs)
raw_choice="$choice"
choice="${choice#Random: }"
choice="${choice#Current: }"
if [[ -z "$choice" ]]; then
echo "No choice selected. Exiting."
exit 0
fi
# Resolve selection directly when using Random/Current entries
if [[ "$raw_choice" == Random:\ * ]]; then
selected_file="$RANDOM_PIC"
elif [[ "$raw_choice" == Current:\ * && -n "$CURRENT_MON_PIC_PATH" ]]; then
selected_file="$CURRENT_MON_PIC_PATH"
elif [[ -f "$choice" ]]; then
selected_file="$choice"
else
# Handle random selection by name when needed
if [[ "$choice" == "$RANDOM_PIC_NAME" ]]; then
choice=$(basename "$RANDOM_PIC")
fi
choice_basename=$(basename "$choice" | sed 's/\(.*\)\.[^.]*$/\1/')
# Search for the selected file in the wallpapers directory, including subdirectories
selected_file=$(find "$wallDIR" -iname "$choice_basename.*" -print -quit)
fi
if [[ -z "$selected_file" ]]; then
echo "File not found. Selected choice: $choice"
exit 1
fi
# Modify the Startup_Apps.conf file based on wallpaper type
modify_startup_config "$selected_file"
# **CHECK FIRST** if it's a video or an image **before calling any function**
if [[ "$selected_file" =~ \.(mp4|mkv|mov|webm|MP4|MKV|MOV|WEBM)$ ]]; then
apply_video_wallpaper "$selected_file"
else
apply_image_wallpaper "$selected_file"
fi
}
# Check if rofi is already running
if pidof rofi >/dev/null; then
pkill rofi
fi
main