#!/bin/bash # omarchy:summary=Open a generic image selector menu # omarchy:args=[--selected ] [--colors-file ] [--print-name] ... OMARCHY_PATH=${OMARCHY_PATH:-$HOME/.local/share/omarchy} selected_image="" colors_file="" print_name=false image_dirs=() while [[ $# -gt 0 ]]; do case "$1" in --selected) selected_image="$2" shift 2 ;; --colors-file) colors_file="$2" shift 2 ;; --print-name) print_name=true shift ;; --help|-h) echo "Usage: omarchy-menu-images [--selected ] [--colors-file ] [--print-name] ..." exit 0 ;; *) image_dirs+=("$1") shift ;; esac done if (( ${#image_dirs[@]} == 0 )); then echo "Usage: omarchy-menu-images [--selected ] [--colors-file ] [--print-name] ..." >&2 exit 1 fi selection_file=$(mktemp) done_file=$(mktemp) rm -f "$done_file" trap 'rm -f "$selection_file" "$done_file"' EXIT socket_path="${XDG_RUNTIME_DIR:-/run/user/$UID}/omarchy-image-selector.sock" selector_qml="$OMARCHY_PATH/default/quickshell/wallpaper-switcher.qml" image_dirs_env="" for dir in "${image_dirs[@]}"; do if [[ -z $image_dirs_env ]]; then image_dirs_env="$dir" else image_dirs_env+=$'\n'"$dir" fi done current_image=$(readlink -f "$selected_image" 2>/dev/null) selected_list_image="" if [[ -n $current_image ]]; then for dir in "${image_dirs[@]}"; do if [[ -d $dir && -f $selected_image && ${selected_image%/*} == "$dir" ]]; then selected_list_image="$selected_image" break elif [[ -d $dir ]]; then selected_list_image=$(find -L "$dir" -maxdepth 1 -type f -samefile "$current_image" -print -quit 2>/dev/null) [[ -n $selected_list_image ]] && break fi done fi cache_dir=${XDG_CACHE_HOME:-$HOME/.cache}/omarchy/image-selector index_file="$cache_dir/index.tsv" rows="" mkdir -p "$cache_dir" cache_key=$(printf '%s' "$image_dirs_env" | md5sum | cut -d ' ' -f 1) rows_cache_file="$cache_dir/$cache_key.rows" rows_signature_file="$cache_dir/$cache_key.signature" rows_signature="" for dir in "${image_dirs[@]}"; do if [[ -d $dir ]]; then rows_signature+="$dir:$(stat -Lc '%Y' "$dir")"$'\n' fi done thumbnail_for() { local image="$1" local signature hash thumbnail signature=$(stat -Lc '%s:%Y' "$image") || return hash=$(awk -F '\t' -v path="$image" -v sig="$signature" '$1 == path && $2 == sig { print $3; exit }' "$index_file" 2>/dev/null) if [[ -z $hash ]]; then hash=$(md5sum "$image" | cut -d ' ' -f 1) printf '%s\t%s\t%s\n' "$image" "$signature" "$hash" >>"$index_file" fi thumbnail="$cache_dir/$hash.jpg" if [[ ! -f $thumbnail ]]; then magick "$image" -auto-orient -resize '1536x864^' -gravity center -extent '1536x864' -strip -quality 82 "$thumbnail" fi printf '%s' "$thumbnail" } if [[ -f $rows_cache_file && -f $rows_signature_file ]] && cmp -s "$rows_signature_file" <(printf '%s' "$rows_signature"); then rows=$(<"$rows_cache_file") else for dir in "${image_dirs[@]}"; do if [[ -d $dir ]]; then while IFS= read -r -d '' image; do thumbnail=$(thumbnail_for "$image") [[ -n $thumbnail ]] || continue if [[ -z $rows ]]; then rows="$image"$'\t'"$thumbnail" else rows+=$'\n'"$image"$'\t'"$thumbnail" fi done < <(find -L "$dir" -maxdepth 1 -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) -print0 2>/dev/null) fi done printf '%s' "$rows" >"$rows_cache_file" printf '%s' "$rows_signature" >"$rows_signature_file" fi rows_payload=${rows//$'\t'/$'\f'} rows_payload=${rows_payload//$'\n'/$'\v'} if [[ -S $socket_path && $selector_qml -nt $socket_path ]]; then quickshell kill -p "$selector_qml" >/dev/null 2>&1 || true rm -f "$socket_path" fi if [[ ! -S $socket_path ]]; then quickshell kill -p "$selector_qml" >/dev/null 2>&1 || true quickshell -d -p "$selector_qml" >/dev/null for ((i = 0; i < 100; i++)); do if [[ -S $socket_path ]]; then break fi sleep 0.01 done fi if [[ ! -S $socket_path ]]; then echo "Image selector failed to start" >&2 exit 1 fi printf '%s\t%s\t%s\t%s\t%s\n' "$rows_payload" "$selected_list_image" "$selection_file" "$done_file" "$colors_file" | socat -u - "UNIX-CONNECT:$socket_path" while [[ ! -e $done_file ]]; do sleep 0.01 done if [[ -s $selection_file ]]; then if [[ $print_name == true ]]; then selection=$(<"$selection_file") selection=${selection##*/} printf '%s\n' "${selection%.*}" else cat "$selection_file" fi fi