Candidate 9 (draft): wip-u-cmd2 (router gate_message hook + 12 more arms through komorebi_core::command; stacked on wip-u-wm2) with wip-u-mac-wm2 (shared push_simple_rule, macOS ignore-rule fix, Minimize/Close/DebugWindow methods) and wip-u-docs2 (MIGRATION-SUMMARY.md, macos-hand-check-plan.md), all on wip-cand8. Conflicts, if any, are resolved here.
Records the twelve arms moved in wip-u-cmd2 (28 with the earlier 16), the
two host traits added, and the clusters whose text is identical on all
three routers but still per daemon (rules and padding, animation, lock/save/
load, overrides and work-area offsets, queries) as the next candidates.
Docs only; the list of identical arms comes from comparing the three routers
at wip-cand8.
Records, while kfde's gate_message hook and WindowManagerPlatform trait did not exist yet:
macOS gates every message with the same call at the same place as KDE (so the default
gate_message needs no macOS override), the macOS entry points as hooks with their size and
seam note (focus_workspace keeps the pre-existing main-queue dispatch under the lock, no
hook adds one), what was done meanwhile (Minimize, Close, DebugWindow as methods;
push_simple_rule), and that update stays macOS's (D-coord-15).
Verified: documentation only.
macos-handcheck.md grew by appending sections from several authors (A-H, the
review checks H1-H12, deep-dedup rows, bar clicks, settings rows), so the owner
had to merge them by hand. The new runbook orders every item by what could
make the daemon unusable first: prerequisites, startup and the command path
(shared transport, shared SocketMessage, lock order), hiding and restoring
(shared Container/Workspace/Monitor, HideSpot), the window registry and leaks,
the pointer preamble, settings reload, the rest of the walk-through, the bar,
then the known issues that are expected to misbehave. Each item has steps, the
expected result, how to stop or roll back, the revision that introduced it, a
mark where a second display, trackpad or cables are needed, and a time
estimate per block (about 5 hours in all).
It opens with the list of commands that must not be run on a Mac that has a
live komorebi (stop, start, quickstart, autostart, pkill, state-changing
komorebic commands, SIGSTOP on pids not just started), with the reasons read
from the code: a second daemon exits when a process named komorebi exists, and
a daemon deletes the socket in the user data directory on exit. The original
document is kept as the source.
Commands were checked against the checked-in macOS docs/cli page list; nothing
was run on a Mac. Not built.
BEHAVIOUR (a pure move; type-checked and clippy-clean with the fake CC).
The three inline router arms of process_command.rs become minimize_foreground_window,
close_foreground_window and debug_window(window_id, reply), with the bodies the arms had (the
foreground element through AdhocWindow, the CoreGraphics window list walked for the id); the
arms are the same text as KDE's now. The bodies stay macOS's: there is no way to share
them without a window abstraction that hides the element, which is the registry work
of a later step. This is the part of the owner's item (4) that can be done without
changing behaviour.
Verified: fast-check macOS PASS; fake-CC cargo clippy -p komorebi-macos --all-targets -D
warnings clean; tools/format-all --check --tree mac clean. Not verified: any macOS run.
Verified on the Mini: not yet. Hand check row added.
A maintainer who was not here had no one place that says what the repository
is now, what was shared and how, what was kept per platform on purpose, how it
was verified and what was not, what is still open, and how to go on. The page
gives: the four unified packages and how cfg(target_os) selects the platform;
the three trees; the shared crates (protocol, config with the one rule matcher,
collections, transport, backend, core with Container/Workspace/Monitor/
update_shared/command, settings, bar-core, komorebic-core) and the way each was
moved; what stays per platform (WindowManager, router, events, macOS update,
borders and other subsystems, bar rendering) with links into core-model.md,
seam.md, settings.md, bar-unification.md and unified-binaries.md; the oracles
and the gate results per candidate (Windows e2e, KDE VM, Mac Mini compile,
unit and nix) with the flake summary; what is not verified (macOS never ran as
a daemon, bar runtime under software rendering, the KDE slow tier, candidate 8
gates still running at the time of writing); known issues; the cutover list
(shims, version crates, flakes, workflows, docs, tools) with a CI and release
proposal that is not decided; how to continue; and a table of 26 decisions
rewritten without agent names.
Facts were taken from the progress and decisions logs, the revision list
wip-cand4..wip-cand8 and the docs in docs/dev; no host or personal paths are
included. Not built. Gate results are as recorded, not re-run.
BEHAVIOUR (a small fix, KDE's behaviour). Router arm ManageRule and the method
add_ignore_rule used an inline loop that skipped a rule when any simple rule had the same
id, whatever its kind: 'ignore-rule class foo' after 'ignore-rule exe foo' was dropped.
They now call komorebi_config::matching::push_simple_rule (kind and id), as KDE does
(its test pins it), and the ManageRule arm is the KDE text.
Verified: fast-check macOS PASS; fake-CC cargo clippy -p komorebi-macos --all-targets
-D warnings clean; tools/format-all --check --tree mac clean. Not verified: any macOS
run. Verified on the Mini: not yet. Hand check row added.
Repeats the function comparison of sections 17/18/20 on the three
window_manager.rs files at wip-cand8: identical on all three is 43
functions and 696 lines (15.6% of Windows, 18.5% of KDE, 15.3% of macOS),
at most four lines apart 81 functions (46% of KDE at best), identical on
KDE and macOS 102 functions (64% of KDE). The all-three threshold of 60%
is not met even with every near-identical function converged. Records the
struct analysis (event type, platform field types, daemon-only methods)
and why the struct move is not taken unattended, and the KDE+macOS subset
as the owner's option. Docs only. Verified: counts from the fnsplit and
cmp3 scripts at the cand8 tree; claims about field types read from the
three WindowManager struct definitions.
Candidate 8 (second draft): cbc40c03 (cand7 + pointer-picks-monitor + thin-events note + bar wgpu fallback + macOS deep dedup) plus wip-u-win-deep (PlatformMonitorId alias, promote_focus_container_idx hook, the WindowManager hook list) and wip-u-fmt (tools/format-all, nix fmt over the nightly rustfmt, deny clarify entries for Windows and KDE). Conflicts, if any, are resolved here.
Candidate 8 (draft): wip-cand7 plus wip-u-deep (which contains wip-u-ptr: shared focus_workspace_number(s), KDE and macOS get the pointer-picks-monitor preamble, the const removed, and the thin-events design note), wip-u-bar4 (eframe wgpu fallback for the Windows bar, scenario rules) and wip-u-mac-deep (ContainerExt removed, nine shared window_manager functions identical on KDE and macOS, five macOS router arms as named methods). Conflicts, if any, are resolved here.
Section 22 of docs/dev/core-model.md, the hook list for kfde: why the
unmanaged-window gate was NOT moved from 18 Windows functions to the router (the
router form refuses every message, an arm that works before its gated call, the
layer split of FocusWindow/MoveWindow/CycleFocusWindow, and callers that bypass
the router), with the defaulted gate_message hook that expresses both shapes; the
WindowManagerPlatform hooks (new, init, stop, restore_all_windows, resize_window,
focus_workspace plan/execute, enforce_workspace_rules, the cross-monitor DPI
check, the floating-window functions); a BorderPlatform hook for the border calls
and the monocle floating hide/restore; wallpaper, window handling behaviour,
workspace names and custom layouts; the result of the cosmetic re-read (nothing
left); and an order for the implementation with the Windows gates.
Docs only.
Design only, nothing implemented (D-coord-13 (c)). Lists the three
event vocabularies read from the window_manager_event.rs files (only
Destroy, Show and Minimize share a name on all three), proposes a small
CoreEvent<W> produced by the platform adapters, sketches the shared
handlers for Gone, Appeared and Minimized with platform hooks, orders
the prerequisites (unmanaged check converged, shared WindowManager
state, PlatformMonitorId, border hooks) and names the risks (side-effect
order per arm, macOS FocusChange without a Window). Verified: docs only;
claims about handler arms rest on section 17 and were not re-measured.
docs/dev/bar-e2e.md: why the golden guest cannot use glow, how the bar falls
back to wgpu (WARP), what the scenario now counts as real and as a skip (both
renderers failing, naming both errors), the log level kept in bar.out, the
measured cost (622 -> 664 crate versions in the Windows bar tree, one new lock
entry; build time and exe size not measured) and the risks.
Verified: not applicable (docs). The checks of the stack: see the other
revisions.
Records the container API unification (ContainerExt gone, Workspace::hide_spot), the nine
window manager functions that are now identical on KDE and macOS (76 of 92 shared
function names identical, 1521 of KDE's 2713 stripped lines: 56%), the five router arms
that became methods, the four that stay macOS's, and the exact differences between
the macOS update and update_shared (a scrolling workspace returns early and skips the
resize-dimensions fix-up and places the windows itself; the SkyLight batch is wider; the
rest folds with hooks), which is why update is not adopted without the owner's decision.
Verified: documentation only.
Candidate 7: wip-cand6 plus wip-u-rulematch (one window-rule matcher in komorebi-config), wip-u-stall2 (lock-holder guard, should_manage before the lock, reaper unlock, heartbeat), wip-u-bar3 (bar e2e scenario fix, skip when the guest cannot draw, bar config tests) and wip-u-cmd (komorebi_core::command: 16 shared router arms). Conflicts, if any, are resolved here.
All three daemons now let the pointer pick the monitor for every shared
command that has the preamble, so the const has no reason left. The
shared functions always call focus_the_monitor_under_the_pointer; the
three CommandHost impls lose the const (Windows had it true already, so
nothing changes there). The core test of the switch becomes
the_pointer_picks_the_monitor_..._on_all_platforms. known-issues item 1
is marked resolved and core-model.md section 18 text is updated.
No behaviour change in this revision beyond the previous two.
Verified: komorebi-core tests all pass (command tests 18); KDE cargo test
-p komorebi-linux 670 passed, 0 failed; fake-CC clippy for the four macOS
packages passes; cargo clippy -p komorebi-windows --all-targets -D warnings
passes. Not verified: Windows tests or e2e (cannot run on Linux).
Deep dedup D-coord-13 (3), the part that is a move. BEHAVIOUR (a pure move; type-checked
and clippy-clean with the fake CC).
The inline arms of ToggleWorkspaceLayer (88 lines), ResizeWindowAxis (59),
SessionFloatRule, IgnoreRule and ReplaceConfiguration in process_command.rs become the
methods toggle_workspace_layer, resize_window_axis, add_session_float_rule,
add_ignore_rule(identifier, &str) and replace_configuration(&Path) (KDE's is &PathBuf, which clippy::ptr_arg flags) of the same
names as KDE's, with the bodies the arms had (de-indented, ending in Ok(())); the router
arms are now the same text as KDE's. Two spellings changed because the KDE
signature has them: the ignore rule's id is a &str (compared with ==, copied with
to_string()), and replace_configuration takes the run loop from self as the arm did.
What stays macOS's own and is not moved, because the body is the platform's:
Minimize and Close (AdhocWindow on the foreground element), DebugWindow and
ManageRule (role against class; no KDE method to match yet), and the macOS
bodies of the five moved methods (the role in the session float rule, the run loop in
replace_configuration, the animation suspension in resize_window_axis): they are
the methods' own differences now, behind the same names.
Verified: fast-check macOS PASS; fake-CC cargo clippy -p komorebi-macos
--all-targets -D warnings clean. Not verified: any macOS test or run. Verified on the
Mini: not yet. Hand check row added to docs/dev/macos-handcheck.md.
Adds four tests to crates/komorebi-config/tests/rule_matching.rs next to
the KDE/macOS ones moved there: a Windows exe rule names the program with
its extension (mirrors rules_exe, where platform.exe_id adds `.exe` on
Windows) and the id without it does not match; a regex id is looked up as
written on Windows and with `.exe` removed elsewhere; the whole grid of
kinds x strategies x ids agrees between RuleQuirks::WINDOWS and UNIX for a
window with one class (mirrors rules_class); a negated class rule for a
window of another class and for one with no class. Each names the e2e
check it mirrors. docs/dev/e2e-to-unit.md points at the shared file.
Verified: cargo test -p komorebi-config --test rule_matching (16 passed);
bare cargo clippy --locked --all-targets -D warnings clean.
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.
docs/dev/core-model.md section 21: the CommandHost mechanism, the sixteen
router arms that now live in komorebi-core (workspace navigation, the
moves across workspaces and monitors, lock and unlock by index), the one
platform switch (the pointer picks the monitor on Windows), and why the
rest of the router stays (each remaining arm needs a WindowManager method
or field).
Verified: not applicable (documentation).
BEHAVIOUR (macOS): FocusWorkspaceNumber, FocusWorkspaceNumbers and
FocusLastWorkspace now focus the display under the pointer first when
its workspace is empty, then run the workspace command, as on Windows
and (since the previous revision) KDE. Done by setting
CommandHost::POINTER_PICKS_THE_MONITOR_FOR_ALL to true in the macOS
CommandHost impl. Adds hand-check row H1 to docs/dev/macos-handcheck.md.
Verified: fake-CC cargo clippy --all-targets -D warnings on
aarch64-apple-darwin for the four macOS packages passes. Not verified:
nothing ran on a Mac. Gate owed: macOS hand check H1.
Deep dedup D-coord-13 (1), the container API. BEHAVIOUR (type-checked and
clippy-clean with the fake CC; the macOS tests are the oracle).
ContainerExt is deleted. Its four methods were the shared Container's with
the monitor's corner as an argument; every call (about 28 sites in
window_manager.rs, process_event.rs, scrolling.rs, workspace.rs, monitor.rs) is now
the shared one: add_window(window, spot), load_focused_window(spot), hide(omit,
spot), restore(), with spot = workspace.hide_spot() (MacosPlatform::hide_spot:
the workspace's corner, no display, which is what the old calls passed;
hide_on's screen argument was None at every remaining caller; the whole-workspace
hide with the display is Workspace::hide, already shared). The nine window
manager functions that differed from KDE's only in these calls (add_window_to_container,
cycle_container_window_in_direction, cycle_container_window_index_in_direction,
focus_container_window, stack_all, monocle_on, monocle_off, cycle_monocle,
transfer_window) now differ from KDE's text only in the spot and in the
error policy (let _ against ?), which the next revisions remove.
Two things change at run time, both small: monocle_on and cycle_monocle took the
corner from the monitor (monitor.extra.window_hiding_position) and now take it
from the workspace's state, which the monitor writes into every workspace when it
updates their globals, so they differ only if a workspace's globals are stale
(a config reload without a layout update in between); and Container::restore
skips the Accessibility call under cfg!(test), as hide and load_focused_window
already did.
Verified: fast-check macOS PASS; fake-CC cargo clippy -p komorebi-macos
--all-targets -D warnings clean. Not verified: any macOS test or run.
Verified on the Mini: not yet. Hand check row added to docs/dev/macos-handcheck.md.
Merge of wip-cand5, wip-u-bugfix, wip-u-wm, wip-u-settings3, wip-u-repotools,
wip-u-nix3 and wip-u-e2e2unit.
Resolutions:
- docs/dev/macos-handcheck.md: every section is kept, in order. The bugfix
agent's section F (bar clicks) and the settings agent's section (also
headed F) both appended after E; the settings one is renamed G, text
unchanged.
- komorebi-for-mac/komorebi/src/animation/mod.rs and static_config.rs: the
formatting-only revision of wip-u-nix3 (76ab52da, import order) conflicts
with the semantic edits of wip-u-settings3 (S4/S5). The files are taken
from wip-u-settings3 as they are; the following style(macos) revision
formats them again with the check's rustfmt invocation.
Verified: see the following revisions and the report.
macos-handcheck.md gets section F (rows M1-M3) for the battery, CPU/network
and update clicks fixed in the two preceding revisions (appended, the file is
kfm's). known-issues.md is new: four findings that are not fixed because
whether they are bugs, or the fix, is the owner's call, each with evidence
(file and line), why it may or may not be a bug, the platforms and a proposed
fix: KDE FocusWorkspaceNumber/Numbers/LastWorkspace without the pointer
monitor preamble, Monitor::focus_workspace overwriting a workspace name,
remove_container focusing focused-1, and the macOS subscriber push without a
write timeout.
Docs only. The line references were read in this tree (pointer-monitor
preamble compared between the Windows and KDE process_command.rs); nothing
was run.
docs/dev/core-model.md section 20: what the converge batch did (two
platform accessors, eleven macOS arms onto KDE's named methods), where the
two daemons stand (137 of 155 router arms byte-identical, 45% of KDE's
window_manager function lines identical with macOS), why it is below the
60% bar (macOS's ContainerExt against the shared Container with a hiding
spot, the ? against let _ policy, the platform entry points, the one-sided
functions) and the four blockers with the recommended next step.
Verified: not applicable (documentation); counts from the arm and function
comparison at this tip.
docs/dev/settings.md section 10: what S4 and S5 moved, the differences
between the daemons that were kept on purpose (KDE resets transparency keys
on load and Windows keeps them; Windows animates a kind when the global flag
is on or the per-kind value is true, KDE and macOS let the per-kind value
win; the scoped guard on KDE, the suspend counter on macOS, the Windows
shutdown write). docs/dev/macos-handcheck.md section F (appended, nothing
else changed): the Mac checks for S3 and S5.
Verified: not applicable (documentation).
tools/README.md describes each tool, the tiered loops of fast-check (tier 1 cargo check and
unit tests of the edited tree, tier 2 other-platform type-check or clippy, nix builds as the
pre-landing gate), the prerequisites (jj, nix develop, jq, flock) and how the fake C compiler
works for the macOS type-check. The measured warm times come from the host README and are dated
2026-10-31 (revision c89651fa). Personal progress-log and scratchpad references are removed.
docs/dev/build-and-test.md gets a "Developer tools" section and links to tools/ where it named
fast-check, kde-closure-check and the fake-CC command (the macOS block now says
`tools/mac-check.sh`).
Verified: links and commands read against the committed scripts; nothing else run.
Inventory of every Windows/shared e2e scenario and the KDE VM suites against the
native tests that exist after the consolidation: class A (covered, cited), B
(coverable with the shared crates, proposed test) and C (needs a real OS), with
effort and value, ordered with the Windows-only e2e behaviours first. Gives the
estimate of gate minutes saved today and if the B items existed, the seams the
shared crates lack (daemon command handler, rule matching shared in
komorebi-config, monitor reconciliation, stack cycling), and the tests added
with the e2e check each mirrors.
Verified: not applicable (documentation); the cited tests were read, and the
added ones were run (see their revisions).
Candidate 5: wip-cand4 plus kfw's review fixes (wip-u-fix5: revert of the subscriber write timeout and the hwnd writer thread, BAR_RUNNING tied to the message, dead-window HIDDEN_HWNDS cleanup, core in default-members), kfm's macOS registry fixes (wip-u-kfm3), kfde's hook rename and per-pass title-bar snapshot (wip-u-core4), the komorebi-core characterization tests (wip-u-coretests) and the docs (wip-u-docs). Conflicts, if any, are resolved here.
docs/dev/macos-handcheck.md: a prioritised section with the independent review's twelve
hand checks and their exact steps (hide spot on the right display, event
latency with a stopped app, native tabs, floating and monocle, scrolling, config
reload, old state with the bar, pause and quit, bar config, unsupported commands,
registry growth, hung subscriber), a row for the wip-u-kfm3 registry fixes, and
a known-issue note: a subscriber that stops reading can stall the daemon (the
push writes under the window manager lock with no timeout; pre-existing and
the same in the original). A write timeout was deliberately not added: the
Windows review found it can truncate the JSON notification and does not bound
the stall, so the fix is a design, not a timeout.
ax_registry.rs module docs: when an entry is created (when the observer is
attached), the inert application, where it ends (the reapers, application
quit), why not in Window::drop, and what is not enforced (an observed
window that closes without passing through the reapers keeps its entry until its
application quits; cost and the unverified Mach-port question).
Verified: fake-CC cargo clippy --locked -p komorebi-macos --all-targets -D
warnings clean; tools/fast-check --since wip-cand4: native, Windows clippy, KDE
check + lib tests, macOS PASS; cargo test -p komorebi-core -p komorebi-backend
pass. Not verified: any run on macOS.
docs/dev/core-model.md section 19: remove_floating_window's hook is
before_floating_removed (behaviour unchanged), and the Windows title-bar
tables are taken once per pass through begin_pass; the sentence of
section 16 that called the per-container read an improvement is
corrected.
Verified: not applicable (documentation).
should_act and should_act_individual exist in the Windows, KDE and macOS
window.rs. Diffed arm by arm: KDE and macOS are byte-identical; Windows
differs only in taking one class instead of a list and in not stripping
`.exe` from the rule id. Strategies, regex lookup, case handling (none),
path handling (as given) and the last-match-wins composite logic are the
same. docs/dev/rule-matching.md has the table and the plan: one shared
implementation in komorebi-config with a single platform flag.
Verified: diff of the extracted functions. Docs only.
One page with the exact commands for each platform, so nobody has to
reconstruct them from the flakes and the progress notes:
- Windows: nix cross build of the binaries, the crane checks (clippy is the
pre-landing gate), the e2e-tests check, native tests of the neutral crates;
- KDE: cargo check/test with the right package names (the unit tests are in
komorebi-linux, not the thin komorebi binary package), the schema test with
one thread, the kfde-* checks of the root flake, the VM suites with `just vm`,
the tier lists, E2E_ONLY and KOMOREBI_RECORDER for VM runs;
- macOS: cargo build/test/clippy with `-p komorebic -p komorebi -p komorebi-bar`,
never `-p komorebic-macos` together with `-p komorebic`, and the Linux-only
type-check;
- Windows e2e: `nix run .#e2e-windows`, the `bar` scenario, E2E_ONLY, trace,
recorder, KEEP_GUEST, SCALE, STATE, bins from another commit;
- a what-to-run table and the known flakes with counts, summarised from the
flake registry kept by the gate runs (no personal paths).
It also records that komorebi-for-kde/justfile still assumes a KDE-only
workspace (`just check` would build the Windows crates).
Verified by running: `cargo metadata --no-deps` (package names), `cargo check
-p komorebi-linux -p komorebi -p komorebic` in komorebi-for-kde (ok), `nix eval
--json .#legacyPackages.x86_64-linux.vmTiers` (the tier lists match). Other
commands were read from flake.nix, justfiles and the e2e README, not run.
A new reader had no single page that said where things are: three platform
trees, nine shared crates, the four unified packages, the shims that remain,
and which differences are on purpose. The page gives:
- the three trees and what lives in each (root = Windows, komorebi-for-kde,
komorebi-for-mac) and that the root Cargo.toml is the only workspace;
- the packages komorebi (komorebi-daemon, cfg_select! over komorebi-windows,
komorebi-linux, komorebi-macos), komorebic, komorebi-client, komorebi-bar
and their cfg(target_os) layout, and the shim packages until the cutover;
- the crates/ map (protocol, config, collections, transport, backend, core,
settings, bar-core, komorebic-core);
- where the platforms differ on purpose, with a pointer to seam.md,
core-model.md, settings.md, unified-binaries.md, bar-unification.md and
macos-handcheck.md;
- the oracles (wire goldens, config and bar schemas, CLI docs, derivation
drift) and the tiered feedback loops;
- the tools outside the repository (fast-check, mac-check.sh,
kde-closure-check, e2e-needed, gate-lock, ...) with a proposal of which to
commit; nothing was moved.
Statements were checked against Cargo manifests (cargo metadata --no-deps
lists the package names used), flake.nix and the source directories. The
version numbers and the packages list were read from manifests. Not built;
macOS statements are what the progress log says, not observed.
The documents in docs/dev were written at different points of the
consolidation and some of their statements are history (for example
unified-binaries.md still says "never write -p komorebi", true before step 8).
Each now opens with a "Status (wip-cand4)" line saying whether it is design,
evidence or a log, what has landed, what has not, and, for
unified-binaries.md, which part is superseded.
The statuses were taken from the revision list wip-main..wip-cand4 and the
progress log, not from re-measuring. Only the line under the title was added;
no existing text changed. Not built.
Candidate 4: wip-cand3c (core line with macOS on komorebi-core, HideSpot, settings S1-S3, bar e2e scenario, handover scenario fix), wip-u-core3 (shared Workspace update_shared and the Windows converge of window_manager/process_command), wip-u-stallfix (lock-holder instrumentation, sysinfo scan before the lock, bar restart and hwnd file off the lock, subscriber write timeout) and wip-u-pkg2 (one komorebi package and binary, daemons as libraries). Conflicts, if any, are resolved here.
docs/dev/core-model.md section 18: the shared share of window_manager.rs
after the converge (26% identical with Windows, 37% within four lines,
63% differing or one-sided, so not above the 60% bar), a table of the
near-identical functions and why each is cosmetic or real (the Windows
handle_unmanaged_window_behaviour calls in 18 functions against the router
call on KDE and macOS, borders, floating windows in monocle, workspace
names, custom layouts, id types), the 25 differing router arms (two
converged, the rest real; FocusWorkspaceNumber(s) and FocusLastWorkspace
probably an omission on KDE), and the seven blockers.
Verified: not applicable (documentation); numbers from the function
comparison at this tip.
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`.
docs/dev/core-model.md section 16: update_shared and where it departs from
section 12, and what macOS's update keeps (SkyLight batch, no maximized
branch, a separate scrolling path, an unconditional clamp, no stackbar) as
three decisions for its owner. Section 17: process_command arm by arm (110
of 155 arms in all three daemons identical, 45 not, with the clusters of
the differing ones), process_event (only three of the events exist on all
three, so it is the thin-events step), and window_manager function by
function (39 identical in all three, 48 differing, the one-sided lists,
the 20 functions that are identical in KDE and macOS and old only in
Windows), with the order and the hooks of the remaining layers of step 9.
Verified: not applicable (documentation); the counts come from the arm and
function comparison of the three trees at this tip.
Merge of kfm's macOS core migration (wip-u-kfm2 9cb4f2fa) and the settings
stack through S3 (wip-u-settings2 696d2929), both on wip-u-integ2. Two files
conflicted, both macOS; every hunk is resolved the same way: take kfm's
version of the file (its new shapes: komorebi_core Monitor/Workspace,
workspace_config and monitor_config as free functions) and re-apply the S3
change to it, because the settings side only touched lines kfm moved.
- komorebi-for-mac/komorebi/src/monitor.rs: conflict 1 (imports): kfm's
header doc kept, the DEFAULT_CONTAINER_PADDING / DEFAULT_WORKSPACE_PADDING
imports dropped (S3). Conflict 2 (std imports): kfm's side (no VecDeque).
The four padding reads (the two default fallbacks in the monitor's
workspace globals) call crate::settings::container_padding() /
workspace_padding(); the now unused Ordering import is removed.
- komorebi-for-mac/komorebi/src/static_config.rs: both conflicts are the
padding defaults in kfm's free functions (workspace_config, monitor_config):
kfm's text kept, the two defaults read from settings. Re-applied S3 in this
file: apply_globals applies paddings, aspect ratio, layout_defaults and
display_index_preferences as one Handle::update of a SharedDelta; the
readers (layout_defaults, aspect ratio, display preferences, paddings) use
the accessors; the statics' imports and the now unused AspectRatio imports
are removed.
komorebi-core and the shared crates read none of the removed statics
(grep: only the unrelated DEFAULT_*_PADDING consts in komorebi-config), so no
hook is needed. S3 semantics are unchanged from wip-u-settings2 (statics
removed, one update per load, reload merges, a few keys reset); the pins
are the settings crate's reload.rs and shared tests plus the KDE
tests/config.rs.
Verified: see the run in the progress log (macOS fake-CC clippy -D warnings
-p komorebi-macos --all-targets clean at this revision).
Records the HideSpot change and the three macOS layers (container, workspace,
monitor) as done, lists the functions that stay in the macOS extension traits,
and notes that ContainerExt is the old container code kept for the daemon's own
call sites.
Verified: documentation only.
Section 9 of docs/dev/settings.md: what S3 moved, how apply_globals and the
command write it, how readers get it, and that the only BEHAVIOUR is the
single publish.
Verified: not applicable (documentation).
Step 11(iii), the Monitor layer. BEHAVIOUR (type-checked and clippy-clean with the
fake CC; the macOS tests are the oracle and have not run).
pub type Monitor = komorebi_core::Monitor<MacosPlatform>. MacosPlatform
implements MonitorPlatform: the id is the u32 display id written as a number, the
serial number a String, and the extra fields MacosMonitorExtra {
window_hiding_position}, flattened into the monitor's JSON (the key was already
the last of the macOS monitor, so the text is the same; a test pins the keys and
their order). The shared monitor gives focus_workspace, add_container,
remove_workspace_by_idx, remove_workspaces, ensure_workspace_count,
new_workspace_idx and the two name/layout lookups (nine functions that were the
same text or differed only in their types). The rest stays macOS's as
MonitorExt: new, placeholder, update_focused_workspace, update_workspace_globals,
update_workspaces_globals, update_all_workspace_globals, load_focused_workspace,
hide_unfocused_workspaces, restore_focused_workspace, move_container_to_workspace
(and its '1' variant) and add_container_with_direction, because they differ from
the KDE ones in what they do (SkyLight batches, the corner, the animator). The
monitor writes its corner into each workspace's state when it updates the
globals. From<&Monitor> for MonitorConfig, an orphan impl now, is the function
monitor_config. Monitor::new and Monitor::placeholder are called through the
MonitorExt trait.
No silent bind: no MonitorExt method shares a name with a method of the shared
monitor (checked: empty intersection); the shared and the old text differ only
in types, and a call of an old signature does not compile.
Verified: fake-CC cargo clippy --locked --target aarch64-apple-darwin -p
komorebi-macos --all-targets -D warnings clean; tools/fast-check macOS PASS.
Not verified: any macOS test or run. Verified on the Mini: not yet. Gate: the
Mini's cargo test, then the hand check row in docs/dev/macos-handcheck.md.
Step 11(iii), the Workspace layer. BEHAVIOUR (type-checked and clippy-clean with
the fake CC; the macOS tests are the oracle and have not run).
pub type Workspace = komorebi_core::Workspace<MacosPlatform>. About 53 of the
65 functions of the macOS workspace.rs are the shared ones now (identical, or
differing only in the id type, the Container type or a hook; section 14 of
core-model.md lists them). MacosPlatform implements WorkspacePlatform:
foreground_window_id and cursor_position (the same MacosApi calls),
should_act_window(_individual) (the macOS should_act with the class as a
one-element slice), the three scrolling hooks, after_floating_removed
(focus_previous_floating_window, which is shared), and the two hide spots:
hide_spot is the monitor's corner with no display (what every Window::hide
call had), hide_spot_on_display adds the display bounds from the work area
(what Workspace::hide gave the containers). The corner is MacosWorkspaceState,
which the monitor sets next to the globals (it was a field of the macOS
WorkspaceGlobals, which is now the shared type; both are serde-skipped, so
the JSON is the same). The eight functions that took the hiding position
(hide, move_window_to_container, new_floating_window,
new_container_for_focused_window, new_container_for_window,
reintegrate_monocle_container, new_monocle_container, focus_container_by_window)
are the shared ones with the spot argument; the ones that stay macOS's are
WorkspaceExt (update, apply_wallpaper, restore, remove_window,
load_static_config, prune_duplicate_windows, visible_window_details,
reap_invalid_windows_for_application, restore_windows, calculate_layouts,
set_scrolling_columns) and, in scrolling.rs, the former inherent methods now
the trait WorkspaceScrolling (an inherent impl on a type of another crate is not
allowed). The Window implements WorkspaceWindow (class is its role, path a
String). From<&Workspace> for WorkspaceConfig, an orphan impl now, is the
function workspace_config. The shared Workspace has one field macOS lacked
(initial_window_placement_rules, None and skipped when None), so the JSON
has the same keys: new test state_pin pins them.
Behaviour that is deliberately kept: floating windows are hidden at the corner
with no display (hide_spot), containers with the display; ContainerWindow's
hide and restore skip their work under cfg!(test), as the old container code did.
No silent bind: the names of the methods of WorkspaceExt, WorkspaceScrolling
and ContainerExt share no name with a method of the shared Workspace
(checked mechanically: the intersection with the core inherent names is only
Container::restore, a different type); and each of the shared functions that
used to take the corner has a different signature from the macOS one it
replaced, so a stale call is a compile error, which was the order in which the
errors showed up.
Verified: fake-CC cargo clippy --locked --target aarch64-apple-darwin -p
komorebi-macos --all-targets -D warnings clean; tools/fast-check macOS PASS.
Not verified: any macOS test or run. Verified on the Mini: not yet. Gate: the
Mini's cargo test, then the hand check added to docs/dev/macos-handcheck.md.
Records the result of the Container move and why Workspace<MacosPlatform> is
not started: eight shared workspace functions call the no-argument infallible
hide forms while macOS passes the monitor's corner and display and
propagates the error; four of them have the same signature as macOS's own, so
the switch would bind the shared body silently (a behaviour change that the
type-check cannot see). Proposes the core change (an associated HideSpot type
on ContainerWindow, () on KDE and Windows, taken from the workspace
globals, and a fallible result) and lists the small mismatches that also
come first (path as String, class, should_act's class slice, the scrolling
hooks).
Verified: documentation only.
Step 11(iii), the Container layer. BEHAVIOUR (type-checked and unit-test
oracle only; macOS cannot run here).
pub type Container = komorebi_core::Container<Window>, with ContainerWindow
implemented for the macOS Window (id is the CGWindowID, exe_name its exe;
hide_window and restore_window use the default corner and log a failure,
because the daemon does not hide through them). The container's own struct,
accessors, preselect, idx_from_exe, contains_window, idx_for_window,
remove_window_by_idx, remove_focused_window and focus_window are now the
shared ones. The four functions that carry the monitor's WindowHidingPosition
(and for hide the display bounds), return a Result and skip the work under
cfg!(test) stay macOS's own, as ContainerExt, under names the shared type
does not use: add_window_at, load_focused_window_at, hide_on and
restore_focused_window (an inherent method of the shared type would shadow an
extension method of the same name); about 35 call sites follow. The shared
Container reads a missing 'locked' as false (macOS used to require it).
komorebi-core is a dependency of the macOS daemon (and its schemars feature).
State JSON: two new tests pin the shape ({id, locked, windows: {elements,
focused}}) and the missing-locked read; the existing round-trip test is kept.
They can only run on a Mac.
Verified: fake-CC type-check (tools/fast-check) PASS on all targets; Windows
clippy, KDE check and tests unaffected PASS. Not verified: any run. Verified
on the Mini: not yet. Gate: the Mini's cargo test; then the hand check added to
docs/dev/macos-handcheck.md (stacks, workspaces, state JSON, per-monitor
hiding corner).
Merge of wip-u-core (kfde: komorebi-core with Container, Workspace<P>, Monitor<P>) and wip-u-pkg-mig3.
Conflicts and how they were resolved:
- komorebi-for-kde/Cargo.toml, komorebi-for-kde/Cargo.lock: deleted, as in the migration (one root
workspace); kfde's only edit there, the komorebi-core workspace dependency, is applied as a path
dependency in the crate manifest.
- komorebi-for-kde/komorebi/Cargo.toml: the migration's manifest (inlined dependencies, package name
komorebi-linux, [lib]/[[bin]]) plus kfde's komorebi-core dependency and the komorebi-core/schemars
feature.
- Cargo.lock: the migration's lock re-resolved with cargo metadata --offline: the only change is the
new komorebi-core 0.1.42 entry; no version of any other package moved (compared by name/version with
both parents; kfde's Windows lock differs only by the komorebi -> komorebi-windows rename).
- komorebi-bar/src/widgets/komorebi.rs: deleted (the Windows bar moved to komorebi-bar/src/windows/);
kfde's one-line edit (title: value.title() instead of value.title().ok()) applied to
komorebi-bar/src/windows/widgets/komorebi.rs.
- komorebi-for-kde/nix/root-crates.json: crates/komorebi-core added (tools/kde-closure-check now ok with
11 root crates).
Gates run: tools/fast-check --since wip-u-pkg-mig3: native tests, Windows clippy -D warnings, KDE check+lib+schemas, macOS fake-CC check, nix evaluation (root and both nested flakes) PASS; KDE cargo test -p komorebi-linux -p komorebic -p komorebi-client -p komorebi-hotkeys -p komorebi-core: 902 passed, 0 failed; CLI docs oracle identical x3; bar schema harness byte-identical for both bars (its Window::title stub now returns Option); bar-core tests 3+6; kde-closure-check ok; by evaluation an edit of the Windows bar or daemon leaves the kfde derivations unchanged, a KDE edit leaves Windows unchanged, and an edit of crates/komorebi-core changes Windows and kfde but not macOS. Not run: nix builds, VM, e2e (the Windows daemon changed: kfde's e2e gate applies), any Mac run.
Classifies every function of komorebi-for-mac/komorebi/src/{container,
workspace,monitor}.rs against komorebi-core (or the KDE extension traits):
container 5 identical, 6 text-only, 4 real (the hiding functions); workspace
11 identical, 26 text-only, 8 differing only through hooks that exist, 8
differing by the hiding position, 4 real, 3 text in the extension trait, 5
macOS-only; monitor 5 identical, 4 text-only, 8 in the extension trait, 4
macOS-only. States the one difference that decides the order: the hiding
position and the fallible hide.
Verified: counts from a function-by-function diff run on this host (stripped
text, namesake against namesake); documentation only. Not verified: that the
text-only functions behave identically on a Mac, which the macOS tests will
show once they run on the shared code.
wip-u-kfm carries the macOS clippy fixes (&Path, drain, filter, slice fill, sort_by_key, collapsible_match allows, capture_spike, bar stroke literals). The bar stroke literal revision touches komorebi-for-mac/komorebi-bar, which the migration moved to komorebi-bar/src/macos; conflicts are resolved here by applying the same edit at the new paths.