Environment and IPC
A running kiln is scriptable from the outside: it loads its config from a fixed search order, exports its socket path to every child process, and evaluates any Lua written to that socket, which makes the socket a live REPL into the compositor.
# ask a running kiln a question from a shell
scripts/kiln-eval 'return #client.all()'
Environment variables
Read by the compositor:
| Variable | Description |
|---|---|
KILN_RC | Explicit path to the config file to load; overrides the search order below. |
KILN_SOCK | Path for the IPC socket. Default: $XDG_RUNTIME_DIR/kiln.sock (falling back to /tmp/kiln.sock). Set it to give an instance a private socket, for example a nested session next to a headless test run. |
KILN_IMAGE_BUDGET_MB | Image decode cache budget in MB (default 64). A working set larger than the budget stays correct but re-decodes per frame. |
LC_ALL, LC_CTYPE, LANG | Checked in that order to build the keyboard compose table (dead keys). A locale with no compose table, such as C, leaves compose off. |
Set for child processes (everything launched via core.spawn and friends):
| Variable | Description |
|---|---|
WAYLAND_DISPLAY | The compositor's Wayland socket, so spawned clients connect to this kiln. |
DISPLAY | The Xwayland display, when kiln is built with Xwayland (the X server itself starts lazily on the first X client). |
XDG_ACTIVATION_TOKEN | Set only for core.spawn_with_token children, so the launched client can raise itself as user-initiated. |
Read by the default config, not the compositor:
| Variable | Description |
|---|---|
KILN_WALLPAPER | Path to a wallpaper image; the default config's backdrop recipe reads it and draws the image behind every client. A custom rc.lua only honors it if it does the same. |
Config search order
First hit wins:
KILN_RC(used verbatim if set and non-empty)$XDG_CONFIG_HOME/kiln/rc.luawhenXDG_CONFIG_HOMEis set, otherwise~/.config/kiln/rc.lua- The installed default,
<prefix>/share/kiln/rc.lua rc.luain the working directory (how kiln runs from a source tree)
Flags
| Flag | Description |
|---|---|
-s <command> | Run a startup command once the compositor is up. |
kiln -s 'foot'
IPC: the eval socket
kiln listens on a unix socket (mode 0600, owner only) and evaluates whatever Lua you send, inside the same VM that runs your config: a live REPL into the config VM, and everything in this reference is drivable over it. The same socket also carries a fixed command surface for the kiln-client CLI; commands travel wrapped in kiln_ipc(...), so bare text is always read as Lua.
The protocol:
- Connect to the socket and write Lua source.
- Half-close the write side (send EOF). The compositor evaluates on half-close.
- Read one reply, then the connection closes.
Evaluation tries expression form first (so 1+1 answers 2), then statement form, so both expressions and statements work. The reply is the results tab-joined through tostring with a trailing newline, or ERROR: <msg> on a load or runtime error, capped at 4096 bytes.
scripts/kiln-eval in the source tree wraps this with nc:
scripts/kiln-eval 'return core.output.list()[1].name'
scripts/kiln-eval 'core.spawn({ "foot" })'
echo 'require("kiln").notify{ title = "hi", message = "from IPC" }' | scripts/kiln-eval
Anything that can connect to the socket evaluates arbitrary Lua in your compositor, including while the screen is locked. The 0600 mode keeps that to your own user; do not loosen it.
See also
- kiln-client: the CLI over this socket, verbs and selectors
- IPC and scripting: workflows built on the socket
- Testing headless: a private instance with
KILN_SOCKandKILN_RC - Reload and debugging: poking a live session
- core: the raw surface you can drive over IPC