docs/dev/COMPARE.md says what komorebi for KDE shares with komorebi for Windows
and komorebi for Mac, what differs, what KDE does by itself and what is not
supported, for a reader who knows komorebi on one of them. Its tables are
generated by scripts/compare-gen.py from this checkout and from checkouts of the
other two, because a count or a name typed by hand is wrong after the next
change to a command, a key or an event. The script also checks the notes that
say why a command has no counterpart, and the sentences of the document that
depend on a table, and stops when one of them is no longer true. CI has neither
checkout and cannot run it; CONTRIBUTING says when to run it. The tables have no
column for the commit that added a row: the plan that numbered the commits is
not in the repository, and a number the script cannot derive for the next commit
would stop it.
The other documents had places that said something the repository does not carry
or does not do:
- DESIGN cited docs/kde.md, which no commit carries, said spike 8 "asked
whether" one komorebi.json could be shared, and described the default of the
key binding mode as a plan. Each entry now states the rule and the evidence.
The first entry no longer says that the Windows implementation is the
reference: both it and the macOS one were read, and the native thing is
preferred where the other two need a workaround.
- "The spikes" was used in PLATFORM, DESIGN and COMPARE and defined nowhere.
PLATFORM's vocabulary defines it, and PLATFORM has a list of what was not
measured, which COMPARE links to.
- ARCHITECTURE said a maximized window is hidden with its workspace and shown
with it, and that the code has a TODO for cycling the focus. A workspace
switch hides nothing, since KWin shows and hides the desktop's windows, and
the cycle leaves a maximized window as it is; the TODO and the commented-out
code under it in window_manager.rs are replaced by a comment that says so. The
Key bindings section no longer repeats the headings of the sections before it.
- README listed the subcommands that work without the daemon, and the list was
short. It gives the rule and one example of each kind.
- The page on changing monitors opened with "nothing to configure" and then
named display_index_preferences.
- COMPARE said KWin waits 300 ms for the pointer to settle before it moves the
focus. That is KWin's default (DelayFocusInterval, in KWin 6.8.1), and
komorebi sets it to 0 while focus follows mouse is on; the page now says so.
- ARCHITECTURE's opening list of what the page describes stopped at the borders
and had no word of animation, themes, wallpapers, transparency, focus follows
mouse or key bindings. Two link definitions that it had twice are there once.
- PLATFORM's list of what was not measured has the progress of the stock
animation effect against the clock: one capture showed none four seconds into
a 30 s animation, where the curve gives about 60 %.
- README, docs/index.md and ARCHITECTURE link COMPARE.md.
- COMPARE's list of the methods of Backend has drag_end, which the end of a
resize is read through, and compare-gen.py has the row and the counts.
KWin maximizes a window for the user as well as for komorebi: the title bar, a
double click and a shortcut do it, and nobody asks the window manager. A window
that stayed a tile would be asked to move at the next retile, so komorebi has to
know.
The bridge reports KWin's maximizedChanged as a maximized event, true only when
the window is maximized both ways. The table turns it into a MaximizeChange, and
adopt_maximize_change takes the window out of the layout as toggle-maximize
does, or, when the user restores it, puts it back in a container of its own at
the index it came from. A window that is already maximized when komorebi starts,
or that opens maximized, is the workspace's maximized window from the start.
komorebi's own maximize is reported too and finds the workspace as it left it,
so it changes nothing.
While a window is maximized, what is asked of the layout does nothing, by the
same rule as for toggle-maximize.
A maximized window of a monitor that is unplugged goes to the monitor that is
left and stays maximized: evacuate_monitor makes it the maximized window of the
workspace it goes to, and the maximized window that workspace had goes back to
its tile. Until now it came back as a tile.
vm-user-maximize maximizes windows with kdotool in a headless KWin, and checks
the daemon's state, the frames, that the layout commands do nothing, and that
toggle-maximize and the user's restore both put the window back in its tile.
A window can be moved to another output by something other than komorebi: a KWin
shortcut that sends it to the next screen, the window menu, an application.
komorebi had it in a container of the old monitor, whose tile is on a screen the
window is not on, so it sat untiled where it landed.
The bridge now reports a window's output changing, with the frame the window has
by then, since the signal and the frame arrive in no fixed order, and the table
makes it an OutputChange event. The window manager handles it with
WindowManager::follow_windows_to_their_monitors: every container whose focused
window, and every floating window, is on another monitor than the one it has it
on moves whole to the workspace of the same number on the monitor that holds the
middle of its frame, and the monitors that changed are tiled. Every window is
looked at, not only the one in the event, and a move komorebi made itself is in
its state already and finds nothing to do.
Nothing is followed while the user drags a window: the end of the drag decides
where that window goes, so the method returns at once while a move or a resize
by the user is going on.
KWin also moves windows for a moment after outputs come and go, so the monitor
reconciliator looks again 1.5 seconds after each notification, where it used to
trust what it found at once. vm-hotplug sends windows over with kdotool as well
as with komorebic.
KWin takes the windows of an output that goes to the outputs that are left and
puts them where it likes, so komorebi's tiles for them were on a screen that was
gone and the windows sat untiled where they landed. The monitor reconciliator
now deals with a change in the set of monitors: the table announces it as a
display connection change instead of a resize, and reconcile_display_change
reads the monitors again, keeps each one that went (workspaces, layouts,
paddings, offsets) in a cache, has the window manager move what was on it to the
monitors that are left, and removes it.
The move is WindowManager::evacuate_monitor, in the new reconcile module: each
container and floating window goes to the workspace of the same number on the
monitor that holds the middle of its window, or on the first monitor that is
left when it is on none, and the workspaces that changed are tiled. A stack goes
as one container, and a monocle and a maximized window come as ordinary
containers. A monitor that is plugged in takes what was cached under its serial
number id, less the windows that closed or that the window manager has elsewhere
by now, so it comes back with its settings and none of the windows it had. A
monitor komorebi never saw gets workspaces of its own, and when the compositor
reports no output at all nothing is done.
The workspace rules of a monitor that goes are dropped, and those of the
workspaces of one that comes back apply again. komorebi.json fills the cache as
well: a monitor that has the entry its display index preference names is kept
with it, and so is the entry of each preference whose monitor is not connected,
which that monitor takes when it is plugged in.
vm-hotplug now sends two windows to the other monitor with komorebic, disables
that output, enables it again and sends a window over once more.
When an output gets another resolution or scale, or a panel starts, grows or
hides, the work area the layout fills is not the one komorebi tiled in, and
nothing moved the windows until something else tiled them again.
The bridge now sends the outputs, with their geometry and the work area of the
desktop each shows, when KWin says they changed, when a dock window opens,
closes or moves, and once a second, because KWin has no signal for the room a
panel leaves. The table turns a monitor whose size or work area changed into a
monitor notification. It is not a window event, since it is about no window: it
goes to the monitor reconciliator, a thread that takes the window manager's lock
as the threads of events and messages do, reads the size and work area of every
monitor again and tiles the workspace in front of the focused monitor. Another
monitor's windows keep their tiles until a retile. Every subscriber is notified
of it, whether or not the state changed.
vm-hotplug starts with the scale of one of two outputs changing under a running
daemon. The VM library gets kde.outputs, which lists, disables, enables and
scales outputs, for the commits that unplug and plug them.