Commit graph

14 commits

Author SHA1 Message Date
Philip Peterson
cb12599391 RPM: each architecture natively, on its own runner
All checks were successful
RPM / rpm (arm64, runner-arm64-linux) (push) Successful in 3m4s
RPM / rpm (amd64, runner-x86-linux) (push) Successful in 1m7s
arm64 builds on the new runner-arm64-linux instead of under emulation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 21:50:12 -09:00
Philip Peterson
ca5d81f2cb RPM: build with the shared quine-global/app-build action
Some checks are pending
RPM / rpm (push) Waiting to run
Its build script moves there, shared with our other apps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 21:05:16 -09:00
Philip Peterson
8564589ff5 RPM: build for arm64 too, under emulation
All checks were successful
RPM / rpm (push) Successful in 31m47s
quine-linux's arm64 image installs it. force-quit-gui links GTK through
cgo, so arm64 builds in an arm64 Fedora rather than cross-compiling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 20:56:29 -09:00
Philip Peterson
b820393162 Package as an RPM, built and published by Forgejo Actions
All checks were successful
RPM / rpm (push) Successful in 49s
packaging/ builds swap-watchdog and force-quit-gui in a Fedora container
and makes an RPM, with the user services pointing at /usr/bin and a preset
enabling them; kdotool comes from Fedora's package.
.forgejo/workflows/rpm.yml runs that on each push to main and uploads it
to the forge's quine RPM group, which quine-linux's image installs from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 03:53:59 -08:00
Philip Peterson
fabe2c664e Show a swap-full warning banner and mem accounting in force-quit-gui
Adds a red "SWAP IS FULL" header plus a live swap/RAM usage line
(used/total/% full) above the process list, refreshed alongside it,
so the kill window gives context on why it popped up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-07 13:35:48 -08:00
Philip Peterson
c0ac538e6f Document force-quit-gui-nucular's GTK-free build rationale in README
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 10:07:08 -08:00
Philip Peterson
ffdf48f83b Preserve scroll position in force-quit-gui across refreshes
store.Clear() snaps the scrollbar to the top immediately, but GTK doesn't
recompute the adjustment's upper bound until its next layout pass, so
restoring the saved position synchronously was getting clamped against the
stale, just-emptied bound. Deferring the restore to an idle callback runs
it after that layout pass instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 09:42:05 -08:00
Philip Peterson
089f1fb9ff 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>
2026-10-06 09:41:52 -08:00
Philip Peterson
889a2c4d50 Fix force-quit-gui losing row selection on every refresh
refresh() rebuilt the GtkListStore from scratch every 2s via
store.Clear(), which invalidates GtkTreeSelection's TreeIter -- so the
highlighted row silently dropped on every tick even when the process
list hadn't meaningfully changed. Now the selected PID is captured
before the rebuild and the matching row is reselected after, mirroring
the PID-based (rather than row-reference-based) selection tracking the
nucular prototype already used.

Verified live: selected PID 19777 stayed highlighted across a refresh
cycle where its RSS/Swap/Total values visibly changed, confirming the
reselect logic runs on real data, not a no-op refresh.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 07:08:59 -08:00
Philip Peterson
141d4f7690 Build swap-watchdog binaries via a Nix-provisioned Dagger pipeline
Replaces the generated dagger scaffold with a real BuildLinux function
that compiles swap-watchdog, force-quit-gui, and kdotool (not packaged
for Fedora, so built from source via cargo) inside an ephemeral
nixos/nix container -- no gtk3-devel/dbus-devel/rust toolchain needs
installing on the host. The host's own Go toolchain is mounted in so
the build matches go.mod's required version exactly.

Nix's glibc uses a non-FHS dynamic linker path that doesn't exist
outside the container, so the built binaries are patched with
patchelf to point at the host's real ld.so; the stale nix-store
RUNPATH entries are harmless since ld.so just skips nonexistent
directories and falls through to the host's normal library search
path, where the real libgtk-3/libdbus-1/etc already live.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 06:54:49 -08:00
Philip Peterson
e0daa6b1e5 Fix nucular prototype's close-to-exit gap via respawn + kdotool
nucular/x11driver can't intercept-and-cancel a WM close request the way
GTK's delete-event handler does, so clicking the window's X would exit
the process -- unacceptable for a tool that's supposed to stay warm and
resident. Rather than patching nucular/x11driver to add that capability,
reuse the external window management swap-watchdog already depends on:
loop in main(), reopening and re-minimizing the window via kdotool each
time it closes. The process, and its warm Go runtime, never exits.

Verified by sending a raw WM_DELETE_WINDOW client message to the running
window: the process survived under the same PID and a new window
reappeared with a different window ID.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 06:22:58 -08:00
Philip Peterson
6f7c2f8a8c Add install script, license, and dagger pipeline scaffolding
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 06:20:03 -08:00
Philip Peterson
4efaa8ddee Add nucular-based prototype of force-quit-gui
Evaluates dropping the GTK3 dependency in favor of a pure-Go, no-cgo
toolkit. Built with -tags nucular_shiny to force the x11driver backend
(nucular's default backend now pulls in Gio/cgo/EGL, which would
defeat the purpose). Reads Xft.dpi directly via xgb for HiDPI scaling,
since nucular has no built-in DPI awareness.

Known gap: x11driver exposes no iconify/withdraw call, so unlike the
GTK version, closing the window exits the process instead of hiding
it. Tracked as a TODO in the file header for follow-up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 06:18:37 -08:00
Philip Peterson
20abe80132 Initial commit: swap-watchdog + Force Quit Monitor
Polls /proc/meminfo swap and /proc/pressure/memory PSI every 3s; on a
rising edge into critical, reveals an always-running, normally-minimized
GTK3 process-killer window via kdotool rather than spawning anything new
at the exact moment the system is least able to launch a process.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 05:47:14 -08:00