Commit Graph
69 Commits
Author SHA1 Message Date
LGUG2Z a478495049 refactor(mac): the daemon uses the shared Container API with the hide spot
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.
2026-11-05 15:03:26 -08:00
LGUG2Z e870eca239 chore(repo): combine candidate 6 with the shared rule matcher, the stall fixes, the bar scenario fix and the shared commands (candidate 7)
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.
2026-11-05 15:03:26 -08:00
LGUG2Z a1e59871c1 test(config): rule matching tests for the Windows input shape
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.
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 20df9c98df docs: the shared commands, what moved and what stays
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).
2026-11-05 15:03:26 -08:00
LGUG2Z 97c21b9360 merge: wip-cand6
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.
2026-11-05 15:03:26 -08:00
LGUG2Z b212b554cd docs(dev): macOS hand-check rows for the bar clicks and a list of findings needing a decision
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.
2026-11-05 15:03:26 -08:00
LGUG2Z 7b070fffda docs: KDE and macOS window_manager.rs and router after the converge, and the blockers
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.
2026-11-05 15:03:26 -08:00
LGUG2Z 278ef8f3fc docs(settings): S4 and S5 as landed, macOS hand-check section F
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).
2026-11-05 15:03:26 -08:00
LGUG2Z f9b18a6f34 docs(tools): add tools/README.md and point build-and-test.md at the committed tools
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.
2026-11-05 15:03:26 -08:00
LGUG2Z f085064af9 docs(dev): e2e-to-unit, which e2e checks the shared crates made testable natively
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).
2026-11-05 15:03:26 -08:00
LGUG2Z ba094355d4 chore(repo): combine the review fixes, new tests and docs (candidate 5)
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.
2026-11-05 15:03:26 -08:00
LGUG2Z ba25355cca docs(macos): the review's checks H1-H12, the registry's lifetime rules, and the known subscriber hang
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.
2026-11-05 15:03:26 -08:00
LGUG2Z 48861ece10 docs: correct the title-bar claim and name the renamed hook (F2, F3)
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).
2026-11-05 15:03:26 -08:00
LGUG2Z 359111ea4c docs(dev): classify the three copies of window-rule matching
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.
2026-11-05 15:03:26 -08:00
LGUG2Z 9c2c50cc40 docs: build-and-test.md, the commands and the known flakes per platform
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.
2026-11-05 15:03:26 -08:00
LGUG2Z 0008c6c27d docs: ARCHITECTURE-UNIFIED.md, a map of the repository after the consolidation
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.
2026-11-05 15:03:26 -08:00
LGUG2Z 864de814cd docs: begin each plan document in docs/dev with a one-line status
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.
2026-11-05 15:03:26 -08:00
LGUG2Z a68668840d chore(repo): combine the gate candidate 3c with the core, stall-fix and one-daemon-package lines (candidate 4)
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.
2026-11-05 15:03:26 -08:00
LGUG2Z 35a9f2d51c docs: the window_manager.rs converge result and the blocker list for WindowManager<P>
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.
2026-11-05 10:30:05 -08:00
LGUG2Z 89bc4512f0 docs: step 8 done (one komorebi), the cutover list, the Mac Mini commands for -p komorebi
Not verified: any build through nix, e2e, VM or Mac run.
2026-11-05 10:30:05 -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 c1f9aab49e docs: update_shared landed, what macOS keeps, and the classification of window_manager, process_command and process_event
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.
2026-11-05 10:30:05 -08:00
LGUG2Z e663e346ba merge: wip-u-kfm2 + wip-u-settings2 (candidate 3)
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).
2026-11-05 10:30:05 -08:00
LGUG2Z cacd508a91 docs(core): section 15, the macOS layers moved and what stayed macOS's
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.
2026-11-05 10:30:05 -08:00
LGUG2Z 0499b5c7a3 docs(settings): record S1, S2 for Windows and S3 for all three daemons
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).
2026-11-05 10:30:05 -08:00
LGUG2Z db6d04fa94 refactor(mac): the daemon's Monitor is komorebi_core::Monitor<MacosPlatform>
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.
2026-11-05 10:30:05 -08:00
LGUG2Z c51858468e refactor(mac): the daemon's Workspace is komorebi_core::Workspace<MacosPlatform>
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.
2026-11-05 10:30:05 -08:00
LGUG2Z 22e6011333 docs(core): where the macOS move stops, and the change it needs in komorebi-core
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.
2026-11-05 10:30:05 -08:00
LGUG2Z 283e5438fc refactor(mac): the daemon's Container is komorebi_core::Container<Window>
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).
2026-11-05 10:30:05 -08:00
LGUG2Z b937a3d716 chore(repo): merge kfde's core line into the package migration
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.
2026-11-05 10:30:05 -08:00
LGUG2Z 6c5731cda4 docs(core): section 14, the macOS functions against the shared model
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.
2026-11-05 10:30:05 -08:00
LGUG2Z 072ba7a471 chore(repo): merge the kfm clippy fixes into the package migration line
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.
2026-11-05 10:30:05 -08:00
LGUG2Z 29bdd0b2c7 docs(macos): record that the Mini runs so far are compile and unit tests only
Adds a status section to the hand-check list: cargo test --workspace passed
on the Mini (daemon 366 passed, 1 ignored) and clippy is clean, but nothing
was run as a daemon, so every walk-through item stays open.

