Files
socktop-swipe/install.sh
T
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

147 lines
5.0 KiB
Bash
Executable File

#!/bin/sh
# socktop-swipe installer.
#
# ./install.sh scripts + config + lisgd (build if missing)
# ./install.sh --xignore ...and tell X to ignore the touch panel
# ./install.sh --i3 ...and add i3 autostart lines
# ./install.sh --xignore --i3 full display-host setup
#
# Safe to re-run: an existing config file is never overwritten, and the i3 edit
# is skipped if already present.
set -eu
PREFIX=${PREFIX:-/usr/local}
BIN="$PREFIX/bin"
ETC="$PREFIX/etc"
CONF="$ETC/socktop-swipe.env"
XCONF=/etc/X11/xorg.conf.d/99-ignore-touch-socktop-swipe.conf
SRC="$HOME/src/lisgd"
here=$(cd "$(dirname "$0")" && pwd)
do_xignore=no
do_i3=no
for a in "$@"; do
case "$a" in
--xignore) do_xignore=yes ;;
--i3) do_i3=yes ;;
*) echo "unknown option: $a" >&2; exit 2 ;;
esac
done
# --- lisgd ------------------------------------------------------------------
# libinput deliberately emits gesture events only for touchpads, never for
# touchscreens, so libinput-gestures and friends cannot work here. lisgd reads
# raw touch events and synthesises the swipes itself.
if command -v lisgd >/dev/null 2>&1; then
echo "==> lisgd already installed: $(command -v lisgd)"
else
echo "==> building lisgd"
if command -v apt-get >/dev/null 2>&1; then
sudo apt-get update
sudo apt-get install -y build-essential pkg-config git libinput-dev libx11-dev
else
echo "!! Non-Debian system: ensure a C toolchain, libinput and libX11 headers"
echo "!! are present, then re-run."
fi
mkdir -p "$(dirname "$SRC")"
if [ -d "$SRC/.git" ]; then git -C "$SRC" pull --ff-only; else
git clone https://git.sr.ht/~mil/lisgd "$SRC"
fi
# WITHOUT_WAYLAND: lisgd builds both backends by default and would otherwise
# need libwayland-dev for code that never runs on an X11-only host.
make -C "$SRC" WITHOUT_WAYLAND=1
sudo make -C "$SRC" install WITHOUT_WAYLAND=1 PREFIX="$PREFIX"
fi
# --- scripts and config -----------------------------------------------------
echo "==> installing scripts to $BIN"
sudo install -d "$BIN" "$ETC"
sudo install -m 755 "$here/socktop-rack" "$here/socktop-swipe" "$here/socktop-gestures" "$BIN/"
if [ -e "$CONF" ]; then
echo "==> keeping existing $CONF (not overwritten)"
else
sudo install -m 644 "$here/config.env" "$CONF"
echo "==> installed default config to $CONF"
echo " EDIT IT before first run if your hardware differs."
fi
# --- input group ------------------------------------------------------------
if id -nG | tr ' ' '\n' | grep -qx input; then
echo "==> already in the 'input' group"
relogin=no
else
echo "==> adding $(id -un) to the 'input' group (lisgd reads /dev/input directly)"
sudo usermod -aG input "$(id -un)"
relogin=yes
fi
# --- optional: make X ignore the panel --------------------------------------
if [ "$do_xignore" = yes ]; then
# shellcheck disable=SC1090
. "$CONF"
product=${XIGNORE_MATCH:-ILITEK}
echo "==> telling X to ignore touch devices matching '$product'"
sudo mkdir -p /etc/X11/xorg.conf.d
sudo tee "$XCONF" >/dev/null <<EOF
# Installed by socktop-swipe.
# The panel is driven by lisgd via /dev/input, NOT through X. Letting X also
# deliver touch makes the terminal, tmux and socktop react to the same swipes
# the gesture daemon is interpreting. MatchProduct is narrow on purpose so it
# cannot match keyboards or other HID devices.
Section "InputClass"
Identifier "ignore touchscreen (socktop-swipe)"
MatchProduct "$product"
MatchIsTouchscreen "on"
Option "Ignore" "on"
EndSection
EOF
echo " wrote $XCONF (takes effect after X restarts)"
relogin=yes
fi
# --- optional: i3 autostart -------------------------------------------------
if [ "$do_i3" = yes ]; then
i3conf="$HOME/.config/i3/config"
if [ ! -e "$i3conf" ]; then
echo "!! $i3conf not found; skipping i3 autostart" >&2
elif grep -q "socktop-gestures" "$i3conf"; then
echo "==> i3 autostart already present; leaving it alone"
else
bak="$i3conf.bak-$(date +%Y%m%d-%H%M%S)"
cp "$i3conf" "$bak"
cat >>"$i3conf" <<EOF
# --- socktop-swipe --------------------------------------------------------
# Exactly ONE gesture daemon: lisgd does not grab the device exclusively, so a
# second instance makes every swipe fire twice.
exec --no-startup-id $BIN/socktop-gestures
exec --no-startup-id \$TERMINAL -e $BIN/socktop-rack
EOF
if i3 -C -c "$i3conf" >/dev/null 2>&1; then
echo "==> added i3 autostart (backup: $bak)"
echo " NOTE: set \$TERMINAL in your i3 config, or edit those lines"
echo " to your terminal's full path."
else
cp "$bak" "$i3conf"
echo "!! i3 rejected the config; restored $bak" >&2
i3 -C -c "$i3conf" || true
fi
fi
fi
echo
echo "=============================================================="
echo "Installed."
[ "$relogin" = yes ] && echo "LOG OUT and back in before use (group and/or X changes)."
cat <<EOF
Start it by hand with:
$BIN/socktop-gestures & # exactly one instance
$BIN/socktop-rack # builds and attaches the session
Configuration: $CONF
Diagnostics: tools/diag.sh
EOF
echo "=============================================================="