Enforce single-instance in socktop-gestures instead of documenting it
The documented restart was `pkill -x lisgd && socktop-gestures &`. pkill exits non-zero when it matches nothing, so `&&` short-circuits and the daemon silently does not start when none was running -- you swipe, get nothing, and reasonably blame the config change you just made. socktop-gestures exec'd lisgd with no guard, so nothing downstream caught it. Rather than only fixing the one-liner, move the invariant into the tool: it now exits non-zero if a daemon is already running, and --replace stops the old one first (waiting for it to actually exit). This is the failure the README itself flags as gotcha 3, so a false success there is expensive. Verified against a live daemon: refusal, --help, bad-option exit codes, and a clean pid handover under --replace with the carousel still working. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -80,10 +80,15 @@ Everything lives in **`/usr/local/etc/socktop-swipe.env`**. Edit it there, not i
|
|||||||
the repo copy. After changing it, restart the daemon and rebuild the session:
|
the repo copy. After changing it, restart the daemon and rebuild the session:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pkill -x lisgd && socktop-gestures &
|
socktop-gestures --replace & # restarts the daemon, running or not
|
||||||
socktop-rack
|
socktop-rack
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Use `--replace` rather than `pkill -x lisgd && socktop-gestures`: `pkill` exits
|
||||||
|
non-zero when it matches nothing, so that one-liner silently starts **nothing**
|
||||||
|
if no daemon was running — you would swipe, get no response, and reasonably
|
||||||
|
blame the config change.
|
||||||
|
|
||||||
| Option | Default | What it does |
|
| Option | Default | What it does |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `SOCKTOP_HOSTS` | four Pi profiles | socktop profile names, **in swipe order**. Any count works; layout and carousel adapt. |
|
| `SOCKTOP_HOSTS` | four Pi profiles | socktop profile names, **in swipe order**. Any count works; layout and carousel adapt. |
|
||||||
@@ -113,6 +118,8 @@ systemctl --user enable --now socktop-swipe
|
|||||||
|
|
||||||
Either way, **run exactly one gesture daemon**. lisgd does not grab the input
|
Either way, **run exactly one gesture daemon**. lisgd does not grab the input
|
||||||
device exclusively, so two instances make every swipe fire twice.
|
device exclusively, so two instances make every swipe fire twice.
|
||||||
|
`socktop-gestures` enforces this: it exits non-zero if one is already running,
|
||||||
|
unless given `--replace`.
|
||||||
|
|
||||||
## Uninstall
|
## Uninstall
|
||||||
|
|
||||||
@@ -160,6 +167,10 @@ Also ensure tmux mouse mode is **off**; `socktop-rack` sets this.
|
|||||||
|
|
||||||
Two lisgd instances are running. `pgrep -x lisgd` should show exactly one.
|
Two lisgd instances are running. `pgrep -x lisgd` should show exactly one.
|
||||||
|
|
||||||
|
`socktop-gestures` refuses to start if a daemon is already running, so this
|
||||||
|
should not happen via the normal path; `--replace` restarts cleanly. It can
|
||||||
|
still occur if lisgd was launched by hand.
|
||||||
|
|
||||||
### 4. Swipes do nothing at all
|
### 4. Swipes do nothing at all
|
||||||
|
|
||||||
In order: is the session running (`tmux ls`)? Is the daemon running
|
In order: is the session running (`tmux ls`)? Is the daemon running
|
||||||
|
|||||||
+42
-1
@@ -25,7 +25,48 @@ 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
|
||||||
|
|
||||||
verbose=
|
verbose=
|
||||||
[ "${1:-}" = "-v" ] && verbose=-v
|
replace=no
|
||||||
|
for a in "$@"; do
|
||||||
|
case "$a" in
|
||||||
|
-v) verbose=-v ;;
|
||||||
|
--replace) replace=yes ;;
|
||||||
|
-h | --help)
|
||||||
|
echo "usage: socktop-gestures [-v] [--replace]"
|
||||||
|
echo " -v log each detected gesture"
|
||||||
|
echo " --replace stop an already-running daemon first"
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "socktop-gestures: unknown option '$a'" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Single-instance guard. lisgd does not grab the input device exclusively, so a
|
||||||
|
# second copy makes every swipe fire twice -- the carousel appears to skip panes.
|
||||||
|
# Enforced here rather than left to the caller: the obvious restart one-liner
|
||||||
|
# `pkill -x lisgd && socktop-gestures` silently starts NOTHING when no daemon was
|
||||||
|
# running, because pkill exits non-zero when it matches nothing.
|
||||||
|
running=$(pgrep -x -u "$(id -u)" lisgd 2>/dev/null || true)
|
||||||
|
if [ -n "$running" ]; then
|
||||||
|
if [ "$replace" = yes ]; then
|
||||||
|
pkill -x -u "$(id -u)" lisgd || true
|
||||||
|
n=0
|
||||||
|
while pgrep -x -u "$(id -u)" lisgd >/dev/null 2>&1 && [ "$n" -lt 30 ]; do
|
||||||
|
n=$((n + 1))
|
||||||
|
sleep 0.1
|
||||||
|
done
|
||||||
|
if pgrep -x -u "$(id -u)" lisgd >/dev/null 2>&1; then
|
||||||
|
echo "socktop-gestures: existing lisgd would not exit" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "socktop-gestures: lisgd is already running (pid: $(echo "$running" | tr '\n' ' '))" >&2
|
||||||
|
echo " Two instances make every swipe fire twice. Use --replace to restart it." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -e "$TOUCH_DEV" ]; then
|
if [ ! -e "$TOUCH_DEV" ]; then
|
||||||
echo "socktop-gestures: $TOUCH_DEV not present" >&2
|
echo "socktop-gestures: $TOUCH_DEV not present" >&2
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Run the real gesture daemon in the foreground, with logging, so you can watch
|
# Run the real gesture daemon in the foreground so you can watch the display
|
||||||
# the display while you swipe. Ctrl-C to stop.
|
# while you swipe. Ctrl-C to stop.
|
||||||
#
|
#
|
||||||
# Expect: swipe right-to-left -> zooms in one host at a time
|
# Expect: swipe right-to-left -> zooms in one host at a time
|
||||||
# swipe left-to-right -> walks back out to the overview
|
# swipe left-to-right -> walks back out to the overview
|
||||||
# "Execute ..." in the output means a gesture matched and fired.
|
# "Execute ..." in the output means a gesture matched and fired.
|
||||||
#
|
#
|
||||||
# Make sure no other instance is running first -- two copies fire every swipe
|
# Pass --replace to take over from an already-running daemon; without it,
|
||||||
# twice, which looks like the carousel skipping.
|
# socktop-gestures refuses to start a second instance (which would make every
|
||||||
|
# swipe fire twice).
|
||||||
set -eu
|
set -eu
|
||||||
|
exec "$(dirname "$0")/../socktop-gestures" -v "$@"
|
||||||
if pgrep -x lisgd >/dev/null 2>&1; then
|
|
||||||
echo "!! lisgd is already running (pid: $(pgrep -x lisgd | tr '\n' ' '))." >&2
|
|
||||||
echo "!! Two instances make every swipe fire twice. Stop it first:" >&2
|
|
||||||
echo " pkill -x lisgd" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$(dirname "$0")/../socktop-gestures" -v
|
|
||||||
|
|||||||
Reference in New Issue
Block a user