dotfiles/de/home/.config/eww/scripts/bar/scratchpad
2025-03-12 16:00:01 -07:00

173 lines
5.1 KiB
Bash
Executable file

#!/bin/bash
#appropriated from https://gitlab.com/wef/dotfiles/-/blob/master/bin/sway-select-window for use with eww
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
}
}
}
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/icons/breeze-dark/mimetypes/32/unknown.svg"
[[ "$verbose" ]] && echo "using missing icon '$icon'" >&2
echo "$icon"
}
function get_scratchpad() {
applist_array=()
applist=""
shopt -s lastpipe
swaymsg -t get_tree |
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
applist_array_item=$(jq -n --arg icon "${icon}" --arg name "${app_name##*.}" --arg title "${win_title}" --arg win_id "${win_id}" '{icon: $icon,name: $name,title: $title,win_id: $win_id}')
applist_array+=("${applist_array_item}")
done
applist=$(printf '%s\n' "${applist_array[@]}" | jq -s .)
echo ${applist}
}
get_scratchpad
swaymsg -t subscribe '["window"]' --monitor | {
while read -r event; do
get_scratchpad
done
}