diff options
Diffstat (limited to 'modules/scripts/activate-windows')
| -rw-r--r-- | modules/scripts/activate-windows/default.nix | 23 | ||||
| -rw-r--r-- | modules/scripts/activate-windows/script.sh | 90 |
2 files changed, 113 insertions, 0 deletions
diff --git a/modules/scripts/activate-windows/default.nix b/modules/scripts/activate-windows/default.nix new file mode 100644 index 0000000..441410f --- /dev/null +++ b/modules/scripts/activate-windows/default.nix @@ -0,0 +1,23 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit ((import ../lib.nix { inherit lib pkgs; })) mkScriptModule; + base = mkScriptModule { + name = "eww-active-windows"; + path = ./script.sh; + description = "Outputs JSON array of active windows for eww bar\nUsed by eww to display window icons in the sidebar"; + deps = [ + pkgs.bash + pkgs.jq + ]; + inherit config; + }; +in +{ + options = base.options; + config = base.moduleConfig; +} diff --git a/modules/scripts/activate-windows/script.sh b/modules/scripts/activate-windows/script.sh new file mode 100644 index 0000000..2abe394 --- /dev/null +++ b/modules/scripts/activate-windows/script.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash + +CACHE_FILE="${XDG_CACHE_HOME:-$HOME/.cache}/eww-icon-cache.tsv" +mkdir -p "$(dirname "$CACHE_FILE")" +touch "$CACHE_FILE" + +APP_DIRS=( + "$HOME/.local/share/applications" + "$HOME/.nix-profile/share/applications" + "/etc/profiles/per-user/$USER/share/applications" + "/run/current-system/sw/share/applications" + "$HOME/.local/share/flatpak/exports/share/applications" + "/var/lib/flatpak/exports/share/applications" +) + +ICON_DIRS=( + "$HOME/.local/share/icons" + "$HOME/.icons" + "$HOME/.nix-profile/share/icons" + "/etc/profiles/per-user/$USER/share/icons" + "/run/current-system/sw/share/icons" + "$HOME/.nix-profile/share/pixmaps" + "/run/current-system/sw/share/pixmaps" +) + +find_desktop_file() { + local id="$1" + for dir in "${APP_DIRS[@]}"; do + [ -d "$dir" ] || continue + local match + match=$(find "$dir" -maxdepth 1 -iname "${id}.desktop" 2>/dev/null | head -1) + [ -n "$match" ] && { echo "$match"; return; } + done + for dir in "${APP_DIRS[@]}"; do + [ -d "$dir" ] || continue + local match + match=$(grep -ilE "StartupWMClass=${id}$|^Name=${id}$" "$dir"/*.desktop 2>/dev/null | head -1) + [ -n "$match" ] && { echo "$match"; return; } + done +} + +find_icon_path() { + local icon_name="$1" + [ -z "$icon_name" ] && return + if [[ "$icon_name" == /* ]]; then + echo "$icon_name" + return + fi + for dir in "${ICON_DIRS[@]}"; do + [ -d "$dir" ] || continue + local match + match=$(find "$dir" -type f \( -iname "${icon_name}.svg" -o -iname "${icon_name}.png" -o -iname "${icon_name}.xpm" \) 2>/dev/null | sort -r | head -1) + [ -n "$match" ] && { echo "$match"; return; } + done +} + +resolve_icon() { + local app_id="$1" + local cached + cached=$(awk -F'\t' -v k="$app_id" '$1==k{print $2}' "$CACHE_FILE") + if [ -n "$cached" ]; then + echo "$cached" + return + fi + + local desktop_file icon_name icon_path + desktop_file=$(find_desktop_file "$app_id") + if [ -n "$desktop_file" ]; then + icon_name=$(grep -m1 '^Icon=' "$desktop_file" | cut -d= -f2-) + fi + icon_path=$(find_icon_path "$icon_name") + [ -z "$icon_path" ] && icon_path="$HOME/.config/eww/icons/fallback.svg" + + printf '%s\t%s\n' "$app_id" "$icon_path" >> "$CACHE_FILE" + echo "$icon_path" +} + +ws=$(niri msg -j workspaces) +active_id=$(echo "$ws" | jq '[.[] | select(.is_focused==true)][0].id') + +niri msg -j windows | jq -c --argjson wsid "$active_id" \ + '[.[] | select(.workspace_id == $wsid) | {app_id: (.app_id // "unknown"), title: (.title // "")}]' \ + | jq -c '.[]' \ + | while read -r win; do + app_id=$(jq -r '.app_id' <<< "$win") + title=$(jq -r '.title' <<< "$win") + icon=$(resolve_icon "$app_id") + jq -nc --arg app_id "$app_id" --arg title "$title" --arg icon "$icon" \ + '{app_id: $app_id, title: $title, icon: $icon}' + done | jq -sc '.' |