Verified: documentation only.
2026-11-05 10:30:05 -08:00
LGUG2Z 6ad0554556 docs: record Monitor<P> and the four hook-shared workspace functions
docs/dev/core-model.md section 13: what Monitor<P> holds and what stays in
MonitorExt, why the two globals updates are not shared (KDE's plural one
has no border), the serde facts the tests pin (flattened map keys, the
schema order) and the hooks of promote_container, effective_layout_options,
new_floating_window and hide.

Verified: not applicable (documentation).
2026-10-31 13:19:31 -07:00
LGUG2Z ba6ad8eacd docs: propose the shared update skeleton with its hooks and the exact bodies
docs/dev/core-model.md section 12: the skeleton of Workspace::update that
can move into komorebi-core (begin_update with the Flow guard,
containers_pruned, place_monocle, maximize_in_layout,
adopt_widths_before_layout for the scrolling-in-motion condition,
monitor_rects, adjust_layout per container, place_container, end_update
returning Pass), a table of the body each daemon keeps in each hook, the
constraints that make it safe, and the unified diff of the two update
bodies at this tip as the exact record. Not implemented: it waits for the
Windows e2e gate.

Verified: not applicable (documentation).
2026-10-31 13:00:46 -07:00
LGUG2Z 20c87b0ad0 docs: record what the Workspace move landed and where the sharing stops
docs/dev/core-model.md section 11: Workspace<P> and its shared functions
are in komorebi-core and both daemons use it; the functions left in the
extension traits (remove_window, restore, new_maximized_window,
reintegrate_maximized_window, apply_wallpaper, update, the custom
layout arms) differ in what they do and not only in how they are
written, listed one by one with the difference; hide and
new_floating_window can be shared once their hooks exist. Where Monitor
stands.

Verified: not applicable (documentation).
2026-10-31 12:55:06 -07:00
LGUG2Z c23569a337 docs: macOS commands name komorebi-macos, not komorebi
The Mac Mini run failed on -p komorebi: the daemon packages are komorebi-macos and komorebi-windows (the
single komorebi package is step 8). Corrected the command list and the note.
2026-10-31 12:53:29 -07:00
LGUG2Z 75688cf74f docs: bar steps B0-B3 done; what to run on the Mac Mini
Marks the bar steps as executed (B4 left, why), and lists the cargo build, clippy, test and schema commands
for aarch64-darwin per revision. Not verified: any of them on a Mac.
2026-10-31 12:45:37 -07:00
LGUG2Z a73c9e2131 docs: state of the package migration (steps 0-6), the bar steps, the owed gates
Updates docs/dev/unified-binaries.md: steps 5 and 6 done, the limits found, step 7 for the bar written as
exact steps (B0-B4, not executed; bar files untouched), and the list of heavy builds, VM, e2e and Mac
checks the coordinator owes. Not verified: any nix build.
2026-10-31 12:35:48 -07:00
LGUG2Z 2b7deddca7 docs: record where the Workspace move stands and what is left, per function
docs/dev/core-model.md section 10: 58 functions (about 530 lines) are now
identical on both sides, only new_container_for_window depends on a
differing function (resolve_placement_index), and a table of every
remaining difference with the converge step or hook that removes it, plus
what ContainerWindow must grow before the first generic function
compiles.

Verified: not applicable (documentation).
2026-10-31 12:22:40 -07:00
LGUG2Z e4a5a03b99 docs: review the Workspace hook design against KDE's update and hide
docs/dev/core-model.md section 9: three corrections to section 8 found by
reading KDE's workspace.rs next to the Windows one (begin_update must be
fallible and mutating because KDE prunes duplicates and clamps the focus
first; end_update must return Pass::Again because Windows' update loops
for scrolling; a scrolling_in_motion condition is read mid-update on both
platforms; adjust_layout is per container for the stackbar), the error
policy of place_window, the orphan-rule cost of extension traits, that
WorkspaceConfig is already shared, that Monitor cannot move before
Workspace (it uses about 25 of its members), the visible-windows decision
for the owner, and the order of what remains.

Verified: not applicable (documentation).
2026-10-31 12:14:35 -07:00
LGUG2Z 2002ca428b docs(core-model): design the platform hooks of a shared Workspace (section 8)
Design only, no code. Section 8 of docs/dev/core-model.md: Workspace<P:
WorkspacePlatform> with defaulted hooks for the six (c) differences of
section 7 (begin_update / adjust_layout / place_window / end_update,
apply_wallpaper, on_window_removed, after_hide, unmaximize_window), what each
platform does in them, the statement that Windows needs no unmaximize in
reintegrate_maximized_window or new_floating_window, how the (d) features
become extension traits or associated state (border_kinds_on_show,
windows_on_show, hwnd_from_exe, custom layouts, the KDE-only reaping and
pruning, scrolling_placed, the Windows-only Monitor fields), what has to
exist first, and the order and e2e gates of the implementation.

