Commit Graph
105 Commits
Author SHA1 Message Date
LGUG2Z c9ca340d4e feat(e2e): mark the initial workspace rule of the macOS daemon, and mark per scenario
An initial workspace rule applied to a window leaves it on the first workspace as well as putting it
on the one the rule names: after it, the state has the window in the containers of both, and it is
in view at its tile (the daemon's log says it hid and restored it). It is the same on every run, in
the scenario and on its own, so the two checks about it are marked as a known failure of the macOS
daemon.

The marks are of one scenario each now: the check that says a window is put away while another workspace
is in view is a check that passes in rules_exe, and a mark on its words would have said so.
2026-11-06 14:40:50 -08:00
LGUG2Z 8dc6390eb1 fix(e2e): wait for the macOS daemon to take up a command, and for its file watcher
komorebic is done when a command is in the daemon's queue, not when it has run, and a scenario opens a
window right after giving a rule or a name: both are events of the same queue, and the window could be
first. The platform asks for `state` after every command that changes something, which the daemon
answers in the order it got things (the rules scenario failed a different check on each run before,
and its named-workspace checks pass three runs in three now).

The daemon watches its configuration file with FSEvents, and a file written in the first half second
after it answered is never noticed (0 s: not reloaded in 12 s; 0.5 s: reloaded after 2.6 s; later
ones after two or three seconds). A start waits a second for it, as nobody edits a file that fast.
config_reload goes from 6 of 8 checks to 8 of 8.
2026-11-06 14:40:50 -08:00
LGUG2Z 5257e11b8d feat(e2e): what the macOS daemon does differently, marked, and what it does not have, skipped
The first run of the scenarios against a real guest ended with 32 failing checks of 586. A window the
daemon puts away is parked with a sliver showing (fixed in the platform), and the rest are differences of
the macOS daemon, marked on the checks that are about them, with the reason:

- stacks: it stacks by raising the focused window over the others, and never puts the others away
- fullscreen: it has no fullscreen detection, and tiles a window over the whole display
- layout_flip: it tiles 10 px below the top of the work area and 12 px above its bottom
- class: a window has none, the daemon matches the role, which every test window shares

placement is skipped as a whole: the macOS daemon has no initial_window_placement_rules.
2026-11-06 14:40:50 -08:00
LGUG2Z 25f50076af feat(e2e): mark one check of a scenario as a known failure of a port
A step could be marked as a known failure of a port, which hides every failing check of it: too
coarse for a scenario in which one or two checks are about a difference of the port and the others
are not. RecordedChecks takes marks now: a part of the description of a check, and the reason. A
marked check that fails is recorded as a known failure, as a step is, and one that passes is a failure
of its own, so that a mark does not outlive the difference it was for. A port that gives no marks
is as it was.

The run of the runner's own subprocess calls says it does not check them.
2026-11-06 14:40:50 -08:00
LGUG2Z 098b7d011e fix(e2e): a window the daemon parked with a sliver showing is put away
macOS does not let a window go entirely off the screen, so the daemon hides one at the corner of
its display with one pixel of it showing (five for a window that scrolled away). The port
called a window hidden only when no pixel of it was on a display, so it said every window the
daemon had put away was in view. A window is put away now when no more than a sliver of it shows,
in either direction.

Against a real guest this takes workspaces, workspace_moves, monocle, lifecycle_hidden, rules_exe
and startup_rules from failing to passing (18, 18, 22, 23, 5 and 5 checks).
2026-11-06 14:40:50 -08:00
LGUG2Z 18d7f9a506 docs(e2e): how the macOS guest works and how to run it
A README for e2e/platforms/tart_macos: what a run does, why the grants live in the golden image and
are inherited through Terminal, why the agent is a Rust program (the stock image has no developer
tools), and the limits (one display, no input, two guests per host, Apple hardware only, so not in
CI). docs/dev/ci.md and e2e-to-unit.md said macOS had no integration coverage; they now say where it
runs and what it cannot reach.
2026-11-06 14:40:50 -08:00
LGUG2Z fa2742a75d feat(e2e): scripts that build the golden image of the macOS guest and its programs
build-golden.sh makes the golden Tart image from a vanilla one of Cirrus Labs: it provisions the
guest over SSH (provision.sh: the agent starts at login from a Terminal window, no state of earlier
runs is left, Terminal does not reopen old windows), stops for the one step that cannot be
scripted (a person allows Screen Recording and Accessibility for Terminal, once, and the grants live
in every clone), checks that the agent answers, and shuts the guest down from inside, so that
the last writes are on the disk the clones copy. build-bins.sh builds the programs under test for
the host and points the libiconv of the nix store at the system's, as the nix package does.
2026-11-06 14:40:50 -08:00
LGUG2Z 6823d13ddd feat(e2e): a runner for the macOS guest
python -m platforms.tart_macos.run GOLDEN BIN_DIR OUT SCENARIO... gives each scenario a fresh
clone of the golden image, uploads the programs under test, starts the daemon and runs the shared
scenario, on the checks, step loop and result file the Windows runner uses (komorebi_vm.runner).
The scenarios a guest cannot run (a second display, a pointer, a lock screen, a window class) are
listed with the reason and skipped, not failed.

The unit tests of the port need no guest: the ignore rules, which windows count as hidden, the
paths a scenario may ask for, and that every scenario the runner names is a module of the core.

tiling (10 checks) and focus (17) pass against a real guest.
2026-11-06 14:40:50 -08:00
LGUG2Z 9b236b14be feat(e2e): a macOS guest and platform for the shared scenarios
A clone of a golden Tart image is booted without a window and its agent (komorebi-e2e-agent, started
at login from the Terminal that holds the Accessibility and Screen Recording grants) is the only
thing the host talks to: no SSH, no password. MacosPlatform implements the Platform protocol
through it: the windows and displays are what the accessibility API says, the daemon is a program
the agent starts, a window the daemon put away is one off every display, and a screenshot is
screencapture.

A guest has one display and nothing here injects input, so has() says no to a pointer and to the
lock screen, and a second display is refused. The windows of the guest's own programs (the
Terminal, the desktop widgets of the image) are left to themselves by an ignore rule the platform
adds to every configuration.
2026-11-06 14:40:50 -08:00
LGUG2Z 80f221b8e7 refactor(e2e): one host client for the agent of every platform
The host side of the agent spoke a protocol that is the same for every platform, and lived in the
Windows port. Move it to komorebi_vm/agent.py, which the Windows module re-exports so that its
imports stay as they are, and give it the calls the protocol gained: spawn with an environment and
an output file, `status` of a spawned program and `send` to its standard input.
2026-11-06 14:40:49 -08:00
LGUG2Z ceaea8ca1b refactor(e2e): lift what a runner needs of a port out of the Windows runner
RecordedChecks (the checks a runner keeps for its result file), the step loop with its timings
and known failures, the commit under test and the step keyword helper have nothing to do with
Windows. Move them to komorebi_vm/runner.py, with the known-failure tables passed in, so that a
runner of another port uses them instead of importing a sibling port or copying them.

