Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Evilchuck666/WinJitsu/llms.txt

Use this file to discover all available pages before exploring further.

Without a background daemon, every winjitsu N (or any other action) would cold-start a new Python process, query the display, animate the window, and exit — adding perceptible latency on every hotkey press. The daemon eliminates that overhead by staying warm between presses. It also solves the key-repeat problem: when a held hotkey fires ten times per second, the daemon collapses the burst into a single animation rather than launching ten overlapping ones.

Starting the daemon

Run winjitsu --daemon once, typically at login. The parent process forks a child, prints its PID, then exits immediately so your terminal or autostart script is not blocked. The child calls os.setsid() to become its own session leader and detaches from the controlling terminal, then redirects stdin, stdout, and stderr to /dev/null.
winjitsu --daemon
winjitsu daemon starting (PID 12345)
Add winjitsu --daemon to your window manager’s autostart, ~/.xprofile, or your desktop environment’s session startup applications so the daemon is always available when you log in.

Reloading the daemon

winjitsu --reload-daemon performs a graceful rolling restart:
1

Read the PID file

The command reads the stored PID from the runtime directory.
2

Send SIGTERM

It sends SIGTERM to the old daemon process.
3

Poll for exit

It polls with os.kill(pid, 0) in 0.1-second intervals for up to 5 seconds, waiting for the process to disappear.
4

Fork a new daemon

Once the old process is gone, a fresh daemon is forked with the current configuration.
winjitsu --reload-daemon
If no PID file exists when you run --reload-daemon, the command exits with an error:
No daemon running.
A stale PID file can be left behind if the daemon crashed or was killed without cleanup. When --reload-daemon finds a PID file but the process no longer exists (a ProcessLookupError on the liveness check), it removes the stale file and exits with No daemon running (stale PID file). — it will not fork a new daemon in that case. Run winjitsu --daemon directly to start fresh.

Runtime files

The daemon creates two files under a versioned runtime directory:
FileDefault path
Unix socket$XDG_RUNTIME_DIR/winjitsu/winjitsu.sock
PID file$XDG_RUNTIME_DIR/winjitsu/winjitsu.pid
$XDG_RUNTIME_DIR defaults to /run/user/<uid> when the environment variable is not set, so on most systems the socket lives at /run/user/1000/winjitsu/winjitsu.sock. The directory is created with parents=True, exist_ok=True on daemon startup, and both files are removed when the daemon exits cleanly. The socket is created with mode 0o600, so only the owning user can connect to it. On startup the daemon also calls clear_cache(), which deletes all rows from the windows table in the SQLite state database. This ensures that stale window positions from a previous session do not affect the first U (restore) call after a reboot or re-login.

Debounce logic

The daemon’s --delay-ms option (default 250 ms, config key [daemon] delay_ms) controls the debounce window. When the daemon receives an action over the socket it does not execute immediately. Instead it:
  1. Cancels any pending timer from a previous action in the burst.
  2. Immediately resolves the superseded action with OK so the old client can unblock.
  3. Schedules the new action to fire after delay_ms milliseconds.
If the window passes without another action arriving, the last action executes. This means rapid key-repeat bursts — common with held modifier combinations — collapse into exactly one animation.
# Start with a tighter debounce window (100 ms) for fast typists
winjitsu --daemon --delay-ms 100

# Increase to 400 ms if key-repeat still causes double-fires
winjitsu --daemon --delay-ms 400

How actions are sent to the daemon

Every winjitsu <ACTION> invocation (e.g., winjitsu N) is a thin client that:
  1. Checks whether $XDG_RUNTIME_DIR/winjitsu/winjitsu.sock exists.
  2. Opens a AF_UNIX / SOCK_STREAM connection to the socket.
  3. Sends ACTION\n (e.g., N\n).
  4. Reads one line back from the daemon and exits.
The daemon responds with one of three prefixes:
ResponseMeaning
OKAction completed successfully.
WARN: <message>Action ran but produced a warning (e.g., no cached state to restore). Printed to stderr.
ERROR: <message>Action failed. Printed to stderr; client exits 1.

Error handling

If the socket file does not exist at the time winjitsu <ACTION> is called, the client prints the following message to stderr and exits with code 1:
Error: WinJitsu daemon is not running. Start it with: winjitsu --daemon
No connection is attempted and no exception is raised — the missing socket is treated as a clean “daemon not running” signal.

Build docs developers (and LLMs) love