Docs only.
2026-10-31 12:14:35 -07:00
LGUG2Z 5660ad8f02 docs: record the state of the package migration (steps 0-4 done)
Adds the state, the measured cache isolation after the workspace merge and the limits found (stubbed
source is read at evaluation, so other systems' attributes need their own builder; deny/fmt/taplo of the
merged workspace unbuilt; steps 5 and 6 left for the cutover). Not verified: any nix build.
2026-10-31 12:10:04 -07:00
LGUG2Z 3f50f09264 docs: classify the workspace.rs and monitor.rs differences per function
docs/dev/core-model.md section 7: the two files compared function by
function (not by one whole-file diff, which misaligns): 36 non-test
functions of workspace.rs are identical, the differing ones are 1
cosmetic, 15 same-behaviour-different-text, 6 platform differences and 14
one-sided features, with changed-line counts; monitor.rs likewise (8
identical, 2 b, 3 platform, 9 one-sided). Lists what each remaining
cluster needs, as the hand-over to the Windows side.

Verified: not applicable (documentation); the counts come from per-function
diffs of the files at this tip.
2026-10-31 11:42:19 -07:00
LGUG2Z fdd5e7f8da docs: record that Container moved into komorebi-core and where the move stops
docs/dev/core-model.md section 6: what komorebi-core holds (Container<W>,
ContainerWindow), how KDE and Windows use it, how the JSON is pinned, and
why Monitor is not moved yet: after kfw's convergence the two monitor.rs
still differ by 657 changed code lines (extra Windows fields name,
device_id and workspace_names, serial_number_id Option vs String, the
hmonitor_json id, MonitorInformation fields, the workspace show/hide and
globals methods), which is a decision about the state JSON and a Platform
hook design, not a mechanical converge. Lists what remains in order.

Verified: not applicable (documentation); the 657 comes from diff of the
files stripped of comments and blank lines at this tip.
2026-10-31 11:36:54 -07:00
LGUG2Z 12870fa533 chore(repo): base for the package migration
Merge of wip-stage (kfde, bar, settings), wip-cand1 (kfw, kfm), wip-u-nix and wip-u-pkg (the
unified-binaries doc), so the migration is built on the open stacks and does not conflict with them later.
2026-10-31 11:31:14 -07:00
LGUG2Z 374269646e docs: unified komorebi, komorebic and komorebi-bar packages (layout, migration order, risks)
Records the spike (revisions on wip-u-pkg-spike, nothing landed on wip-main): one root
workspace holds the Windows, KDE and macOS crates with one Cargo.lock (+41 packages), the
unified komorebic builds on all three targets, KDE tests pass unchanged except one test
that reads the package name. Recommends komorebic and bar as one crate with cfg(target_os)
modules and the daemon as three gated libraries behind one thin binary, lists the migration
order, risks, gates (compile, S oracle, nix, e2e, KDE VM, Mac hand check) and the file moves
that conflict with the open wip-u-* stacks.

Verified: Windows cargo check -p komorebic, KDE check and 879 of 880 tests, macOS fake-CC
check, all on the spike tree. Not verified: nix builds, e2e, VM, any macOS link or run.
2026-10-31 11:27:53 -07:00
LGUG2Z 1b3b33fb2c chore(repo): combine the kfde, bar and settings stacks (staging)
Staging merge of three stacks that make no runtime change on Windows or KDE: the KDE Backend/Container/process_command refactors (wip-u-kfde), the shared bar core moves (wip-u-bar) and komorebi-settings with the S1/S2 pins (wip-u-settings). Conflicts, if any, are resolved here. Not yet gated: the KDE VM suites and the Windows bar check are owed.
2026-10-31 11:25:59 -07:00
LGUG2Z 0a823eec94 docs(settings): inventory of the process-wide statics and the Settings design
Measured on wip-main 633e7453 by grep and reading: 126 (Windows), 53 (KDE)
and 74 (macOS) static declarations, of which 61/35/36 are configuration and
51/29/28 are written by apply_globals. The document has the per-static
table (type, writers, readers, shared or platform, matching name), the lock
order of the rule lists, the proposed Settings (shared part plus a platform
type parameter, snapshot reads, serialised updates, scoped override), the
statics whose semantics would change (reload merges rather than replaces;
partial updates visible mid-reload; save-and-restore writes; the empty
WORKSPACE_MATCHING_RULES window), the migration order with pure refactor
versus BEHAVIOUR marks and the gate each needs, and section 7 with the
findings from encoding the semantics in the crate (aspect ratio starts at
Widescreen but a load without the key writes Standard).

Verified: nothing run (documentation); counts from grep, line numbers read
at 633e7453.
2026-10-31 11:25:26 -07:00