The Windows runner keeps its tables and the names it and its tests use. The unit tests of the core
and of the Windows runner pass unchanged (163), and ruff reports what it did before.
2026-11-06 14:40:49 -08:00
LGUG2Z c234b1d884 build(tools): route the justfile and tools to crates/ 2026-11-05 15:03:27 -08:00
LGUG2Z 6def6bdfbf refactor(layout): move library and dev-tool crates under crates/, rename komorebi-daemon to komorebi
Pure renames, no content changes. This revision does not build on its own;
the next one routes the workspace to the new paths.
2026-11-05 15:03:27 -08:00
LGUG2Z 3e21ebd3a4 feat(e2e): windows-nextest runs the Windows unit tests in the guest
The Windows crates' unit tests could only run in the (future) hosted Windows
CI. They run in the existing Windows e2e guest: nix run .#windows-nextest
boots the golden image like a scenario (restoring a saved state when
KOMOREBI_E2E_STATE is set), uploads the test executables that the check
windows-nextest-build cross-compiled, runs every test in a process of its own
(nextest.exe is not needed: komorebi's tests share global state, so one
process per test is what nextest does too) and prints a line per executable
and the failures, with OUT/cargo-tests.json for every result.

The driver e2e/platforms/qemu_windows/cargo_tests.py already existed and was
wired to nothing; it now takes the check output (tests.tsv) as well as cargo
messages, creates the saved state itself, prints the panic message of a
failure, and uploads the data files the tests read. Those are found by the
CARGO_MANIFEST_DIR baked into the executables, a path of the Nix build, so
the check also keeps schemas/ and the tests' fixtures and the driver puts them
at that path under C:. Without them 20 tests failed for the missing files.

docs/dev/build-and-test.md and docs/dev/flake-checks.md describe the check,
the app and the neutral crates in linux-nextest.

