komorebi managed every normal window that is alive, and there was no way to keep an application out of the layout. The rule engine decides whether a window is managed: an ignore rule keeps the windows it matches out, unless a manage rule matches them too, and a float rule puts a window in the floating windows of its workspace when it opens. A rule matches a window by its title, its executable, its class or the path of its executable. Plasma's shell and KRunner are ignored from the start. `komorebic ignore-rule` and `manage-rule` add a rule, `session-float-rule` floats the focused window and the windows like it until the daemon stops, `clear-session-float-rules` removes those rules, and `global-state` shows the rules. The `DebugWindow` message says why a window is managed or not. Applications often open a window before they give it its title, so the bridge now reports a title change, and a window komorebi does not have is asked about again when its title changes, for a rule on the title to decide. The vm-commands sweep adds and shows rules, and a section of its own checks that a window an ignore rule matches by its first title is tiled once it has another. vm-kwin-events checks that a window giving itself another title reaches the daemon as a title update.
komorebi for KDE
A tiling window manager for KDE Plasma on Wayland, in the family of komorebi for Windows and komorebi for Mac. The daemon decides where each window goes, and KWin, the window manager of Plasma, does the moving and the drawing.
Installing it
On NixOS, the flake's module, services.komorebi, installs komorebi and
komorebic and starts komorebi with every Plasma session: one flake input,
one module line and services.komorebi.enable = true. Elsewhere, both are
built from source. docs/installation.md has both
ways. There are no prebuilt binaries: the Komorebi license does not allow third
parties to redistribute them.
Running it locally
nix develop
cargo run --bin komorebi --locked -- --version
cargo run --bin komorebi --locked -- --log-level debug
cargo run --bin komorebi --locked -- --fake-backend
Inside a Plasma Wayland session, komorebi loads a script into KWin, reads the
monitors and the windows that are open, tiles them, and tiles the windows again
whenever one opens, closes, takes the focus, is minimized or comes back, until
it is stopped with Ctrl-C. It needs KWin 6.8 or newer;
docs/dev/PLATFORM.md has what it expects of the
session. Outside a Plasma session it exits with an error that says what is
missing. --fake-backend runs the window manager against an in-memory desktop
with one monitor and no windows instead.
While it runs, the daemon takes messages on a Unix socket, komorebi.sock in
$XDG_RUNTIME_DIR/komorebi (the local data directory when there is no runtime
directory): a message can ask for the state of the window manager, ask which
monitor, workspace or container has the focus, give the focus to another
window, move the focused window to another tile, change the layout, resize a
tile, float a window, retile every monitor, or stop the daemon. komorebi-client writes them, and komorebic,
the command line, is how a person sends them. komorebic start runs the
komorebi on the PATH, and passes it what follows a --. In a Plasma
session:
cargo build --locked
export PATH="$PWD/target/debug:$PATH"
komorebic start
komorebic state
komorebic stop
komorebic start -- --fake-backend tries the daemon and komorebic without a
compositor, against the in-memory desktop.
nix develop provides the Rust toolchain that rust-toolchain.toml
selects, a nightly rustfmt, and the tools just check and the flake's checks
use. With direnv, the .envrc does it on
cd. On Linux, nix run .#komorebi -- --version builds and runs the daemon
without a checkout of the toolchain.
Crates
komorebi: the daemon, and the library behind it. The library has the vocabulary the window manager is written in (core), theBackendtrait through which it reaches a compositor and the in-memory desktop the tests use (backend), the backend that reaches KWin through a script it runs (kwin), the model of what it tiles (monitor,workspace,container,window), the window manager that keeps the model (window_manager), loads it from the backend (desktop) and changes it when the compositor reports an event (window_manager_event,window_manager_event_listener,process_event), theRingthat holds monitors, workspaces and containers, and the lists in which some elements are locked in place. It answers the messages on the daemon's socket (core::SocketMessage,process_command), shows its state (state), and sends its subscribers a notification of each event and message it handles (notify_subscribers).komorebi-client: a library that sends messages to the daemon, reads its answers, subscribes to its notifications, and re-exports the types they are made of.komorebic: the command line. A subcommand that asks something of the daemon is one message on its socket;start,log,data-directory,completionsand the hiddendocgenwork without the daemon.version: the version string every binary reports.
The layouts, which turn a work area and a number of containers into a rectangle
for each, are komorebi-layouts from komorebi,
a git dependency at the revision Cargo.toml pins.
Checks
just check runs the formatting check, clippy with warnings denied, the tests,
rustdoc with warnings denied, and the type check and tests of the bridge (no
package.json: tsc and node come from the dev shell), inside nix develop.
nix flake check runs the same checks as derivations, plus cargo deny, the
TOML and Nix formatting, the tests under cargo nextest, and
nixos-module-eval, which evaluates the NixOS module in real NixOS systems, on
Linux and on an Apple silicon Mac. On Linux it also boots every VM test, which
needs KVM. A Mac runs the tests against the fake desktop, since KWin only exists
on Linux. nix fmt formats every file the checks look at.
The VM tests boot NixOS with Plasma and run a real KWin, on machines configured
with the NixOS module, so every one of them runs komorebi as the module installs
it. just vm NAME runs one; docs/dev/vm-tests.md has
the details, including how to run them on a Mac.
How it fits together
The daemon decides where every window goes and asks the compositor to put it
there. Everything it needs from the compositor is behind one trait, Backend,
so the window manager logic runs against a real compositor and against an
in-memory fake desktop alike. docs/dev/ARCHITECTURE.md
describes the trait and where each of its rules is enforced.
On KDE Plasma the backend is in two parts. A script that komorebi loads into KWin, the bridge, reports what KWin sees over the session bus, and carries out the commands it is given as the answer to a call it holds open. The daemon keeps a table of the windows and monitors from those reports, answers the window manager's questions from it, and turns each report into an event for the window manager. If KWin restarts, the daemon loads the bridge into the new one.
The window manager models the desktop as monitors, each with a ring of workspaces, each with a ring of containers, each with a ring of windows. A workspace's layout gives each of its containers a tile of the monitor's work area, and every window of a container is moved onto its tile. At startup the window manager loads the monitors and the windows that are open from the backend and tiles them; after that it changes the model when the compositor reports that a window was shown, closed, focused, minimized or restored, and tiles the workspace in front again.
Everything else reaches the daemon as a message on its socket: one JSON
SocketMessage per line, handled one at a time with the window manager
locked. A message that asks a question is answered on the same connection. A
message that gives an order changes the model the way an event does: focus
and cycle-focus give the focus to the container on one side of the focused
one in the layout, or to the next one in the workspace's order, and move and
cycle-move swap the focused container with that one and tile the workspace
again. change-layout, cycle-layout and flip-layout tile the workspace in
another layout, layout-ratios and scrolling-layout-columns tune it,
toggle-tiling stops it moving windows and starts it again,
preselect-direction reserves a tile for the next window, resize-edge and
resize-axis move the edges of the focused tile, promote brings the
focused window to the largest tile, toggle-float takes it out of the
layout, and toggle-lock keeps its container at its place. The scrolling layout
is a strip of columns that runs past the edges of the monitor and scrolls to
the window that has the focus. minimize and close ask KWin to minimize or
close the focused window, unmanage takes it out of the layout until manage
takes it back, and toggle-pause stops the daemon acting on events and orders
until it is resumed. The padding commands set the gaps around the tiles, and
the work area offsets keep parts of a monitor free of tiles. Rules decide which
windows are managed at all: ignore-rule keeps an application out of the
layout, manage-rule tiles it whatever the ignore rules say, and
session-float-rule floats the focused window and the windows like it.
A program such as a status bar can subscribe to the daemon's notifications: it listens on a socket of its own, and after each event and each message, the daemon connects to it and writes the event or the message with the state of the window manager.
On NixOS, the module nix/nixos-module.nix runs the
daemon as a systemd user unit that the Plasma session starts, and systemd
starts it again if it fails.
Documentation
The user guide starts at docs/index.md,
docs/installation.md says how to install komorebi,
and docs/cli has a page for every komorebic subcommand, which
just docgen writes from the subcommands' help.
cargo doc --workspace --no-deps --open builds the API documentation.
CONTRIBUTING.md says how to work on the code.
docs/dev/ARCHITECTURE.md describes the model,
docs/dev/DESIGN.md says why it is built that way,
docs/dev/PLATFORM.md what it needs from KDE Plasma,
and docs/dev/vm-tests.md how the VM tests work.
License
komorebi for KDE is under the Komorebi License. Contributions
are accepted under the terms in CONTRIBUTING.md.