From c628c452910cac9d8e22aa8d1abe2a129dc1ccd7 Mon Sep 17 00:00:00 2001 From: jasonwitty Date: Fri, 28 Aug 2026 10:33:26 -0700 Subject: [PATCH] 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 --- README.md | 6 ++++++ config.env | 11 +++++++++++ socktop-gestures | 7 +++++++ socktop-rack | 6 ++++++ socktop-swipe | 42 +++++++++++++++++++++++++++++++++++++----- 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 902048d..53cfa96 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ left-to-right walks back the same way. 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 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_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_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. | diff --git a/config.env b/config.env index 0d6a724..58afafb 100644 --- a/config.env +++ b/config.env @@ -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. 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. 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. GESTURE_IN="${GESTURE_IN:-RL}" 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}" diff --git a/socktop-gestures b/socktop-gestures index e174438..bf4ed4b 100755 --- a/socktop-gestures +++ b/socktop-gestures @@ -20,6 +20,9 @@ done : "${FINGER_COUNTS:=1 2 3}" : "${GESTURE_IN:=RL}" : "${GESTURE_OUT:=LR}" +: "${SOCKTOP_AUX_CMD:=}" +: "${GESTURE_AUX_IN:=UD}" +: "${GESTURE_AUX_OUT:=DU}" SWIPE_CMD=${SWIPE_CMD:-$(dirname "$0")/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 set -- "$@" -g "$f,$GESTURE_IN,*,*,R,$SWIPE_CMD next" 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 exec lisgd $verbose \ diff --git a/socktop-rack b/socktop-rack index bdbda0e..aa07dbf 100755 --- a/socktop-rack +++ b/socktop-rack @@ -13,6 +13,7 @@ done : "${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 @@ -68,6 +69,11 @@ for group in $SOCKTOP_GROUPS; do 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 diff --git a/socktop-swipe b/socktop-swipe index 639ef5d..db4ef50 100755 --- a/socktop-swipe +++ b/socktop-swipe @@ -1,5 +1,5 @@ #!/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 # 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 # 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 # and stay connected while hidden, so swiping back shows current data with no # 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 : "${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. -wins=$(tmux list-windows -t "$SOCKTOP_SESSION" -F '#{window_id}' 2>/dev/null) || exit 0 -[ -n "$wins" ] || exit 0 +# Ordered window ids (@N) of the carousel windows, the aux window if any, and +# the currently active window. +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 </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 for w in $wins; do if [ "$seen" = yes ]; then next_win=$w; break; fi