Hardened script to prevent waybar crashing

This commit is contained in:
2026-02-26 15:17:06 +01:00
parent d247670230
commit e7f2e72cfb
@@ -1,42 +1,49 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
COLUMN_WIDTH="${COLUMN_WIDTH:-0.5}" # match your hyprscrolling config COLUMN_WIDTH="${COLUMN_WIDTH:-0.5}"
ICON="${ICON:-󰓒}" # nerd-font icon ICON="${ICON:-󰓒}"
# Focused monitor id (numeric) + its active workspace id (numeric) # Always output valid JSON, even on error
fail_json() {
printf '{"text":"%s !","tooltip":"hyprscroll-overflow: %s","class":"error"}\n' "$ICON" "${1//\"/\\\"}"
exit 0
}
command -v hyprctl >/dev/null 2>&1 || fail_json "hyprctl not in PATH"
command -v jq >/dev/null 2>&1 || fail_json "jq not in PATH"
# Focused monitor id + its active workspace id (both numeric)
read -r focused_mon_id focused_ws_id < <( read -r focused_mon_id focused_ws_id < <(
hyprctl -j monitors | jq -r ' hyprctl -j monitors 2>/dev/null | jq -r '
.[] | select(.focused==true) | "\(.id) \(.activeWorkspace.id)" .[] | select(.focused==true) | "\(.id) \(.activeWorkspace.id)"
' ' 2>/dev/null
) ) || fail_json "failed to read monitors"
# Fallback if something went wrong (shouldn't happen) [[ -n "${focused_mon_id:-}" && -n "${focused_ws_id:-}" ]] || fail_json "no focused monitor?"
focused_mon_id="${focused_mon_id:-0}"
focused_ws_id="${focused_ws_id:-1}"
# Count mapped windows on the focused monitor + its active workspace. # Count mapped windows on that monitor+workspace
win_count="$( win_count="$(
hyprctl -j clients | jq --argjson ws "$focused_ws_id" --argjson mid "$focused_mon_id" ' hyprctl -j clients 2>/dev/null | jq --argjson ws "$focused_ws_id" --argjson mid "$focused_mon_id" '
[ .[] [ .[]
| select(.mapped == true) | select(.mapped == true)
| select(.workspace.id == $ws) | select(.workspace.id == $ws)
| select(.monitor == $mid) | select(.monitor == $mid)
] | length ] | length
' ' 2>/dev/null
)" )" || fail_json "failed to count clients"
# floor(1 / COLUMN_WIDTH) using awk (portable) # floor(1 / COLUMN_WIDTH)
max_visible="$(awk -v w="$COLUMN_WIDTH" 'BEGIN{ if (w<=0) {print 1} else {print int(1.0/w)} }')" max_visible="$(awk -v w="$COLUMN_WIDTH" 'BEGIN{ if (w<=0) {print 1} else {print int(1.0/w)} }')" || fail_json "awk failed"
if [ "$max_visible" -lt 1 ]; then max_visible=1; fi (( max_visible < 1 )) && max_visible=1
overflow=$(( win_count - max_visible )) overflow=$(( win_count - max_visible ))
if [ "$overflow" -gt 0 ]; then if (( overflow > 0 )); then
printf '{"text":"%s +%d","tooltip":"%d windows on this monitor/workspace, approx %d fit (column_width=%s)","class":"overflow"}\n' \ printf '{"text":"%s +%d","tooltip":"%d windows; approx %d fit (column_width=%s)","class":"overflow"}\n' \
"$ICON" "$overflow" "$win_count" "$max_visible" "$COLUMN_WIDTH" "$ICON" "$overflow" "$win_count" "$max_visible" "$COLUMN_WIDTH"
else else
# keep hidden when OK (set text to something like "" if you want it always visible) # If you want it visible even when OK, change "" to "•"
printf '{"text":"TEST ELSE","tooltip":"%d windows, approx %d fit","class":"ok"}\n' \ printf '{"text":"","tooltip":"%d windows; approx %d fit","class":"ok"}\n' \
"$win_count" "$max_visible" "$win_count" "$max_visible"
fi fi