Commit Graph
4 Commits
Author SHA1 Message Date
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
LGUG2Z 12b0aa9301 feat(wm): the floating layer
A workspace with floating windows had no way to say which of the two kinds of
windows a focus or move command was about, so the commands always acted on the
tiles. A workspace is now on one of two layers, tiling or floating, and
`komorebic focus`, `cycle-focus`, `move` and the resize commands act on the
windows of that layer. Floating a window puts the workspace on the floating
layer, and so does a window that a float rule floats when it opens and a focus
change to a floating window; putting the window back, tiling a new window and a
focus change to a tile put it on the tiling layer. `komorebic
toggle-workspace-layer` switches it by hand: the windows of the layer it goes to
are raised, the focused one last, and one of them is given the focus. Going to
the tiles hides the floating windows, and going back to the floating layer shows
them.

On the floating layer, focusing in a direction goes to the nearest floating
window on that side and, where there is none, crosses to the next workspace or
the monitor on that side as it does for tiles, and fails where there is none.
Cycling goes round the floating windows in the order they were floated, `move`
moves the focused floating window by the resize delta without leaving the work
area, the resize commands change its frame, and `preselect-direction` does
nothing. A floating window that is maximized leaves the floating windows. The
layer is in the state of each workspace.

A window that opens while a workspace is on its floating layer floats when the
floating layer behavior says so: the workspace's own, else its monitor's, else
the window manager's. All three tile by default, and only the configuration
file, which is not here yet, sets the first two.

komorebi/tests/floating_layer.rs drives the layers against the fake desktop,
with the floating layer behavior as well, and the vm-commands sweep runs the new
command.
2026-10-28 07:20:37 -07:00
LGUG2Z 331db681e2 feat(wm): stack out of sight on a parking desktop
A container has one tile, so the windows of a stack that are not in front have
to be out of sight. KWin has nothing a script can set to hide a window except a
virtual desktop nobody looks at, which the first spike measured to cost no focus
change where minimizing a window cost two. Backend::hide takes a window out of
sight and Backend::restore brings it back; the KWin backend parks the window on
a desktop named komorebi-park, which the table keeps out of the workspaces, and
remembers where each hidden window came from so that it is still on its
workspace.

KWin saves a desktop in kwinrc as soon as it is made, so komorebi removes the
parking desktop when it stops, after the windows are back, and the first
snapshot of the next run finds one a killed run left, sends its windows home and
removes it. The windows komorebi hid are recorded, so that a minimize the
compositor reports for one is not mistaken for the user's.

komorebic stack, unstack, stack-all and unstack-all stack and unstack windows.
The window container behavior and the float override decide whether a window
that opens joins the focused container or floats, for every workspace or for
one. vm-stacks stacks windows in a headless KWin, shows a workspace and goes
back, stops, and kills the daemon with a window parked.
2026-10-28 07:20:37 -07:00
LGUG2Z 062fe57fac feat(wm): float
Some windows are better left out of the layout. `komorebic toggle-float` takes
the window that has the focus out of its container into the floating windows of
the workspace, which komorebi gives no tile and does not move, and the other
windows share the work area; on a floating window it puts it back in a container
at the focused place.

A floating window is in the index of managed windows like any other, so its
events find it, and it is in the state as the workspace's `floating_windows`.
Where a floated window goes is the `toggle_float_placement` of the window
management behaviour: by default it stays where it is, since the spike's
centering of floated windows waited for a configuration file. Centering and
resizing to the floating aspect ratio come with it.

Opening windows floating (the float override and the float rules), the floating
layer and its own focus and move commands come later.

The vm-commands sweep floats a window and puts it back, and its health check
counts the floating windows.
2026-10-28 07:20:37 -07:00