Install kdotool to ~/.local/bin and wire it into swap-watchdog's PATH

kdotool is built by the Dagger pipeline but has no system install step of
its own; swap-watchdog execs it by bare name, so without this the service
couldn't find it. Also hardens install.sh's dagger-CLI check and brings
uninstall.sh/README.md in line with the final install flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Philip Peterson 2026-10-06 09:41:42 -08:00
parent 889a2c4d50
commit 089f1fb9ff
4 changed files with 38 additions and 23 deletions

View file

@ -54,9 +54,14 @@ deliberately separate, bigger problem, not handled here.
## Requirements
- `kdotool` (KWin window control on Wayland — used by the watchdog to
reveal the GUI window).
- `gtk3-devel` to build `force-quit-gui` (cgo bindings via `gotk3`).
- `dagger` CLI + a container runtime (podman or docker) — the build runs
in an ephemeral Nix-provisioned container (see `.dagger/main.go`), so
`gtk3-devel`, `dbus-devel`, and a Rust toolchain (needed to build
`kdotool`, which isn't packaged for Fedora) never have to be installed on
the host. Only the resulting binaries' *runtime* libraries matter, and
any normal desktop — GTK-based or not — already has `libgtk-3`,
`libdbus-1`, etc., since KDE/GNOME portals and GTK-using apps pull them
in regardless of your actual desktop toolkit.
- Built and tested against `gotk3 v0.6.3` — v0.6.4 fails to compile its
`gdk` package against this system's GTK3 (3.24.52) with an `undefined:
callback` error in `gdk_since_3_22.go`'s `Seat.Grab`, an unrelated
@ -66,17 +71,16 @@ deliberately separate, bigger problem, not handled here.
## Install
```
go build -o bin/swap-watchdog ./cmd/swap-watchdog
go build -o bin/force-quit-gui ./cmd/force-quit-gui
mkdir -p ~/.config/systemd/user
cp systemd/*.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now force-quit-gui.service swap-watchdog.service
./install.sh
```
Builds `swap-watchdog`, `force-quit-gui`, and `kdotool` via Dagger into
`bin/`, copies `kdotool` to `~/.local/bin`, installs the systemd user units,
and enables + starts both services.
The unit files' `ExecStart=` point at `%h/Code/swap-watchdog/bin/...` — if
you clone this somewhere other than `~/Code/swap-watchdog`, edit the unit
files to match before copying them.
files to match before running `install.sh`.
## Uninstall

View file

@ -1,7 +1,13 @@
#!/usr/bin/env bash
# Builds swap-watchdog / force-quit-gui and installs them as systemd user
# services. See README.md "Install" for the manual steps this automates,
# Builds swap-watchdog / force-quit-gui / kdotool and installs them as
# systemd user services. See README.md "Install" for what this automates,
# and uninstall.sh to remove them again.
#
# The build runs in an ephemeral Nix-provisioned container via Dagger (see
# .dagger/main.go) instead of requiring gtk3-devel, dbus-devel, or a Rust
# toolchain on the host -- those are only needed at build time, and the
# resulting binaries link against the host's own GTK3/D-Bus runtime libs,
# which any normal Linux desktop already has.
set -eu
cd "$(dirname "${BASH_SOURCE[0]}")"
@ -13,19 +19,20 @@ if [[ "$HOME/Code/swap-watchdog" != "$(pwd)" ]]; then
echo "find the binaries." >&2
fi
if ! pkg-config --exists gtk+-3.0 2>/dev/null; then
echo "Warning: gtk+-3.0 dev files not found (need gtk3-devel) --" >&2
echo "building force-quit-gui will likely fail." >&2
if ! command -v dagger >/dev/null 2>&1; then
echo "Error: dagger CLI not found. Install it (e.g. 'brew install dagger/tap/dagger')" >&2
echo "and a container runtime (podman or docker) before running this script." >&2
exit 1
fi
if ! command -v kdotool >/dev/null 2>&1; then
echo "Warning: kdotool not found -- swap-watchdog needs it at runtime" >&2
echo "to reveal the Force Quit Monitor window." >&2
fi
echo "Building swap-watchdog, force-quit-gui, and kdotool via Dagger+Nix..."
dagger call build-linux --src=. --go-toolchain="$(go env GOROOT)" export --path=./bin
echo "Building binaries..."
go build -o bin/swap-watchdog ./cmd/swap-watchdog
go build -o bin/force-quit-gui ./cmd/force-quit-gui
chmod +x bin/swap-watchdog bin/force-quit-gui bin/kdotool
echo "Installing kdotool to ~/.local/bin (so the systemd service can find it)..."
mkdir -p "$HOME/.local/bin"
cp bin/kdotool "$HOME/.local/bin/kdotool"
echo "Installing unit files..."
mkdir -p "$HOME/.config/systemd/user"

View file

@ -5,6 +5,7 @@ PartOf=graphical-session.target
[Service]
Type=simple
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=%h/Code/swap-watchdog/bin/swap-watchdog
Restart=always
RestartSec=5

View file

@ -20,4 +20,7 @@ echo "Killing any still-running instances..."
pkill -f "$HOME/Code/swap-watchdog/bin/swap-watchdog" 2>/dev/null
pkill -f "$HOME/Code/swap-watchdog/bin/force-quit-gui" 2>/dev/null
echo "Done. Source and binaries are untouched; re-run install steps from README.md to re-enable."
echo "Removing installed kdotool..."
rm -f "$HOME/.local/bin/kdotool"
echo "Done. Source and binaries are untouched; re-run ./install.sh to re-enable."