Files
komorebi/docs/usage/running-komorebi.md
T
LGUG2Z 9cb26daf38 build(nix): keybindings in the module
On NixOS the key bindings belong in the configuration, with the rest of
komorebi. services.komorebi.keybindings takes the format (skhd, whkd or sxhkd),
the bindings as text or as a file (exactly one of the two, asserted), the mode
(auto, engine or static; engine by default, as PlanMode::default() is),
chordTimeout (3000 ms), layout (us, the only one), strict and appAliases. skhd's
.load is refused by an assertion: the file it reads would not be in the store.

At build time the module runs komorebic hotkeys compile on the file in the
package komorebi-keybindings, whose share/kglobalaccel goes into the system
profile, where KWin finds the static shortcuts when the session starts. Its
diagnostics are in the build log and in diagnostics.txt, and strict passes
--strict, which fails the build on a warning or an error. execStart gains
--keybindings with the same store file, its format and mode, --chord-timeout and
an --app-alias per alias, so the daemon plans the file as the build did and runs
the bindings the build left to the engine. The unit already releases the keys
after the daemon stops.

The check keybindings-fixtures runs every file of the fixture corpus through
komorebic hotkeys compile --mode auto --dry-run, the command the module runs,
and diffs what it prints against nix/tests/keybindings.expected; it also checks
that docs/{skhdrc,whkdrc,sxhkdrc}.sample are the corpus's sample case.
nixos-module-eval gains the key binding scenarios: text, file, both, no format,
.load and a layout that is not us, and one with the typed config together with
key bindings, whose execStart has the checked file and then the keys. The corpus
gains the case vm, in the three formats: a binding a shortcut file can hold, and
one on the comma key, which X-KDE-Shortcuts cannot, so that the engine runs it
in auto mode. The VM suites vm-keys-skhd, vm-keys-whkd and vm-keys-sxhkd
configure the module with that case in their format and press both keys; they
share one script through the generator's script attribute.

For strict, nixos-module-eval has two scenarios with the same skhd text, which
has a line komorebic cannot read: strict = true and the default. Evaluation
never reads the key bindings, so the checks read the script of the build: with
strict it runs hotkeys compile --strict and exits 1 when that fails, without it
there is no --strict and the diagnostics are only printed to the build log. A
third check says the daemon gets the same command line either way. ARCHITECTURE
names them in the row for strict.

komorebic quickstart writes the sample skhdrc next to komorebi.json and
applications.json, from docs/skhdrc.sample, where the daemon and hotkeys compile
read it; the flake's source filter keeps that file for the build.

Docs: the user guide docs/usage/keybindings.md, the three sample files,
docs/example-configurations.md for KDE and NixOS, the options in
docs/installation.md, and the module's section of ARCHITECTURE. Whether the
engine or static shortcuts should be the default stays open in DESIGN: a static
shortcut took 233 ms to run its command at the median on KWin 6.8.1, the engine
3 ms, but only the static shortcut survives a dead daemon.
2026-10-28 07:39:49 -07:00

7.9 KiB

Running komorebi

komorebi is the daemon that tiles your windows, and komorebic is the command line you control it with. This page covers starting and stopping the daemon, asking it what it is doing, and reading its log.

Getting the two programs

Installing komorebi covers NixOS, where the flake's module installs both and starts the daemon with every Plasma session, and building them from source. In a checkout of the repository, on Linux, nix build leaves them in result/bin, and nix profile install . puts them on your PATH. Without nix, build them with the Rust toolchain that rust-toolchain.toml selects:

cargo build --release --locked
export PATH="$PWD/target/release:$PATH"

With the NixOS module, the daemon is the user unit komorebi.service, which starts when you log in to Plasma. systemctl --user start komorebi starts it again after a komorebic stop, and journalctl --user -u komorebi shows what it wrote. Everything else on this page applies to it as it is.

Starting and stopping

komorebic start runs the komorebi on your PATH in the background, and checks three seconds later that it is running. It tries three times. If komorebi has not started by then, komorebic start runs it once more in the foreground and prints what it wrote on its standard error, which explains why it did not start. When a komorebi is running already, komorebic start does nothing.

komorebi manages the windows of the Plasma Wayland session it is started in: it connects to KWin on the session bus and loads a script into it, so start it from a terminal in that session. Outside a Plasma session it exits with an error that says what is missing, which komorebic start prints. komorebic check says what is missing from the session, and what is wrong with the configuration, without starting anything.

--config gives the daemon the komorebi.json to read (Configuration says where it looks otherwise), and komorebic quickstart writes one to start from:

komorebic start --config ~/mine.json