Verified: nix run .#windows-nextest on the golden image g8 (scale 1.5, state
~/e2e-w0/state-nextest): 964 tests in 37 executables, 964 passed, 0 failed,
202 s with the state restored (first run 163 s more to save the state).
One run only; not soaked. No e2e scenario, the golden image or the existing
e2e-windows behaviour changed.
2026-11-05 15:03:27 -08:00
LGUG2Z 22d2e1ae78 docs: fix the nix attribute names and paths the one flake renamed
Only the commands and paths that named an attribute or file of the old flakes: the kde source
filter list (nix/linux/root-crates.json), the Windows drift check (windows-default), the KWin
effect install checks (linux-*-install), the module evaluation check on a Mac and the VM suites
(legacyPackages.<system>.vm.NAME, which are also the heavyChecks for now), and the Windows e2e
agent package (windows-komorebi-e2e-agent). docs/dev/flake.md has the full table. The history
in docs/dev/unified-binaries.md keeps the names of the time it describes. On the rebase onto
wip-cutover-all the coordinator edits of ARCHITECTURE-UNIFIED.md were kept and these two lines
applied on top.

Verified: not run (documentation).
2026-11-05 15:03:27 -08:00
LGUG2Z f7f444efb6 build(tools): tools, justfile and scripts name the outputs of the one flake
fast-check classifies the paths of the final directories (komorebi-linux, komorebi-macos,
komorebi-hotkeys, nix/{windows,linux,macos}, docs and schemas per platform), runs the Linux
check from the repository root and evaluates one check and one package per platform in the
root flake; kde-closure-check reads nix/linux/root-crates.json and compares it with the cargo
tree of the Linux packages (the listed crates besides komorebi-linux, komorebi-hotkeys and
komorebi-daemon); mac-check.sh drops the nested-workspace branch; e2e-needed treats nix/windows,
nix/workspace-src.nix, nix/lib.nix and nix/common.nix as fixed inputs of the Windows binaries
and the Linux and macOS trees as outside them; build-ref.sh builds `windows-NAME` for a REF with
the one-flake layout and keeps the old names for an older REF with its own flake. The justfile
names linux-nix-options-validation and runs a VM suite as legacyPackages.<system>.vm.NAME
(the vm-* checks are heavyChecks for now). scripts/linux/{run-kde,vm-mac,sync-e2e-core,
scenario-status} find the repository root and the VM library from scripts/linux/ and nix/linux/
(on the rebase onto wip-cutover-all the coordinator versions of run-kde, vm-mac and
scenario-status were kept: same change).

Not touched: scripts/linux/compare-gen.py, a migration comparison between the three old trees
that still looks for komorebi-for-mac/ (obsolete; open).

Verified: bash -n on the changed scripts; tools/kde-closure-check passes (14 root crates);
tools/fast-check --list classifies this revision as nix-only. fast-check commands for the
platforms were not run.
2026-11-05 15:03:27 -08:00
LGUG2Z 87fb8340d0 chore(repo): one workspace version, 0.2.0
Every package of the workspace now takes its version from [workspace.package]
(version.workspace = true) instead of its own number. The numbers before were
0.1.42 (Windows libraries and packages), 0.1.0 (KDE, the macOS version crate,
komorebi-shortcuts and the e2e guest crates) and 0.1.1 (macOS libraries); the
unified release is 0.2.0 for all of them.

Cargo.lock only changes the version of the workspace's own packages.

Not changed here: the version text in schema doc comments and the generated
schemas (next revision), and the shim packages, which are deleted later and
only pick up the number meanwhile.

