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.