Releases: topce/fq
Release list
fq 0.4.0 — macOS, Linux and Windows
The same command line everywhere, with a per-platform implementation behind it:
| macOS | Linux | Windows | |
|---|---|---|---|
| Enumeration | lsappinfo (the apps the Force Quit dialog shows), osascript fallback |
/proc scan of the graphical session, wmctrl -lpx alternative |
tasklist (windowed processes), PowerShell alternative |
| Kill | SIGKILL to the process group |
SIGKILL to the process group, or to the process tree |
taskkill /T /F |
Sleep (-s) |
pmset sleepnow |
systemctl suspend |
SetSuspendState |
Install
- macOS and Linuxbrew —
brew install topce/fq/fq(builds from this tag) - macOS, Linux —
opam install fq, or build from source:dune build - Arch Linux —
fqin the AUR - Windows — build from source with a native OCaml ≥ 5.1 and opam 2.2+
(dune build, then_build\default\bin\main.exe)
No prebuilt archives are attached to this release: Homebrew, opam and the AUR
build from this tag's source. See docs/RELEASING.md for how the optional
archives and the Scoop/WinGet manifests are produced and published.
Verification
macOS (arm64) has the full suite green — unit tests, the -s/--sleep end-to-end
checks, the platform checks against a fixture /proc tree — plus the real
lsappinfo backend. The Linux and Windows code paths are covered by
fixture-driven end-to-end tests (a synthetic /proc tree whose pids are live
processes for the Linux kill path; stub taskkill for the Windows one) and by
the unit tests, but this release has not been run on real Linux or Windows
hardware by the maintainer yet. Please report anything that misbehaves.
What changed
[0.4.0] - 2026-09-16
Added
- Linux support. Applications are enumerated from
/proc: a process is an
application when it runs in a graphical session (DISPLAY/WAYLAND_DISPLAY),
does not belong to a terminal (it is neither a shell nor the job a terminal
is running in the foreground — an application started withapp &or
detached from its terminal counts) and is not session infrastructure (window
manager, compositors, panels, session/sound daemons, portals, input methods).
Helper
processes of a multi-process application run the application's own binary and
are folded into it, and applications are named after their.desktopentry
when there is one. Victims are killed as a process group, or — for a process
that does not lead its own group — as a whole process tree read from/proc.
-b wmctrllists the windows on screen instead (X11). - Windows support. Applications are enumerated with
tasklist /V(windowed
processes; the image name without.exe), with PowerShellGet-Processas
the alternative backend. Victims are terminated withtaskkill /PID <pid> /T /F, helpers included. The process tree is read once with PowerShell for
the "this terminal is never killed" logic. - Platform-specific sleep commands:
systemctl suspend(withpm-suspendand
zzzas fallbacks) on Linux andSetSuspendState('Suspend')(with
rundll32as a fallback) on Windows. On Windows the detached helper that
guarantees the sleep when the terminal itself is force-quit is a hidden,
detached PowerShell script. - Platform-specific protected system applications: the session shell, window
managers and session daemons on Linux; Explorer, the desktop window manager
and the core session processes on Windows. -b/--backendaccepts the backends of the running platform only, and an
unsupported platform is refused with a clear message instead of failing
somewhere deeper.- The help text, prompts and messages are platform-aware ("put the Mac to
sleep", "put the computer to sleep", "put the PC to sleep"). - Packaging for every channel:
packaging/renders the Homebrew, Scoop,
WinGet, AUR and nfpm manifests from aSHA256SUMSfile, and
docs/RELEASING.mdis the release runbook (tagging, the package managers,
building the optional archives by hand, canary stage, verification,
rollback, monitoring). - Test hooks for driving the non-native code paths anywhere:
FQ_PLATFORM,
FQ_ENUM_OUTPUT,FQ_PROC_ROOTandFQ_DESKTOP_DIRS(documented in the
README), plustest/test_platforms.sh, which exercises the Linux backend
and its real kill path against a synthetic/proctree.
Changed
- A failed force-quit now always exits 1. Previously the exit status was only
turned into 1 by-s/--sleep; without it, a force-quit that failed (a
permission error, say) reported the failure but exited 0, contradicting the
documented exit status. FQ_APPS_FILEis read directly instead of withcat, so the test hooks work
on Windows too.
fq 0.3.1
fq 0.3.1
Bug-fix release. fq -y -o -s no longer kills fq's own process group — the
"self process" — so it reliably keeps the terminal running and still puts the
Mac to sleep.
Fixed
--othersno longer kills fq's own process group. If an application in the
list led fq's process group (so it was not an ancestor), fq treated it as a
victim and sentSIGKILLto the whole group, taking itself down with it; the
requested-s/--sleepthen never happened. The process-group leader is now
treated as self by--others, andforce_quit_pidnever signals fq's own
process group or pid, so the sleep (and anything else still to do) always
runs.- With no other application to quit,
fq -o -y -sstill puts the Mac to sleep.
Tests
test/test_sleep.shcovers the self-process case: fq is placed in a process
group led by a non-ancestor application and-o -y -smust leave that
application running and still put the Mac to sleep.test/test_fq.mlchecks that a force-quit refuses fq's own pid.
Install
brew install topce/fq/fqNote: an unrelated message broker is also published as
fqin homebrew-core,
so use the fully qualifiedbrew install topce/fq/fq.
Full changelog: https://github.com/topce/fq/blob/main/CHANGELOG.md
v0.3.0
Fixed
-s/--sleepis no longer skipped when there is nothing to force-quit. Every
mode that found zero victims exited before reaching the sleep code, so
fq -o -y -s— the natural "quit everything else, then sleep" command —
silently did nothing at all when every other application was protected or
the application running the terminal was the only one left. The sleep is now
a step of its own that every mode reaches; with nothing to quit and without
-y, fq asks about the sleep alone ("Put the Mac to sleep? [y/N]") instead
of asking to force-quit zero applications.- The sleep is no longer asked for twice: the combined "force quit … and put
the Mac to sleep?" confirmation now covers the sleep, so a singleyboth
quits and sleeps. This was still broken when naming an application on the
command line (fq -s Safari), which asked a second time after the firsty
and then treated the second, unanswered prompt as a decline — so the Mac was
never put to sleep.
Added
FQ_SLEEP_CMDoverrides the program used to put the Mac to sleep, and
FQ_APPS_FILE(pid namelines) overrides application enumeration. Both
exist so the test suite can exercise the real code paths without touching
running applications or actually sleeping the machine.
Tests
test/test_sleep.shcovers the sleep behaviour end to end, driven through
the built executable with a synthetic application list and a stub sleep
command: nothing-to-quit still sleeps (including a machine with no
applications at all), one confirmation never asks twice (for--others,
--pid, and a named application alike), a declined confirmation never
sleeps, and a refused protected application exits 1 without sleeping.