From 3fe005b4d29b55ba7a177908256dbdc3d499f405 Mon Sep 17 00:00:00 2001 From: Penelope Gwen Date: Tue, 11 Mar 2025 20:45:06 -0700 Subject: [PATCH] New backup 2025-03-11 20:45:06 --- de/home/.config/eww/scripts/bar/scratchpad | 176 +++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100755 de/home/.config/eww/scripts/bar/scratchpad diff --git a/de/home/.config/eww/scripts/bar/scratchpad b/de/home/.config/eww/scripts/bar/scratchpad new file mode 100755 index 0000000..4757ef7 --- /dev/null +++ b/de/home/.config/eww/scripts/bar/scratchpad @@ -0,0 +1,176 @@ +#!/bin/bash + +declare -A icons=( +) + +jq_get_windows=' + # descend to workspace or scratchpad + .nodes[0].nodes[0] + # save workspace name as .w + | {"w": .name} + ( + if (.nodes|length) > 0 then # workspace + [recurse(.nodes[])] + else # scratchpad + [] + end + + .floating_nodes + | .[] + # select nodes with no children (windows) + | select(.nodes==[]) + )' + +jq_windows_to_tsv=' + [ + (.id | tostring), + # remove markup and index from workspace name, replace scratch with "[S]" + (.w | gsub("<[^>]*>|:$"; "") | sub("__i3_scratch"; "[S]")), + # get app name (or window class if xwayland) + (.app_id // .window_properties.class), + (.name), + (.pid) + ] + | @tsv' + +get_hardcoded_icon() { + icon="${icons[$1]}" + echo "$icon" +} + +get_desktop() { + app="$1" + p="/usr/share/applications" + + # fast and easy cases first: + for prefix in "" org.kde. org.gnome. org.freedesktop.; do + d="$p/$prefix$app.desktop" + [[ -r "$d" ]] && { + echo "$d" + [[ "$verbose" ]] && echo "found '$d'" >&2 + return + } + done + + # maybe lowercase + for prefix in "" org.kde. org.gnome. org.freedesktop.; do + d="$p/$prefix${app,,}.desktop" + [[ -r "$d" ]] && { + echo "$d" + [[ "$verbose" ]] && echo "found '$d'" >&2 + return + } + done + + # this is fairly reliable but slow: + # look for a .desktop file with Exec=$app eg + # gnome-disks (but exclude gnome-disk-image-writer.desktop) + # gnome-font-viewer + GREP='egrep -r' + type rg &>/dev/null && GREP=rg + d=$( $GREP -il "^exec=$app( %u)*[[:space:]]*$" $p | head -n 1) + [[ -r "$d" ]] && { + echo "$d" + [[ "$verbose" ]] && echo "found '$d'" >&2 + return + } + + # desperation - weird apps like com.github.wwmm.pulseeffects.desktop!! + # shellcheck disable=SC2012 + d=$( ls "$p/"*".$app.desktop" 2>/dev/null | head -n 1 ) + [[ -r "$d" ]] && { + echo "$d" + [[ "$verbose" ]] && echo "found '$d'" >&2 + return + } +} + +get_icon() { + app="$1" + + icon=$( get_hardcoded_icon "$app_name" ) + [[ "$icon" && -r "$icon" ]] && { + echo "$icon" + [[ "$verbose" ]] && echo "using hardcoded icon '$icon'" >&2 + return + } + + # let's go poke in the .desktop files: + icon_name="" + dt=$( get_desktop "$app" ) + + # sometimes we get the 'class' rather than the exe - so try this: + [[ "$dt" ]] || { + app=$( tr '\0' '\n' < "/proc/$pid/cmdline" | head -n 1 ) + dt=$( get_desktop "$( basename "$app" )" ) + } + + [[ "$dt" ]] && { + icon_name=$( awk -v IGNORECASE="set" -F"=" '/^icon/ {print $2}' "$dt" ) + [[ -r "$icon_name" ]] && { + icon="$icon_name" + echo "$icon" + [[ "$verbose" ]] && echo "using .desktop icon '$icon'" >&2 + return + } + [[ "$icon_name" ]] && { + icon_locations=( + icons/hicolor/scalable/apps + icons/hicolor/48x48/apps + icons/gnome/48x48/apps + icons/gnome/48x48/devices + pixmaps + ) + for d in "${icon_locations[@]}"; do + for s in .svg .png .xpm ""; do + icon=/usr/share/$d/$icon_name$s + [[ -r $icon ]] && { + echo "$icon" + [[ "$verbose" ]] && echo "using .desktop icon '$icon'" >&2 + return + } + done + done + icon=$(find /usr/share/icons | grep "/${icon_name}-symbolic.svg" | head -n 1) + [[ -r $icon ]] && { + echo "$icon" + [[ "$verbose" ]] && echo "using .desktop icon '$icon'" >&2 + return + } + } + } + + # desperation street: + icon=$( find /usr/share/icons /usr/share/pixmaps | grep -E -i "/$app.(png|svg)" | head -n 1 ) + [[ "$icon" && -r "$icon" ]] && { + echo "$icon" + [[ "$verbose" ]] && echo "using found icon '$icon'" >&2 + return + } + + # failed: + icon="/usr/share/gtk-doc/html/gtk2/image-missing.png" + [[ "$verbose" ]] && echo "using missing icon '$icon'" >&2 + echo "$icon" +} + +id_fmt='%s' +ws_fmt='%s' +app_fmt='%-15.15s' +title_fmt='%s' + +swaymsg -t get_tree | +# get list of windows as tab-separated columns +jq -r "$jq_get_windows | $jq_windows_to_tsv" | +column -s $'\t' -o $'\t' -t | while IFS=$'\t' read -r win_id ws_name app_name win_title pid; do + shopt -s extglob + app_name="${app_name%%*( )}" + icon=$( get_icon "$app_name" "$pid" ) + [[ "$verbose" ]] && printf "[%s]=%s\n" "$app_name" "$icon" >&2 + # shellcheck disable=SC2059 + printf "img:$icon:text:${id_fmt}\t${app_fmt}\t${ws_fmt}\t${title_fmt}\n" \ + "$win_id" \ + "${app_name##*.}" \ + "$ws_name" \ + "$win_title" +done | +sort -k3 -k2 +#wofi --cache-file=/dev/null --insensitive --allow-images --show dmenu --prompt='Focus a window'