Indicate and jump to tmux panes waiting for attention

Show a bar indicator whenever tmux has flagged a window, the same state
that highlights the tab, and jump to it on click or with Super + Ctrl + J.
Tmux hooks push the state to the shell, so nothing polls while no pane is
waiting.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-23 17:40:47 -07:00
co-authored by Claude Opus 4.8
parent 98e88723ae
commit a382be2645
9 changed files with 252 additions and 1 deletions
+1
View File
@@ -79,6 +79,7 @@ GROUP_DESCRIPTIONS[style]="Global UI style controls"
GROUP_DESCRIPTIONS[sudo]="Sudo configuration helpers"
GROUP_DESCRIPTIONS[system]="System status, reboot, shutdown, logout, and lock"
GROUP_DESCRIPTIONS[theme]="Theme management"
GROUP_DESCRIPTIONS[tmux]="Tmux session helpers"
GROUP_DESCRIPTIONS[toggle]="Toggle Omarchy features"
GROUP_DESCRIPTIONS[transcode]="Image and video transcoding"
GROUP_DESCRIPTIONS[tui]="Terminal UI launchers"
+104
View File
@@ -0,0 +1,104 @@
#!/bin/bash
# omarchy:summary=Show or jump to tmux windows waiting for attention
# omarchy:args=<show [--json]|focus>
# omarchy:examples=omarchy tmux alert show | omarchy tmux alert focus
set -e
# Window names can contain the separator, so they always come last when parsed.
WINDOW_FORMAT='#{window_bell_flag}#{window_activity_flag}#{window_silence_flag}|#{session_name}|#{window_index}|#{window_name}'
usage() {
echo "Usage: omarchy-tmux-alert <show [--json]|focus>" >&2
exit 1
}
# Windows tmux has flagged with a bell, activity, or silence alert, which is the
# same state that highlights the window in the tmux status bar.
alerted_windows() {
local flags session index name
tmux list-windows -a -F "$WINDOW_FORMAT" 2>/dev/null |
while IFS='|' read -r flags session index name; do
if [[ $flags == *1* ]]; then
printf '%s|%s|%s\n' "$session" "$index" "$name"
fi
done
}
show() {
local windows=() window session index name description=""
readarray -t windows < <(alerted_windows)
for window in "${windows[@]}"; do
IFS='|' read -r session index name <<<"$window"
[[ -n $description ]] && description+=", "
description+="$name ($session:$index)"
done
if [[ ${1:-} == "--json" ]]; then
jq -nc --argjson count "${#windows[@]}" --arg tooltip "$description" '{count: $count, tooltip: $tooltip}'
elif [[ -n $description ]]; then
echo "$description"
fi
}
focus_terminal_window() {
local pid=$1 address="" window_pid window_address
local -A windows=()
while read -r window_pid window_address; do
windows[$window_pid]=$window_address
done < <(hyprctl clients -j | jq -r '.[] | "\(.pid) \(.address)"')
# The tmux client runs somewhere below the terminal that owns the window.
while [[ -n $pid ]] && (( pid > 1 )); do
if [[ -n ${windows[$pid]:-} ]]; then
address=${windows[$pid]}
break
fi
pid=$(awk '/^PPid:/ { print $2 }' "/proc/$pid/status" 2>/dev/null)
done
[[ -n $address ]] || return 1
hyprctl dispatch "hl.dsp.focus({ window = \"address:$address\" })" >/dev/null 2>&1 ||
hyprctl dispatch focuswindow "address:$address" >/dev/null
}
focus() {
local target session index client tty pid
target=$(alerted_windows | head -n1)
[[ -n $target ]] || return 0
IFS='|' read -r session index _ <<<"$target"
client=$(tmux list-clients -t "$session" -F '#{client_tty}|#{client_pid}' 2>/dev/null | head -n1)
[[ -n $client ]] || client=$(tmux list-clients -F '#{client_tty}|#{client_pid}' 2>/dev/null | head -n1)
if [[ -z $client ]]; then
tmux select-window -t "$session:$index"
exec omarchy-launch-terminal tmux attach -t "$session"
fi
IFS='|' read -r tty pid <<<"$client"
tmux switch-client -c "$tty" -t "$session:$index"
omarchy-shell -q omarchy.indicators refresh
focus_terminal_window "$pid"
}
case "${1:-}" in
show)
shift
show "$@"
;;
focus)
focus
;;
*)
usage
;;
esac