c5b8d04b84
Wall displays must never blank. --noblank applies two layers: an Xorg ServerFlags snippet with all four timeouts at 0 (covers the DM greeter, and survives reboots) and an xset line in the i3 autostart (a session or DM can re-enable the screensaver after X starts). Either alone is insufficient. Documents the trap that cost time here: `sudo xset ...` targets root's X connection and silently does nothing, so a `sudo bash noblank.sh` wrapper looks like it worked while blanking stays fully armed. Also fixes a latent bug: `[ "$relogin" = yes ] && echo ...` as the final statement made install.sh exit non-zero under `set -e` -- and skip the closing instructions -- whenever a relogin was not required. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
196 lines
6.8 KiB
Bash
Executable File
196 lines
6.8 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 --noblank ...and stop the screen blanking
|
|
# ./install.sh --xignore --i3 --noblank full wall-display 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
|
|
BCONF=/etc/X11/xorg.conf.d/10-no-blanking-socktop-swipe.conf
|
|
SRC="$HOME/src/lisgd"
|
|
|
|
here=$(cd "$(dirname "$0")" && pwd)
|
|
do_xignore=no
|
|
do_i3=no
|
|
do_noblank=no
|
|
for a in "$@"; do
|
|
case "$a" in
|
|
--xignore) do_xignore=yes ;;
|
|
--i3) do_i3=yes ;;
|
|
--noblank) do_noblank=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: stop the screen blanking -------------------------------------
|
|
if [ "$do_noblank" = yes ]; then
|
|
echo "==> disabling screen blanking and DPMS"
|
|
# Two layers on purpose:
|
|
# 1. An Xorg ServerFlags snippet, so it applies to every X session including
|
|
# the display manager greeter, and survives reboots.
|
|
# 2. An xset call at i3 startup, because a session or DM can re-enable the
|
|
# screensaver after X starts.
|
|
# Note `xset` alone is NOT enough, and must run as the session user -- running
|
|
# it under sudo targets root's X connection and silently does nothing.
|
|
sudo mkdir -p /etc/X11/xorg.conf.d
|
|
sudo tee "$BCONF" >/dev/null <<'EOF'
|
|
# Installed by socktop-swipe. This is a wall display: it must never blank.
|
|
Section "ServerFlags"
|
|
Option "BlankTime" "0"
|
|
Option "StandbyTime" "0"
|
|
Option "SuspendTime" "0"
|
|
Option "OffTime" "0"
|
|
EndSection
|
|
EOF
|
|
echo " wrote $BCONF"
|
|
|
|
# Apply immediately too, if a session is available.
|
|
if [ -n "${DISPLAY:-}" ]; then
|
|
xset s off s noblank -dpms 2>/dev/null || true
|
|
echo " applied to the running session"
|
|
fi
|
|
|
|
i3conf="$HOME/.config/i3/config"
|
|
if [ -e "$i3conf" ] && ! grep -q "xset s off" "$i3conf"; then
|
|
bak="$i3conf.bak-$(date +%Y%m%d-%H%M%S)"
|
|
cp "$i3conf" "$bak"
|
|
printf '\n# Wall display: never blank (socktop-swipe --noblank)\nexec --no-startup-id xset s off s noblank -dpms\n' >>"$i3conf"
|
|
if i3 -C -c "$i3conf" >/dev/null 2>&1; then
|
|
echo " added xset to i3 autostart (backup: $bak)"
|
|
else
|
|
cp "$bak" "$i3conf"
|
|
echo "!! i3 rejected the config; restored $bak" >&2
|
|
fi
|
|
fi
|
|
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."
|
|
if [ "$relogin" = yes ]; then
|
|
echo "LOG OUT and back in before use (group and/or X changes)."
|
|
fi
|
|
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 "=============================================================="
|