Verified: cargo metadata --offline --locked succeeds.
2026-11-05 15:03:27 -08:00
LGUG2Z e1fc1499d4 test(e2e): the bar scenario lists processes with plain tasklist
The bar scenario counted komorebi-bar.exe processes through 'tasklist /fi "imagename eq komorebi-bar.exe" /fo csv /nh' run via the guest agent, which exits with status 1 there (quoting of the filter), so the process checks failed even though the bar was running and drawing (wgpu). 'tasklist /fo csv /nh' lists the process and the existing filter on lines starting with komorebi-bar.exe keeps the result the same. Found by the candidate 8 Windows gate (gate-cand8.md, bar-fix8.diff: with it the scenario ran 23/0). The file is also reflowed by ruff format (the CONFIG dict), which is formatting only. Verified: ruff format and ruff check on the file; the e2e run in the gate with the one-line change.
2026-11-05 15:03:27 -08:00
LGUG2Z e70a0e4921 style(windows): format with the project's rustfmt settings (tools/format-all --apply --tree windows)
Pure formatting by the same nightly rustfmt invocation the nix fmt check uses (tools/format-all, edition 2024, the tree's rustfmt.toml). No code change. Applied last on the candidate because it touches many files other agents were editing. Verified: tools/format-all --check --tree windows passes afterwards; light gates (fast-check) after all three.
2026-11-05 15:03:27 -08:00
LGUG2Z 0a315a61bc test(e2e): the bar scenario's window checks are real again when wgpu draws the bar
The bar now falls back to wgpu (Direct3D 12, WARP) when glow has no OpenGL
context, so in the OpenGL-less golden guest the bar can open a window and the
window, stays-alive, daemon-restart and notify checks run for real. They are
skipped only when BOTH renderers fail, and the skip names both errors
(`skip ...: guest cannot draw: glow: ...; wgpu: ...`, taken from the bar's
"Error: glow: ...; wgpu: ..." line); any other early exit still fails. The
scenario starts the bar with RUST_LOG=info,wgpu_hal=debug,wgpu_core=warn so
bar.out keeps what wgpu says about its adapters on the first run, and prints
which renderer drew the window ("the bar draws with wgpu").

Unit tests: both renderers failing (classify + the error line), a bar that fell
back and runs (the glow warning is not an "Error:"), plus the earlier ones.

Verified: runner and library tests 163 passed; ruff clean on the scenario and
its test. NOT run: needs the win-e2e `bar` gate.
2026-11-05 15:03:26 -08:00
LGUG2Z fa2d630701 test(e2e): the bar scenario says when the guest cannot draw, and the bar config is tested
The Windows gate showed that the bar cannot open a window in the golden
guest (no OpenGL 2.0: "egui_glow requires opengl 2.0+"). The scenario now
reads the bar's own output (`classify`): that exact failure turns the
window, stays-alive and daemon-restart checks into visible
`skipped: guest has no OpenGL 2.0` lines (counted in `result.json` and
printed as `skipped: N` by the runner); the schema equality, "the bar reads
its configuration" (real: the configuration is parsed before the window),
`komorebic state` and `stop --bar` stay checks; any other early exit of
the bar (a configuration error, a panic) is a failure with the bar's
output in the message, and a bar that opens its window gets the full walk as
before. Unit tests for `classify` run with the runner tests.

komorebi-bar-core gets tests/config.rs: windows-only widgets and the `mouse`
block are accepted on every platform, `supported()/unsupported()/enabled()`
name and skip what the platform cannot run (D-coord-1), a Command mouse
message is a plain string and the tagged form is rejected (the e2e finding),
the network widget accepts `default_interface_options` and the old key
names, layouts read from their names, `KomobarConfig::read` fills the frame
and refuses a non-json file. The warning text itself is not asserted (no
tracing subscriber in the core).

docs/dev/bar-e2e.md records the limitation and an analysis of getting
rendering into the guest (wgpu with the WARP adapter recommended; a mingw
Mesa is not offered by nixpkgs); nothing was added.

Verified: runner and library tests (161 passed), ruff clean on the scenario
(three older findings in other files are not mine), bar-core native tests 3
unit + 7 oracle + 6 config. Windows clippy and the macOS check: see the
report. The scenario itself was not run.
2026-11-05 15:03:26 -08:00
LGUG2Z fdd9f0891d test(e2e): the bar scenario's mouse command is a plain string
`MouseMessage::Command(String)` is an untagged variant, so
`"on_middle_click": {"Command": ...}` in the scenario's bar configuration
did not deserialize and the bar exited at start ("data did not match any
variant of untagged enum MouseMessage"). The value is the string itself.

Found by the Windows gate on candidate 5 (win-e2e, S/e2e-win/gate-cand5.md,
bar section; the fix is its bar-fix.diff). Verified: ruff clean; not run.
2026-11-05 15:03:26 -08:00
LGUG2Z 4e2c50e526 chore(repo): combine candidate 3b with the KDE handover scenario fix (candidate 3c)
Gate candidate 3c: wip-cand3b (cand3 + the bar e2e scenario) plus wip-u-kdefix (handover precondition in both copies of the shared e2e lib, KDE vm-commands bring_back step). The shared e2e/lib handover scenario is also what the Windows runner runs, so the Windows gate must include it.
2026-11-05 15:03:26 -08:00
LGUG2Z 61d6423fdd test(e2e): handover needs two tiled containers on the workspace, or says so
Scenario precondition fix; the check "the unmanaged window is inside the work area and not on a
tile of the layout" itself stays as strict as it was.

The KDE VM suite vm-commands failed it on a calm host, on the original komorebi-for-kde tip
(7d19fd40) and on the refactored stage alike, with the same numbers each time: work area
(0,0,1920,1080), layout a single tile (10,10,1900,1060), win3 at (10,10,1896,1050) (within the
24 px tolerance of that tile), win1/win2/win5 parked on workspace 3. After the sweep win3 was the
only window on its workspace. Unmanaging a lone window leaves it on the tile it was put on, and
an emptied workspace has nothing to calculate, so it keeps its last layout; "not on a tile" could
never hold. The scenario now checks first that the focused workspace has at least two tiled
containers and, if not, fails with a message that says so (and the describe() dump) instead of
the misleading unmanage failure. Windows runs handover as its own suite with its three tiled
clients on workspace 0, so the precondition holds there.

The same file lives in e2e/lib and in komorebi-for-kde/nix/tests/vm/lib; both are edited alike. A
fake-platform test covers the precondition; the existing handover cases still fail where they
should.

Native pytest of the VM lib: 320 passed; ruff check and format clean.
VM verification: not yet (vm-commands on baseline-with-fix and candidate, ~20 min each, after the
KDE VM run).
2026-11-05 15:03:24 -08:00
LGUG2Z f0a0d71b83 test(e2e): a Windows scenario bar for komorebi-bar
New extras scenario e2e/platforms/qemu_windows/extras/bar.py, registered in
run.py as `bar` (runs after the tiling windows, like the other Windows
extras). It starts komorebi-bar in the guest with a configuration that has
storage, time, applications, komorebi workspaces and layout widgets, the
Windows-only Keyboard and Systray widgets and a `mouse` block (a message and
a command), and checks: `komorebi-bar --schema` equals the checked-in
schema.bar.json byte for byte; the process starts and its window titled
komorebi-bar appears, visible and sized; it runs 15 s (scaled); `komorebic
state` answers and komorebi does not tile the bar; commands that notify the
bar work; the bar survives `komorebic stop` and the daemon starting again as
the same process (it reconnects: it does NOT exit when the daemon stops, so
the task text "exits cleanly when komorebi stops" is checked as
`komorebic stop --bar` ending daemon and bar); screenshots are kept as
artefacts, no pixel assertions. No known failures.

Plumbing: run.py uploads komorebi-bar.exe when the binaries directory has it
(other scenarios do not need it, so older build-ref directories still work),
the nix app copies it and sets KOMOREBI_E2E_BAR_SCHEMA to the checked-in
schema (the e2e directory alone does not contain it), build-ref.sh builds it.
README and docs/dev/bar-e2e.md document it.

Verified: py_compile and ruff clean; the runner and library unit tests: 157
passed; flake.nix parses. NOT run: the scenario itself (the Windows guest is
reserved for gates), so every check is untested against a real bar and may
need adjusting (window title, timings, the Systray widget inside the VM).
Needs gate: win-e2e `bar`.
2026-11-05 10:30:05 -08:00
LGUG2Z 1f1805f66e fix(e2e): drop the unsafe block nested inside the testwin unsafe block
e2e/guest/testwin/src/main.rs had an unsafe block inside an unsafe block, which clippy -D warnings rejects (unused_unsafe). Removes the inner one without changing behaviour. Verified: Windows clippy passes.
2026-10-31 01:37:53 -07:00
LGUG2Z ff3711dcb5 docs(e2e): document the Windows guest and what it found
README.md: building the image, running scenarios, the variables, the known
failures. W1.md: the measurements and findings behind them.
2026-10-30 18:59:32 -07:00
LGUG2Z 0aec364345 feat(e2e): no known failure of maximizing.user once kfw has the fix 2026-10-30 18:59:32 -07:00
LGUG2Z 7f6e530b35 feat(e2e): sync the neutral core from kfde 7d19fd40 2026-10-30 18:54:37 -07:00
LGUG2Z 503ccbc9c6 feat(e2e): add a probe of toggle-monocle under a user's maximize 2026-10-30 18:49:48 -07:00
LGUG2Z 8cf77519a2 fix(e2e): name toggle-monocle as what maximizing.user still fails 2026-10-30 18:45:15 -07:00
LGUG2Z a2ab755352 feat(e2e): sync the neutral core from kfde b3dc2ed9 2026-10-30 18:25:26 -07:00
LGUG2Z e5c1e2fa75 feat(e2e): run the cargo tests of the workspace in the Windows guest
The tests are cross-compiled for Windows, so they run there: cargo_tests.py
uploads each test executable, lists its tests and runs every one in a
process of its own, as nextest does. The nix check never ran them
(doCheck is false).
2026-10-30 18:22:45 -07:00
LGUG2Z 345ddf30ea feat(e2e): the known difference of maximizing.user after kfw tracks a user's maximize
On a komorebi with 3fa3d429 the step passes its tracking checks; what is
left is that toggle-float and stack left/right are not ignored while a
window is maximized. The marker says so for such a build.
2026-10-30 18:22:45 -07:00
LGUG2Z b1d053b358 perf(nix): build the test window with the constant stamp too
komorebi-testwin-e2e is the e2e build's test window, so a change to it
rebuilds the crate and not its dependencies (86 s instead of minutes);
build-ref.sh uses it.
2026-10-30 18:22:45 -07:00
LGUG2Z 0c21138e25 fix(e2e): make the test window gray, not blue
The pixel checks of the shared scenarios (the ring of a border by hue) take
the window's own color to be neutral. The default was (48, 80, 128), which
is cool by their measure, so a warm ring beside it read as mixed.
2026-10-30 18:22:45 -07:00
LGUG2Z 7e5f956415 feat(e2e): sync the neutral core from kfde 72631512 2026-10-30 18:22:45 -07:00
LGUG2Z f6d877b82d feat(e2e): sync the neutral core from kfde 1383d58a 2026-10-30 18:22:45 -07:00
LGUG2Z fe95747267 fix(e2e): a temp path may have folders in it and a space in a name
temp_path takes wallpapers/my pictures/cool.png, as the wallpaper scenario
asks for; a name that leaves the folder is still refused.
2026-10-30 18:22:45 -07:00
LGUG2Z a007996f6a feat(e2e): no known-failure marker for a build that tracks a user's maximize
maximizing.user is a known difference only on a komorebi without 3fa3d429
(track a window the user maximizes or restores); on a build that has it
the step runs as any other.
2026-10-30 18:22:45 -07:00
LGUG2Z 9818a1b885 feat(e2e): add a probe of the wallpaper of the Windows guest 2026-10-30 18:22:45 -07:00
LGUG2Z 937430b70e feat(e2e): the wallpaper members and put_file on the Windows guest
put_file writes bytes to a path in the guest (a folder that has a space in
its name is made), wallpaper and set_wallpaper read and set the wallpaper
of a display through IDesktopWallpaper, with the COM calls in C# compiled by
Add-Type (wallpaper.ps1).
2026-10-30 18:22:45 -07:00
LGUG2Z 720306deca feat(e2e): run the columns and two_monitors steps of scrolling 2026-10-30 18:22:45 -07:00
LGUG2Z ead3d91e37 fix(e2e): vendor the fake wallpaper that the focus and moving tests import 2026-10-30 18:22:45 -07:00
LGUG2Z 19e2cd6112 fix(e2e): vendor the fake strip that the focus and moving tests import
kfde's sync-e2e-core does not list tests/fake_strip.py, which
test_focus_moving.py now imports, so it is copied by hand until it does.
2026-10-30 18:22:45 -07:00
LGUG2Z 6a05754308 feat(e2e): sync the neutral core from kfde 6fb6a66e 2026-10-30 18:22:45 -07:00
LGUG2Z c51f79acb5 feat(e2e): add a probe of a resize drag from the top row of a frame 2026-10-30 18:22:45 -07:00
LGUG2Z fb549f5685 feat(e2e): say where a resize border is pressed on the Windows guest
The left, right and bottom borders of a window reach outside its visible
frame (the invisible DWM border), so the press is 4 px outside; the top has
none and its border is inside the window, so the press is in its first
rows. Outside the top the press hit the desktop and no drag started.
2026-10-30 18:22:45 -07:00
LGUG2Z 271abc3e9c feat(e2e): record two known differences of kfw as known failures
maximizing.user (a user's maximize is not the maximized window) and
hotplug.user_move (only a drag relocates a window to another monitor).
Their failing checks are known failures with the reason; a step that has
no failing check says the marker can go.
2026-10-30 18:22:45 -07:00
LGUG2Z d1d08d59d2 feat(e2e): sync the neutral core from kfde 6190a4ad 2026-10-30 18:22:44 -07:00