Files
jasonwitty 18ddd39184 Initial commit: swipe-to-zoom touchscreen navigation for socktop
Tiled socktop dashboard where a right-to-left swipe zooms into each host
full-screen and left-to-right walks back out.

The carousel is tmux pane zoom rather than separate socktop instances, so
there is one process per host: half the processes, no reconnect delay when
swiping back, and constant polling load on the monitored hosts.

Gestures come from lisgd because libinput emits gesture events only for
touchpads, never touchscreens, which rules out libinput-gestures entirely.

Documents the four gotchas found while building this: panels reporting 2-3
contacts for a one-finger swipe, X needing to ignore the panel so the
terminal and socktop stop competing for the same touches, tmux mouse mode
being incompatible with swipes, and lisgd not grabbing the device
exclusively so two instances double-fire.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 01:22:23 -07:00

60 lines
1.8 KiB
Bash
Executable File

#!/bin/sh
# socktop-swipe next|prev
#
# Walks a linear "zoom carousel" over the tiled socktop window:
#
# overview <-> pane 0 <-> pane 1 <-> ... <-> pane N-1
# (all hosts) host 1 host 2 last host
#
# "next" moves right along that line and stops at the last pane.
# "prev" moves back and stops at the overview. Deliberately no wrap-around:
# on a wall display, wrapping makes it impossible to tell where you are.
#
# 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.
set -eu
for c in /usr/local/etc/socktop-swipe.env "$(dirname "$0")/config.env"; do
[ -r "$c" ] && . "$c" && break
done
: "${SOCKTOP_SESSION:=socktop4}"
dir=${1:?usage: socktop-swipe next|prev}
# Resolve the session's active window to its window id (@N) rather than assuming
# a window name, so this works against any socktop session however it was built.
WIN=$(tmux display-message -t "$SOCKTOP_SESSION" -p '#{window_id}' 2>/dev/null) || exit 0
[ -n "$WIN" ] || exit 0
state=$(tmux display-message -t "$WIN" -p '#{window_zoomed_flag} #{pane_index} #{window_panes}') || exit 0
zoomed=${state%% *}
rest=${state#* }
idx=${rest%% *}
count=${rest##* }
last=$((count - 1))
zoom_to() {
# Selecting a different pane auto-unzooms, so zoom explicitly afterwards.
tmux select-pane -t "$WIN.$1"
tmux resize-pane -Z -t "$WIN.$1"
}
if [ "$zoomed" = 0 ]; then
case "$dir" in
next) zoom_to 0 ;;
prev) : ;; # already at the overview; nothing further out
esac
else
case "$dir" in
next) [ "$idx" -lt "$last" ] && zoom_to $((idx + 1)) || : ;;
prev)
if [ "$idx" -gt 0 ]; then
zoom_to $((idx - 1))
else
tmux resize-pane -Z -t "$WIN.$idx" # unzoom -> overview
fi
;;
esac
fi