Add swipe-down aux screen (SOCKTOP_AUX_CMD)

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>
This commit is contained in:
jasonwitty
2026-08-28 10:33:26 -07:00
parent 818b09762e
commit c628c45291
5 changed files with 67 additions and 5 deletions
+6
View File
@@ -16,6 +16,10 @@ left-to-right walks back the same way.
With a single group this is simply overview -> each host -> back. With a single group this is simply overview -> each host -> back.
Optionally, swiping **down** from any screen shows a different TUI (an
[Uptime Kuma](https://github.com/louislam/uptime-kuma) status page on the rack
display), and swiping **up** returns to exactly the screen you left.
Built for a 10" touch panel on a server rack driving four Raspberry Pis, on a Built for a 10" touch panel on a server rack driving four Raspberry Pis, on a
low-power x86 box running i3 on X11. low-power x86 box running i3 on X11.
@@ -98,6 +102,8 @@ blame the config change.
| --- | --- | --- | | --- | --- | --- |
| `SOCKTOP_GROUPS` | Pis quartered `;` Orange Pi + Debian stacked | Groups separated by `;`, each a list of socktop profile names **in swipe order**, plus an optional `@layout` (`tiled` default, `even-vertical` stacks, `even-horizontal` side-by-side, `main-*` also work). Any count of groups and hosts works. | | `SOCKTOP_GROUPS` | Pis quartered `;` Orange Pi + Debian stacked | Groups separated by `;`, each a list of socktop profile names **in swipe order**, plus an optional `@layout` (`tiled` default, `even-vertical` stacks, `even-horizontal` side-by-side, `main-*` also work). Any count of groups and hosts works. |
| `SOCKTOP_HOSTS` | empty | Legacy single-group form; used only when `SOCKTOP_GROUPS` is empty | | `SOCKTOP_HOSTS` | empty | Legacy single-group form; used only when `SOCKTOP_GROUPS` is empty |
| `SOCKTOP_AUX_CMD` | `uptime-kuma-status …` | Command for the swipe-down "aux" screen. Full path. Empty disables the feature and its gestures. |
| `GESTURE_AUX_IN` / `GESTURE_AUX_OUT` | `UD` / `DU` | Swipe down shows aux, swipe up returns |
| `SOCKTOP_SESSION` | `socktop4` | tmux session name | | `SOCKTOP_SESSION` | `socktop4` | tmux session name |
| `SOCKTOP_BIN` | `$HOME/.cargo/bin/socktop` | Full path — i3 does not have `~/.cargo/bin` on `PATH` | | `SOCKTOP_BIN` | `$HOME/.cargo/bin/socktop` | Full path — i3 does not have `~/.cargo/bin` on `PATH` |
| `TOUCH_DEV` | ILITEK by-id path | Touch device. **Always use a `/dev/input/by-id/` path**; `eventN` numbers change on reboot. | | `TOUCH_DEV` | ILITEK by-id path | Touch device. **Always use a `/dev/input/by-id/` path**; `eventN` numbers change on reboot. |
+11
View File
@@ -31,6 +31,12 @@ SOCKTOP_GROUPS="${SOCKTOP_GROUPS:-rpi-master rpi-worker-1 rpi-worker-2 rpi-worke
# Legacy single-group form. Used only when SOCKTOP_GROUPS is empty. # Legacy single-group form. Used only when SOCKTOP_GROUPS is empty.
SOCKTOP_HOSTS="${SOCKTOP_HOSTS:-}" SOCKTOP_HOSTS="${SOCKTOP_HOSTS:-}"
# Optional "aux" screen: a different TUI reached by swiping DOWN from any
# carousel screen; swiping UP returns to exactly the screen you left. It runs in
# its own tmux window, kept alive like the socktop panes, so switching is
# instant. Leave empty to disable. Use full paths -- i3 has no ~/.cargo/bin.
SOCKTOP_AUX_CMD="${SOCKTOP_AUX_CMD:-$HOME/.cargo/bin/uptime-kuma-status https://status.wittyoneoff.com/status/wittyoneoff}"
# tmux session name. Change only if it collides with something else. # tmux session name. Change only if it collides with something else.
SOCKTOP_SESSION="${SOCKTOP_SESSION:-socktop4}" SOCKTOP_SESSION="${SOCKTOP_SESSION:-socktop4}"
@@ -78,3 +84,8 @@ FINGER_COUNTS="${FINGER_COUNTS:-1 2 3}"
# Swap these two values to reverse the direction of travel. # Swap these two values to reverse the direction of travel.
GESTURE_IN="${GESTURE_IN:-RL}" GESTURE_IN="${GESTURE_IN:-RL}"
GESTURE_OUT="${GESTURE_OUT:-LR}" GESTURE_OUT="${GESTURE_OUT:-LR}"
# Aux screen swipes. UD = up-to-down (swipe down) shows it; DU = down-to-up
# (swipe up) returns. Only bound when SOCKTOP_AUX_CMD is set.
GESTURE_AUX_IN="${GESTURE_AUX_IN:-UD}"
GESTURE_AUX_OUT="${GESTURE_AUX_OUT:-DU}"
+7
View File
@@ -20,6 +20,9 @@ done
: "${FINGER_COUNTS:=1 2 3}" : "${FINGER_COUNTS:=1 2 3}"
: "${GESTURE_IN:=RL}" : "${GESTURE_IN:=RL}"
: "${GESTURE_OUT:=LR}" : "${GESTURE_OUT:=LR}"
: "${SOCKTOP_AUX_CMD:=}"
: "${GESTURE_AUX_IN:=UD}"
: "${GESTURE_AUX_OUT:=DU}"
SWIPE_CMD=${SWIPE_CMD:-$(dirname "$0")/socktop-swipe} SWIPE_CMD=${SWIPE_CMD:-$(dirname "$0")/socktop-swipe}
[ -x /usr/local/bin/socktop-swipe ] && SWIPE_CMD=/usr/local/bin/socktop-swipe [ -x /usr/local/bin/socktop-swipe ] && SWIPE_CMD=/usr/local/bin/socktop-swipe
@@ -83,6 +86,10 @@ set --
for f in $FINGER_COUNTS; do for f in $FINGER_COUNTS; do
set -- "$@" -g "$f,$GESTURE_IN,*,*,R,$SWIPE_CMD next" set -- "$@" -g "$f,$GESTURE_IN,*,*,R,$SWIPE_CMD next"
set -- "$@" -g "$f,$GESTURE_OUT,*,*,R,$SWIPE_CMD prev" set -- "$@" -g "$f,$GESTURE_OUT,*,*,R,$SWIPE_CMD prev"
if [ -n "$SOCKTOP_AUX_CMD" ]; then
set -- "$@" -g "$f,$GESTURE_AUX_IN,*,*,R,$SWIPE_CMD down"
set -- "$@" -g "$f,$GESTURE_AUX_OUT,*,*,R,$SWIPE_CMD up"
fi
done done
exec lisgd $verbose \ exec lisgd $verbose \
+6
View File
@@ -13,6 +13,7 @@ done
: "${SOCKTOP_HOSTS:=}" : "${SOCKTOP_HOSTS:=}"
: "${SOCKTOP_SESSION:=socktop4}" : "${SOCKTOP_SESSION:=socktop4}"
: "${SOCKTOP_BIN:=socktop}" : "${SOCKTOP_BIN:=socktop}"
: "${SOCKTOP_AUX_CMD:=}"
# Legacy form: SOCKTOP_HOSTS alone is a single tiled group. # Legacy form: SOCKTOP_HOSTS alone is a single tiled group.
if [ -z "$SOCKTOP_GROUPS" ]; then if [ -z "$SOCKTOP_GROUPS" ]; then
@@ -68,6 +69,11 @@ for group in $SOCKTOP_GROUPS; do
done done
IFS=$old_ifs 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 select-window -t "$SOCKTOP_SESSION:g0"
tmux set-option -t "$SOCKTOP_SESSION" pane-border-status top tmux set-option -t "$SOCKTOP_SESSION" pane-border-status top
+37 -5
View File
@@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# socktop-swipe next|prev # socktop-swipe next|prev|down|up
# #
# Walks a linear "zoom carousel" over the socktop session. Each tmux window is # Walks a linear "zoom carousel" over the socktop session. Each tmux window is
# one group of hosts; within a group the line is the tiled overview, then each # one group of hosts; within a group the line is the tiled overview, then each
@@ -11,6 +11,10 @@
# moves back and stops at the first overview. Deliberately no wrap-around: on # moves back and stops at the first overview. Deliberately no wrap-around: on
# a wall display, wrapping makes it impossible to tell where you are. # a wall display, wrapping makes it impossible to tell where you are.
# #
# "down" jumps to the optional aux window (see SOCKTOP_AUX_CMD) and remembers
# where you were; "up" returns there. The aux window is not part of the
# horizontal carousel, and horizontal swipes while on it do nothing.
#
# This is tmux pane zoom, NOT extra socktop instances. All panes keep running # This is tmux pane zoom, NOT extra socktop instances. All panes keep running
# and stay connected while hidden, so swiping back shows current data with no # and stay connected while hidden, so swiping back shows current data with no
# reconnect, and the polling load on the monitored hosts is constant. # reconnect, and the polling load on the monitored hosts is constant.
@@ -21,13 +25,41 @@ for c in /usr/local/etc/socktop-swipe.env "$(dirname "$0")/config.env"; do
done done
: "${SOCKTOP_SESSION:=socktop4}" : "${SOCKTOP_SESSION:=socktop4}"
dir=${1:?usage: socktop-swipe next|prev} dir=${1:?usage: socktop-swipe next|prev|down|up}
# Ordered window ids (@N) of the session, and the currently active one. # Ordered window ids (@N) of the carousel windows, the aux window if any, and
wins=$(tmux list-windows -t "$SOCKTOP_SESSION" -F '#{window_id}' 2>/dev/null) || exit 0 # the currently active window.
[ -n "$wins" ] || exit 0 all=$(tmux list-windows -t "$SOCKTOP_SESSION" -F '#{window_id} #{window_name}' 2>/dev/null) || exit 0
[ -n "$all" ] || exit 0
wins= aux=
while read -r id name; do
if [ "$name" = aux ]; then aux=$id; else wins="$wins $id"; fi
done <<EOF
$all
EOF
WIN=$(tmux display-message -t "$SOCKTOP_SESSION" -p '#{window_id}') || exit 0 WIN=$(tmux display-message -t "$SOCKTOP_SESSION" -p '#{window_id}') || exit 0
case "$dir" in
down)
[ -n "$aux" ] || exit 0
[ "$WIN" = "$aux" ] && exit 0
tmux set-option -t "$SOCKTOP_SESSION" @return_to "$WIN"
tmux select-window -t "$aux"
exit 0
;;
up)
[ "$WIN" = "$aux" ] || exit 0
back=$(tmux show-option -qv -t "$SOCKTOP_SESSION" @return_to)
[ -n "$back" ] && tmux has-session -t "$back" 2>/dev/null || back=${wins# }
back=${back%% *}
tmux select-window -t "$back"
exit 0
;;
esac
# On the aux screen, horizontal swipes are deliberately inert.
[ "$WIN" = "$aux" ] && exit 0
prev_win= next_win= seen=no prev_win= next_win= seen=no
for w in $wins; do for w in $wins; do
if [ "$seen" = yes ]; then next_win=$w; break; fi if [ "$seen" = yes ]; then next_win=$w; break; fi