Everything after a -- is passed to komorebi. --fake-backend runs it against an in-memory desktop with one monitor and no windows instead of KWin, which is a way to try the daemon and komorebic without a compositor:

komorebic start
komorebic start -- --log-level debug
komorebic start -- --fake-backend

komorebic stop tells the daemon to stop. It brings back the windows it hid (the back of a stack, stacking windows, and the windows behind a monocle), removes the desktop they were hidden on, asks KWin to unload its script, removes its socket and exits. Stopping the process with SIGINT or SIGTERM does the same.

Key bindings

Key bindings is the guide to key bindings, and to the NixOS module's options for them; this section is a summary for a daemon started by hand.

komorebi reads key bindings from a file in the format of skhd, whkd or sxhkd. The daemon looks for skhdrc, whkdrc or sxhkdrc in ~/.config/komorebi (or in $KOMOREBI_CONFIG_HOME) and takes the first it finds; --keybindings FILE names another, with --keybindings-format skhd|whkd|sxhkd when its name does not end with one of those. The daemon registers the keys with KDE itself and runs the command of each press:

komorebic start -- --keybindings ~/dotfiles/skhdrc

KDE can also run a binding with no komorebi process, as a static shortcut that shows in System Settings: komorebic hotkeys compile writes those, and --mode auto writes every binding that can be one. Give the daemon the same mode, so that it leaves those bindings to KDE:

komorebic hotkeys compile --mode auto
komorebic start -- --keybindings-mode auto

The daemon realizes the modes of an skhdrc (and the chains of an sxhkdrc that stay open) itself: while a mode is active, only its keys are taken, and every other key reaches the window as usual. The log says which mode the daemon is in after each change. A chord chain of an sxhkdrc (alt + w ; h) works the same way: after alt + w, only the keys that can come next and Escape are taken, until one of them is pressed or 3 seconds pass (--chord-timeout 1500 waits 1.5 seconds instead).

A binding that does something else in each application (skhd's [ ... ] list, whkd's per-application list) takes its key only while an application it names has the focus, or any application for a * or Default entry; everywhere else the key reaches the application. A name matches the executable, the Wayland app id (org.kde.konsole) or the desktop entry of the focused window, whatever the case. skhd and whkd name applications as macOS and Windows do, so give the daemon the names they have on KDE:

komorebic start -- --app-alias firefox=firefox-esr,librewolf --app-alias Terminal=konsole

komorebic hotkeys state shows the keys komorebi has registered with KDE and what the daemon's engine is doing (its mode, and the keys it holds), and komorebic hotkeys reload has the daemon read its key binding file again. A daemon that is killed leaves its keys swallowed until it is started again; komorebic stop gives them back, and so does komorebic hotkeys release, with or without a daemon, which the NixOS module's unit runs after the daemon stops. When KWin restarts, the daemon registers the keys again with the new KWin.

Asking komorebi what it is doing

The daemon answers questions on its socket, and these commands print the answers:

  • komorebic state: every monitor, with its workspaces, their containers and the windows in them, as JSON.
  • komorebic monitor-information: the id, the name and the bounds of every monitor, as JSON.
  • komorebic query: one value, the answer to one question: the index of the focused monitor, workspace, container or window, the layout of the focused workspace, whether the focused container is a single window or a stack, or the version of the daemon.
komorebic query focused-workspace-index
komorebic state | jq '.monitors.elements[0].workspaces.elements[0].containers.elements | length'

komorebic retile tiles the windows of every monitor again, which puts a window that was moved by hand back on its tile.

When the daemon is not running, these commands fail: there is no socket to write to.

A program that wants to know what komorebi does without asking can subscribe to its notifications instead (Subscribing to notifications).

The socket and the data directory

The daemon listens on komorebi.sock in its data directory, $XDG_RUNTIME_DIR/komorebi (the local data directory, ~/.local/share/komorebi, when there is no runtime directory). komorebic data-directory prints the directory, if it exists.

The log

The daemon logs to its standard output and to a file a day in ~/.local/share/komorebi ($XDG_DATA_HOME/komorebi when that is set): komorebi.log.YYYY-MM-DD, with colors, and komorebi_plaintext.log.YYYY-MM-DD, without. The day is the UTC date.

komorebic log follows the file of the current day, with colors, until you press Ctrl-C. The --log-level of komorebi sets how much is logged: error, warn, info (the default), debug or trace.

Shell completions

komorebic completions prints a completion script for bash, elvish, fish, PowerShell or zsh:

komorebic completions fish > ~/.config/fish/completions/komorebic.fish
komorebic completions bash > ~/.local/share/bash-completion/completions/komorebic

Every command

docs/cli has a page for every komorebic command, generated from its help with just docgen.