The scenario table has the four new scenarios, which pass on both
ports, and maximizing, which kfw has not run. The state's padding and
the frames' disagree on both ports, by 10 px on kfde and 7 on kfw.
The scenario's failure was its own: it waited for a focus that already
held. Five consecutive runs of 14 scenarios on Windows passed, hotplug
and focus_follows_mouse apart.
The last check of focus_follows_mouse fails on a Windows guest after
the setting was turned off with the pointer on a window and on again;
disable then enable works. The cause is not known, and the scenario is
unchanged.
Reported by the kfw session from a probe: the reconciliator sees the
removal and loops on it, and state lists two monitors for as long as it
is watched. It passes in some runs, so it is not a known failure; the
check stays red when it fails.
Run once on a real KWin with every tile 200 pixels too wide, and not
committed: seven checks failed, all about tiles on each other, and the
other 139 passed.
A port that cannot start with a case's rules, or orders its windows
otherwise, is recorded as a known failure for that case, and the other
cases run on. kfw does not accept the place as a JSON number, so
BEHAVIOUR.md lists the case as a known failure there.
A window kfw had cloaked is uncloaked by the stop and managed again on
the first workspace. A minimized window is left minimized and is not
managed. The lifecycle scenario counts only the windows in view.
The pointer on kfw reaches the first display only, because QMP's
absolute tablet is mapped there. The commands sweep passed in the two
runs that had the host to themselves and failed in the two that ran
beside a VM suite and a build.
kfw's 0ffc502c fixes the resize shortfall: a 60 pixel drag widens the
left tile by exactly 60. The commands sweep passes with a second
display, and rules, hotplug and lifecycle pass on a Windows guest.
The earlier sweep failures came with a kfde suite running beside it.
Checks.known_failure records a check that fails for a reason that is
to be followed up on: the suite does not fail, the totals say how many
known failures there are, and one that holds fails the suite so the
marker goes. unknown_monitor takes the reason, and core-e2e runs it
last, because the window it loses stays lost. BEHAVIOUR.md says so.
The scenario sends the focused window to monitor 7 with send-to-monitor and
move-to-monitor, which no display has, and checks that the daemon still
manages every window. A port may refuse or ignore the command, but a window
that was managed has to stay so: one that is not is left on the screen with
nothing tiling it.
It found a bug in both ports. kfw managed one window fewer than the OS had
afterwards (seen by hand on a Windows guest), and kfde failed it in
core-e2e on a real KWin: move_container_to_monitor takes the focused
container out of its workspace before it looks the monitor up, so the
error for a monitor that is not there comes after the container is gone.
It is not fixed, so the scenario is not in core-e2e, which would fail;
BEHAVIOUR.md has the finding. Its unit tests run it against a fake that
loses the window and one that ignores the command.
A table of the scenarios against the two ports, with where each result
comes from, the resize finding and its cause (kfw reads the rectangle a
drag started from when it handles the start event, about 100 ms after the
drag began, so the distance it measures is short by what the window moved
in that time, and more so for a longer drag), what the scenarios had to
allow for, and what is not covered.
Seven of the eight shared scenarios pass on a Windows 11 guest under QEMU
against kfw's daemon, as the session that ran them reports. The eighth,
resize, ran there and found that the edge moves less than the pointer; an
unmanaged window followed the same drag exactly, so the shortfall is in
what kfw does with the drag.
monocle toggles monocle on the focused window and checks that it fills the
work area up to the layout's padding, that the state has it as the monocle
container, that every other window is put away, that it keeps the focus,
and that toggling back puts every window in view on the tile it had.
closing closes a window and checks that the OS has no frame for it, that
the daemon manages one window fewer, and that the windows left in view
take more room between them, inside the work area and clear of each other.
Platform.close closes a window as its button would; KdePlatform does it
with kdotool. The fake daemon models monocle and closing, and its
os_window now knows the workspace a window is on, which the workspaces
scenario had passed without. core-e2e runs both: 120 checks pass on KVM.
Platform.has says whether a platform can do what a scenario needs, and
Platform.pointer is a Pointer (move, down, up, drag) where it has one;
KdePlatform takes the pointer of a session node. scenarios.resize drags the
edge two tiles share by 60 pixels and checks that the tiles that end at the
edge are that much wider, the ones that start after it start that much
later and end where they did, nothing moves up or down, and tiles that do
not touch the edge are where they were. A platform with no pointer skips
it, and says so.
The fake daemon has a pointer that moves an edge. The scenario runs on KDE
at the end of drag-resize: 19 checks pass on KVM. Its first run failed one
check that was the scenario's: both tiles of a BSP column share the dragged
edge, and the check took the second for one that had not moved.
core-e2e writes the komorebic state of kfde, with three tiled windows and
with one stacked onto another, into its output, and the files are kept in
tests/fixtures beside kfw's three, recorded from a Windows guest (tiled,
stacked, one window floated). test_recorded.py reads all five with the
same checks: three containers of one window, a layout rectangle for each
inside the work area, each window where its container's rectangle is up to
a terminal cell (foot rounds to cells, kfw's test window does not), and a
stack that is a container of two whose focused window is the one the ring
names. Nothing in the parser had to change; the checks passed on the first
real kfw state.
The scenes written from the serializers stay for the shapes no run has
recorded. The sync script copies the fixtures too. The workspaces scenario
prints which windows are in view after the switch: one run of core-e2e
failed that check and passed on the next, and the log did not say which
window had been in view.
tiling has run against kfw's daemon on a Windows 11 guest under QEMU, 10 of
10 checks, with this core copied unchanged; the other four scenarios have
not run there yet. Says so in vm-tests.md, and what keeps the copy in
step.
latency measured a p95 of 128.9 ms against its 100 ms times scale on the
WSL2 machine, under nested KVM with nothing else running, where x86-1 had
passed it at scale 1. Every Linux host is no faster than a Mac to the
suites that time the daemon, so scale is 1.5 on all of them: latency
passes at it with a p95 of 132.4 ms against 150 ms. The run-to-run
difference (p50 46.0 ms, then 70.0) is as large as the margin left, which
PLATFORM.md says.
PLATFORM.md records the wall times of the suites on this machine. All 33
were run there after the library was split: 32 passed at scale 1, and
latency is the one that failed. The other 32 were not rerun at 1.5, which
changes their derivations.
workspaces sends the focused window to workspace 1, checks that it is put
away and that the daemon has it there while the others stay in view,
switches to workspace 1 and checks that only that window is in view and has
the focus, and switches back.
hidden now says a window is out of sight for any reason the daemon has: on
KDE that is the parking desktop and also a desktop that is not the one in
view. Snapshot's workspace, containers and focused_title take the focused
workspace when none is given, and the fake daemon has two workspaces. The
scenario passes in core-e2e on KVM: 106 checks.
hidden says that a window exists but the daemon has put it away: the others
of a stack, here, and later those of another workspace or behind a monocle.
It is a window on the parking desktop on KDE and will be a cloaked one on
Windows. scenarios.stacks stacks the focused window onto its neighbor,
cycles the stack, checks that the window in view has the focus and fills
the tile the first had, and takes the stack apart.
The scenario's fake daemon now models stacks. Running it on KDE found a bug
in Snapshot: focused_title took the first window of the focused container,
and a stack's focused window is the one its ring names. Snapshot keeps that
index now. core-e2e runs the scenario after the others: 98 checks pass on
KVM.
focus moves the focus with focus and cycle-focus and checks that the OS and
the daemon's state agree on the window that has it and that no window moved.
moving swaps the focused window with its neighbor with move and puts every
window back with cycle-move, and checks that the focus stays with it. Both
read the windows through the Platform, so they are what kfw's suite will
run.
Their unit tests run against a fake daemon that follows the commands over
three tiles, and against two that do not (a move that moves nothing, a move
that loses the focus). core-e2e runs them after tiling on KDE: 85 checks
pass on KVM.
KdePlatform is a Kde session seen through the neutral vocabulary: kdotool
for the OS's frames, foot for clients, the cell of its font as the
tolerance. The core-e2e suite runs scenarios.tiling through it as a new
section, so that the scenario that will run on Windows is checked on the
one platform that works; the suite's own sections are unchanged. It passes
on KVM (74 checks) on the WSL2 machine.
komorebic state prints a different JSON on kfde and on kfw: a window is
{id, rect, details} on one and {hwnd, title, exe, class, rect} on the
other, and a monitor and the state itself have fields the other lacks.
core.snapshot.parse reads either into monitors, workspaces, containers and
windows with the same names, keeping what only one has in Snapshot.extra,
so that a scenario does not have to care which port it runs on.
The fixtures in its tests are written from the two serializers, not
recorded; they are replaced by recorded states once a run on each port
exists.
Checks, Rect and the pixel helpers depend on no compositor. They move to
komorebi_vm.core, which may not import komorebi_vm.kde, so that the package
can go to the Windows port unchanged. komorebi_vm re-exports them and no
suite changes. This is the first step of the cross-platform e2e plan.
The guide for the one command: docs/trying-it.md says what a machine needs to
run the demo guest, with the lines of .wslconfig and of the NixOS-WSL
configuration for Windows 11, how to check it with `run-kde --doctor`, what the
command does and shows, the key bindings to try, how the GPU path is chosen, how
to open Windows' own RDP client, how long the first run takes (measured on a
machine with 32 cores and an empty store, by number of cores, with an estimate
for a WSL 2 machine and its caveats), how to start again, how to work on
komorebi in the guest, and what to do when something is wrong, by symptom. It
ends with what was run and what was not: nothing has been run on WSL 2 yet. The
README has a section and a link, and the user guide index a line.
DESIGN.md has four entries. Two record what I decided and want: the QEMU window
first and RDP second, and the GPU wherever the host has one. Two say that a
reason was not written down, for QEMU with KVM and not Hyper-V and for sharing
the password by a directory, and what is known that bears on each; the password
entry also says why a password is made for each user. PLATFORM.md has a section
for WSL 2 with what the command expects, a table of the probe results still to
be recorded (KVM, display, GPU, RDP, resources, virtiofs), and what is known of
virtiofsd without WSL 2.
The demo guest is what the command `run-kde` starts, so it should not stop
working between the times somebody runs it by hand. The suite `run-kde` puts the
guest module, nix/dev/run-kde.nix, on the session node, as the rdp suite does
with krdp.nix, and checks what only a booted session can say: the demo opens two
Konsole windows, Kate and Dolphin and komorebi tiles them clear of the panel,
the cheat sheet is a window that is not a tile, what it shows of `komorebic
check` has no error, and KWin says what it draws with.
The node makes the directory the host shares as the guest finds it once it has
mounted it: owned by a user the guest does not have, with a password and a
public key in it. The suite checks that the guest takes them as root before the
login, that ssh lets in that key and no other, that KRDP starts by itself and
listens, and that a client with the password is let in and shows the display.
The client of those RDP checks moves from the rdp suite into the library as
RdpClient, with unit tests against the fake machine, so that both suites run the
same checks; the machine protocol gains copy_from_machine for it.