c628c45291
A separate tmux window running any TUI, reached with a vertical swipe from any carousel screen; swiping up returns to the exact window/zoom you left. The aux window is excluded from the horizontal carousel and horizontal swipes on it are inert. Bound only when SOCKTOP_AUX_CMD is set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
92 lines
2.7 KiB
Bash
Executable File
92 lines
2.7 KiB
Bash
Executable File
#!/bin/sh
|
|
# Build the socktop display session: one tmux window per GROUP, one pane per
|
|
# host inside it. Window order and pane index order together are the swipe
|
|
# order (see socktop-swipe).
|
|
set -eu
|
|
|
|
# shellcheck source=config.env
|
|
for c in /usr/local/etc/socktop-swipe.env "$(dirname "$0")/config.env"; do
|
|
[ -r "$c" ] && . "$c" && break
|
|
done
|
|
|
|
: "${SOCKTOP_GROUPS:=}"
|
|
: "${SOCKTOP_HOSTS:=}"
|
|
: "${SOCKTOP_SESSION:=socktop4}"
|
|
: "${SOCKTOP_BIN:=socktop}"
|
|
: "${SOCKTOP_AUX_CMD:=}"
|
|
|
|
# Legacy form: SOCKTOP_HOSTS alone is a single tiled group.
|
|
if [ -z "$SOCKTOP_GROUPS" ]; then
|
|
: "${SOCKTOP_HOSTS:?no SOCKTOP_GROUPS or SOCKTOP_HOSTS -- is the config installed?}"
|
|
SOCKTOP_GROUPS=$SOCKTOP_HOSTS
|
|
fi
|
|
|
|
tmux kill-session -t "$SOCKTOP_SESSION" 2>/dev/null || true
|
|
|
|
# Pane titles are set on the session, so do it up front; windows inherit.
|
|
build_group() {
|
|
# $1 = window name, remaining args = host names and an optional @layout
|
|
name=$1
|
|
shift
|
|
layout=tiled
|
|
hosts=
|
|
for tok in "$@"; do
|
|
case "$tok" in
|
|
@*) layout=${tok#@} ;;
|
|
*) hosts="$hosts $tok" ;;
|
|
esac
|
|
done
|
|
# shellcheck disable=SC2086
|
|
set -- $hosts
|
|
[ $# -gt 0 ] || return 0
|
|
|
|
if ! tmux has-session -t "$SOCKTOP_SESSION" 2>/dev/null; then
|
|
tmux new-session -d -s "$SOCKTOP_SESSION" -n "$name" "$SOCKTOP_BIN -P $1"
|
|
else
|
|
tmux new-window -d -t "$SOCKTOP_SESSION" -n "$name" "$SOCKTOP_BIN -P $1"
|
|
fi
|
|
win="$SOCKTOP_SESSION:$name"
|
|
tmux select-pane -t "$win.0" -T "$1"
|
|
shift
|
|
for h in "$@"; do
|
|
# Split the most recently created pane so creation order == index order.
|
|
tmux split-window -t "$win" "$SOCKTOP_BIN -P $h"
|
|
tmux select-pane -t "$win.$(tmux display-message -t "$win" -p '#{pane_index}')" -T "$h"
|
|
done
|
|
tmux select-layout -t "$win" "$layout"
|
|
tmux select-pane -t "$win.0"
|
|
}
|
|
|
|
n=0
|
|
old_ifs=$IFS
|
|
IFS=';'
|
|
for group in $SOCKTOP_GROUPS; do
|
|
IFS=$old_ifs
|
|
# shellcheck disable=SC2086
|
|
build_group "g$n" $group
|
|
n=$((n + 1))
|
|
IFS=';'
|
|
done
|
|
IFS=$old_ifs
|
|
|
|
# The aux window sits outside the carousel; socktop-swipe recognises it by name.
|
|
if [ -n "$SOCKTOP_AUX_CMD" ]; then
|
|
tmux new-window -d -t "$SOCKTOP_SESSION" -n aux "$SOCKTOP_AUX_CMD"
|
|
fi
|
|
|
|
tmux select-window -t "$SOCKTOP_SESSION:g0"
|
|
|
|
tmux set-option -t "$SOCKTOP_SESSION" pane-border-status top
|
|
tmux set-option -t "$SOCKTOP_SESSION" pane-border-format ' #{pane_title} '
|
|
tmux set-option -t "$SOCKTOP_SESSION" status off
|
|
|
|
# Keep dead panes so pane indices stay stable if a socktop exits.
|
|
tmux set-option -t "$SOCKTOP_SESSION" remain-on-exit on
|
|
|
|
# Mouse mode MUST stay off. With it on, every touch swipe is ALSO delivered to
|
|
# tmux as a click-drag: dragging across a pane border resizes it and taps
|
|
# reselect panes, which fights the gesture daemon. See README, "Why no tapping".
|
|
tmux set-option -t "$SOCKTOP_SESSION" mouse off
|
|
|
|
exec tmux attach -t "$SOCKTOP_SESSION"
|