Files
komorebi/docs/usage/stacking-windows.md
T
LGUG2Z 5eaa613f50 feat(wm): configuration in komorebi.json
The daemon takes its settings from a komorebi.json: the file --config names, or
the one in the config home ($KOMOREBI_CONFIG_HOME, else ~/.config/komorebi).
Without a file it runs on its defaults, as before.

StaticConfig reads the file in three steps, because the monitors are known only
after the backend has been asked. preload makes the window manager and applies
the settings that are process-wide, postload gives each monitor and workspace
the entry of its place (by the index display_index_preferences gives a monitor's
serial number id, else in order), and main asks KWin for a desktop for each
workspace the file lists. A watcher on the file sends the daemon a
ReloadStaticConfiguration about two seconds after it changes, whether an editor
wrote the file in place or renamed a new one over it, and a file that does not
parse changes nothing.

A workspace can change its layout, its work area offset and its layout options
with the number of its containers, from the file or with komorebic
(workspace-layout-rule, its named form and the two that clear), and
layout_defaults gives every workspace of a layout the options it sets none of.
One file is meant to serve every platform, so a key that does nothing on Plasma
is accepted and ignored. config_parity checks the example and the files of other
platforms; the keys of features that are not in yet are listed there, and the
test fails when a list names a key that is read.

The file also sets what the stacks, the float override, the floating layer and
monocle set while the daemon runs: window_container_behaviour, with its rules by
container count in a workspace, float_override, float_override_placement,
floating_layer_behaviour (for a monitor and a workspace too),
floating_layer_placement and monocle_focus_behaviour. Their features come before
this commit, but a file to put the keys in does not, so they are part of this
one.

komorebic gains configuration, generate-static-config and start --config. The
NixOS module gets configFile, which the unit gives the daemon as --config.
2026-10-28 07:20:37 -07:00

6.0 KiB

Stacking windows

A stack is a container with more than one window. The windows share one tile of the layout, and one of them, the window in front, is in sight: the others are out of the way. Stacking puts two windows on one tile, so the layout has one tile fewer to give out.

Putting windows in a stack

komorebic stack puts the focused window and the window on one side of it in one stack: left, right, up or down. As with komorebic focus, the layout decides which tile is on which side. The focused window ends up in front, and it keeps the focus. Where the layout has no tile on that side, nothing happens.

komorebic stack left
komorebic stack down

komorebic unstack takes the window in front out of its stack and puts it in a tile of its own after the stack, and the next window of the stack is in front again. A window that is alone on its tile cannot be unstacked, and the daemon logs "a container must have at least one window".

komorebic unstack

komorebic stack-all puts every window of the focused workspace in one stack, in the order they had, with the focused window in front. komorebic unstack-all takes every window out of the focused stack, each onto a tile of its own, and the window that had the focus keeps it.

komorebic stack-all
komorebic unstack-all

A stack moves as one: moving it with komorebic move or to another workspace takes every window in it. When the window in front closes, the next window of the stack comes to the front and has the focus.

Choosing the window in front

komorebic cycle-stack brings the next or the previous window of the focused stack to the front and gives it the focus; the window that was in front is hidden. It wraps around: next from the last window of the stack brings the first.

komorebic cycle-stack next
komorebic cycle-stack previous

komorebic focus-stack-window brings the window at an index of the stack to the front, counting from 0 in the order the stack has, which is the order of its windows in komorebic state. It works on the monitor the pointer is on, which it focuses first, so that a program such as a status bar that runs it when one of its tabs is clicked acts on the stack of its own monitor.

komorebic focus-stack-window 0

komorebic cycle-stack-index moves the window in front one place along the stack, swapping it with the window there, and wraps around the same way. It stays in front and keeps the focus: only the order of the stack changes, which is what cycle-stack and focus-stack-window count by.

komorebic cycle-stack-index next

A stack of one window cannot be cycled, and an index the stack does not have cannot be focused: the daemon logs "there is only one window in this container" or "there is no window in this container at index 5".

Windows that open into a stack

By default a window that opens gets a tile of its own. With the window container behavior set to append, a window that opens joins the focused stack instead, in front, and a workspace with no window still gives it a tile of its own, since there is nothing to join. komorebic toggle-window-container-behaviour switches every workspace between the two. komorebic toggle-workspace-window-container-behaviour does it for the focused workspace only: the first time, it takes the opposite of what every workspace has, and from then on it follows its own setting.

komorebic toggle-window-container-behaviour
komorebic toggle-workspace-window-container-behaviour

The setting is in the daemon's state, as new_window_behaviour for every workspace and as window_container_behaviour in each workspace that has one of its own.

In komorebi.json, window_container_behaviour is the setting for every workspace, Create or Append, and the entry of a workspace can have its own. The entry of a workspace can also have window_container_behaviour_rules, which give the behavior by the number of containers:

{ "name": "chat", "layout": "Columns", "window_container_behaviour_rules": { "2": "Append" } }

A window opens in a tile of its own until the workspace has two containers, and joins the focused stack from then on. The configuration page says how the rules and the toggle for one workspace go together.

Where the windows behind go

komorebi does not minimize the windows behind the front one: it moves them to a virtual desktop that nobody looks at, which it makes when it first needs it and calls komorebi-park. A window there is still open, still on its workspace as far as komorebi is concerned, and still in the stack, and it comes back to the desktop of its workspace when it is brought to the front, when it is unstacked, and when komorebi stops. The parking desktop is the last desktop, after the ones that are workspaces, and is not one of them.

KWin keeps its virtual desktops in its configuration as soon as one is made, so the parking desktop would be there in the next session if komorebi did not remove it. It does when it stops. If komorebi did not get to stop (it was killed, or the session ended under it), the next komorebi finds the parking desktop in KWin's list, sends the windows on it back to the first workspace's desktop, and removes it. If the parking desktop is removed while komorebi runs, the next hide makes a new one.

A window on the parking desktop can still be reached by something else. Raising one, with a click in the task manager, makes KWin show the parking desktop on that monitor, and komorebi sends the monitor straight back to the workspace it was showing. The window that was raised becomes the front of its stack when komorebi handles its focus change.