EventChannel<E> is the window-event channel that KDE and macOS each write by hand in window_manager_event_listener.rs: bounded, send is try_send and never blocks, an event that does not fit is dropped with the warning 'channel is full; dropping notification', and an optional predicate (EventChannel::coalescing) lets one coalesced event (the ResizeStep of a drag) wait at a time, released by coalesced_taken(), also when the send of the claiming event fails. The channel also records that an event was dropped (take_overflow); no tree reads it (R6 is a behaviour change, out of scope here). The flag orderings are SeqCst as in the KDE copy (macOS used AcqRel/Release; stronger on one variable, no visible difference). Nothing uses it yet. Logs use the target komorebi::transport (D29).
Verified: cargo test -p komorebi-transport: 13 passed, 0 failed (5 new, the three macOS coalescing tests rewritten against the API, plus no-predicate and drop/overflow); cargo clippy -p komorebi-transport --all-targets -D warnings: clean.
notify_subscribers keeps the Windows override events (TitleUpdate, Uncloak and Show, no Monitor), the registry statics and the whole named-pipe part (SUBSCRIPTION_PIPES, error codes 2 and 232), and hands the socket push to komorebi_transport::notify_sockets with uds_windows::UnixStream::connect. Both locks are still held to the end of the function and the early return on a write error still skips the pipes. 33 lines removed from lib.rs. Behaviour-preserving; logs of the socket part use the target komorebi::transport (D29).
Verified: nix develop --command cargo clippy --workspace --locked --all-targets -- -D warnings (x86_64-pc-windows-msvc): finished, no warnings or errors. Not verified: Windows tests and scenarios (subscribers are exercised by the bar and the scenarios).
Same as the KDE revision: notify_subscribers keeps the macOS override events (Monitor, AddSubscriberSocket, AddSubscriberSocketWithOptions, Theme, ReloadStaticConfiguration, WindowManager Show) and the registry statics and hands the push to komorebi_transport::notify_sockets. 40 lines removed from lib.rs. Behaviour-preserving; logs use the target komorebi::transport (D29).
Verified: macOS fake-CC cargo check --locked --target aarch64-apple-darwin --workspace --all-targets: 0 errors, no new warnings. Unit tests cannot run on Linux.
notify_subscribers keeps its KDE-specific part (the override events: Monitor, AddSubscriberSocket, AddSubscriberSocketWithOptions, Theme, ReloadStaticConfiguration, WindowManager Show) and the registry statics, and hands the push to komorebi_transport::notify_sockets. 40 lines of connect/write/stale-removal code removed from lib.rs. Behaviour-preserving; logs use the target komorebi::transport (D29).
Verified in komorebi-for-kde: cargo check -p komorebi --all-targets: no errors or warnings; cargo test -p komorebi --lib: 293 passed, 0 failed; the notify_subscribers doctest (it pushes to a real socket and removes a stale one): passed.
komorebi_transport::notify_sockets is the mechanics of notify_subscribers that the three daemons each copy: for each subscriber socket, skip it if it wants state changes only and nothing changed and the event is not an override event, connect, write the notification, collect the sockets that cannot be connected to, then remove those from the registry and delete their socket file (errors logged). The daemon keeps the registry statics and their locks (the public SUBSCRIPTION_SOCKETS path is used by the bar, main and a KDE doctest, and the Mutex type is the daemon's own parking_lot) and passes what differs per platform: the registry, the push_unchanged decision (state modified or one of its platform's override events), the data dir and the connect function (uds_windows on Windows). Nothing uses it yet. Logs use the target komorebi::transport (D29).
Verified: cargo test -p komorebi-transport: 8 passed, 0 failed (2 new: push and stale removal, state-change filter); cargo clippy -p komorebi-transport --all-targets -D warnings: clean.
listen_for_commands and read_commands_uds call komorebi_transport::listen_for_commands and read_commands. What only Windows does stays Windows-side behind the ConnectionPolicy hook (WindowsConnectionPolicy): the 1 s read timeout set after accept (on_accept) and the 30 s timeout set when a PanGesture::Begin is read (on_message, called before the 1 s try_lock_for, at the same point of the loop as before). WindowManager implements CommandTarget over uds_windows::UnixListener/UnixStream (the transport crate implements the stream traits for them on Windows). The window manager keeps the 1 s try_lock_for. The TCP listener and read_commands_tcp (blocking wm.lock(), 1024-byte reads, TCP_CONNECTIONS) and the named-pipe subscribers are untouched. Behaviour-preserving, not a literal text move. Cosmetic: the accept-error log line now reads 'failed to get unix stream <error>' like KDE and macOS and logs come from the target komorebi::transport (D29). 80 lines of loop code removed from process_command.rs.
Verified: nix develop --command cargo clippy --workspace --locked --all-targets -- -D warnings (x86_64-pc-windows-msvc): finished, no warnings or errors. NOT verified: the Windows unit test and the scenarios; the PanGesture timeout and TCP paths have no test in any tree. Needs the Windows e2e (commands, pausing, pan) before landing.
Same change as the KDE revision: listen_for_commands and read_commands_uds call komorebi_transport::listen_for_commands and read_commands with NoPolicy (macOS sets no read timeouts), and WindowManager implements CommandTarget (clone of command_listener under the lock, try_lock_for on parking_lot, is_paused, process_command). #[tracing::instrument] stays on listen_for_commands. read_commands_uds keeps its name and signature for the unit test. Behaviour-preserving, not a literal text move; logs now use the target komorebi::transport (D29). 75 lines of loop code removed from process_command.rs.
Verified: macOS fake-CC cargo check --locked --target aarch64-apple-darwin --workspace --all-targets: 0 errors. macOS unit tests cannot run on Linux.
listen_for_commands and read_commands_uds now call komorebi_transport::listen_for_commands and read_commands with NoPolicy (KDE has no read timeouts); WindowManager implements CommandTarget (clone of command_listener under the lock, try_lock_for on the parking_lot mutex, is_paused, process_command). The 3 hand-written loops (accept loop of 40 lines, read loop of 35 lines) are gone from process_command.rs. read_commands_uds keeps its name and signature, so the unit tests still call it. Behaviour-preserving, not a literal text move: the loop is generic and the message is cloned once more on the paused path. Logs now come from the target komorebi::transport instead of komorebi::process_command (D29). The test module needed three imports (BufRead, BufReader, FromStr) that it used to get from the parent through use super::*; no test body changed.
Verified in komorebi-for-kde: cargo check -p komorebi --all-targets: no errors, no warnings; cargo test -p komorebi --lib process_command: 11 passed, 0 failed; tests socket + no_kwin + hot_reload: 1 + 3 + 3 passed, 0 failed. Full workspace run: see the next revision's message.
komorebi-transport gets the accept loop and the read loop that the three daemons each carry a copy of: listen_for_commands (restart-on-panic outer thread, listener cloned under the window manager lock, one thread per client) and read_commands (one message per line, the 1 s try_lock_for on the window manager with the warn-and-drop when it is not got, the pause filter, return after a paused message). The window manager is reached through small traits: CommandTarget (shared handle type, listener handle, try_lock_for, is_paused, process_command), CommandListener/CommandStream (implemented here for std::os::unix::net and, on Windows, uds_windows), and a ConnectionPolicy hook (on_accept, on_message; NoPolicy by default) for the Windows read timeouts. The lock itself is taken by the daemon (CommandTarget::try_lock_for) because KDE uses parking_lot 0.13 and the other trees 0.12, so the crate cannot name the Mutex type (D30). This is a behaviour-preserving generalisation of the loops, not a literal text move. Nothing uses it yet.
The crate logs under the target komorebi::transport: the KDE and macOS daemons filter with RUST_LOG=komorebi=<level>, which would silence a target named komorebi_transport (D29).
Verified: cargo test -p komorebi-transport: 6 passed, 0 failed (5 new: messages in order, paused ends the connection, invalid line is an error, policy sees messages, listener serves a connection over a real socket); cargo clippy -p komorebi-transport --all-targets -D warnings: clean.
Both read_commands_uds and read_commands_tcp now ask komorebi_transport::allowed_while_paused instead of listing TogglePause, State, GlobalState and Stop. The one token that differed between the two copies (process_command(message, stream) in the TCP reader, where stream is already a &mut TcpStream, against &mut stream in the UDS reader) is only how the reply stream is passed: each call site keeps its own form, so TCP behaviour is unchanged. A paused connection still ends after the first message. komorebi-transport becomes a dependency of the Windows daemon.
Verified: nix develop --command cargo clippy --workspace --locked --all-targets -- -D warnings: finished, no warnings or errors (tier 2). Not run: Windows unit tests or scenarios.
read_commands_uds now asks komorebi_transport::allowed_while_paused instead of listing TogglePause, State, GlobalState and Stop in a match. Same behaviour: while paused those four are handled, any other message is dropped with the same trace log, and the connection ends after either. komorebi-transport is added as a path dependency of the macOS workspace.
Verified: macOS fake-CC cargo check --locked --target aarch64-apple-darwin --workspace --all-targets in komorebi-for-mac: 0 errors (warnings only, pre-existing). Unit tests cannot run on Linux.
read_commands_uds now asks komorebi_transport::allowed_while_paused instead of listing TogglePause, State, GlobalState and Stop in a match. The behaviour is the same: while paused those four are handled, any other message is dropped with the same trace log, and the connection ends after either. komorebi-transport is added as a path dependency of the KDE workspace.
Verified: cargo check -p komorebi --all-targets in komorebi-for-kde: no errors; cargo test -p komorebi --lib process_command: 11 passed, 0 failed (includes while_paused_only_toggle_pause_state_and_stop_are_handled). Full workspace run is done once at the end of the KDE listener stage.
A new platform-neutral crate, crates/komorebi-transport (edition 2024, member of the root workspace), that will hold the command transport shared by the three daemons (D23/D24). It starts with allowed_while_paused(&SocketMessage) -> bool: the four messages (TogglePause, State, GlobalState, Stop) a daemon still handles while it is paused. It is a free function and not a method of the protocol enum because it is daemon policy, not wire format. Nothing calls it yet. A unit test lists the four and checks that other messages are refused.
Verified: cargo test -p komorebi-transport: 1 passed, 0 failed (native, tier 1). The tree gates run in the revisions that adopt it.
Adds section 7 (the seven consequences of plan step 7, each with its supporting citations and a status: CONFIRMED, CORRECTED or TARGET; plus three findings the plan did not list: a batch/transaction scope, the workspace methods that exist only on KDE, and error-type differences) and section 8 (everything not confirmed, with how to confirm it on a Mac, a Windows guest or by reading). Verified against the citations of sections 2 to 6 on wip-main aa52fdc4d9e5. Not verified: see section 8.
Adds section 6: event sources per platform and how they reach the window manager (references the step 5 prep entries rather than redoing them) and the evidence for the 'set_rect returns once requested, the frame is observed later' contract: KDE queued commands with an optimistic table write, macOS arrival.rs, settle.rs and animator verification, Windows live_resize settling. Verified against wip-main aa52fdc4d9e5: K/kwin/mod.rs, K/kwin/state.rs, K/window_manager_event_listener.rs, K/backend/mod.rs, M/arrival.rs, M/settle.rs, M/animation/animator.rs, M/window.rs, M/window_manager_event_listener.rs, W/winevent_listener.rs, W/windows_callbacks.rs, W/live_resize.rs. Not verified: any runtime ordering of events.
Adds sections 4 (identity: id types per platform, what acting on a macOS window from a bare id would need, where each tree keeps per-window platform data, HWND width including an observation of 440 distinct HWNDs from the Windows guest logs) and 5 (coordinates: Rect convention, origin and y direction, DPI and scale handling, shadow and frame compensation, and where each conversion lives). Closes two plan items: Windows HWND width and macOS Retina points versus pixels. Verified against wip-main aa52fdc4d9e5: komorebi-layouts/src/rect.rs, W/window.rs, W/windows_api.rs, W/lib.rs, K/kwin/state.rs, K/kwin/bridge.js, M/window.rs, M/application.rs, M/macos_api.rs, M/core_graphics/mod.rs, M/core/rect_ext.rs, M/border_manager/border.rs, M/animation/ghost.rs, M/animation/capture.rs, and ~/e2e-w0 logs read-only for the HWND range. Not verified: HWND width as a Microsoft guarantee, AX values on scaled-resolution or mixed-DPI displays, negative monitor origins on Windows.
Adds section 3.3: the macOS main thread (AppKit and CFRunLoop loop, what runs there), every other thread with its locks, every DispatchQueue::main exec_sync/exec_async/blocking-channel site with file:line and whether the main-side closure takes the window-manager lock, and a precise statement of the possible event-thread/main-thread deadlock, marked by reading, not reproduced. Verified against wip-main aa52fdc4d9e5: M/main.rs, M/macos_api.rs, M/monitor_reconciliator.rs, M/border_manager/{mod,border,ns_window}.rs, M/animation/{animator,ghost}.rs, M/process_event.rs, M/process_command.rs, M/reaper.rs, M/settle.rs, M/workspace_reconciliator.rs, M/window.rs, M/application.rs, dispatch2-0.3.1/src/queue.rs. Not verified: that NSWorkspace and CG display callbacks arrive on main (Apple behaviour), that CFRunLoopAddSource from a non-main thread is safe, that AXUIElement is thread-safe (the code asserts Send+Sync), and the deadlock itself (needs a Mac).
Adds sections 3.1 (KDE) and 3.2 (Windows): every thread that exists, what it locks, and which threads call the platform API. Closes two items the plan listed as unverified: which threads call backend() in KDE (traced: main at start-up and stop, the event thread, command threads, the monitor reconciliator and its settle thread, and tests through with_backend; never the KWin bridge or the hotkey threads) and which threads call WindowsApi, with the thread-affine subset. Verified against wip-main aa52fdc4d9e5: K/main.rs, K/kwin/mod.rs, K/kwin/hotkeys.rs, K/process_event.rs, K/process_command.rs, K/monitor_reconciliator.rs, K/backend/mod.rs, W/main.rs, W/winevent_listener.rs, W/windows_callbacks.rs, W/border_manager, W/stackbar_manager, W/animation, W/live_resize.rs, W/reaper.rs. Not verified: Microsoft's documented behaviour of WINEVENT_OUTOFCONTEXT and cross-thread SetWindowPos, and every Windows call chain (the table lists thread entry points and the API each reaches, not every path).
Adds section 2: the operation table (one row per operation present on at least two platforms: KDE Backend method | Windows | macOS | semantic differences), the platform-subsystem table, and the re-measured counts with the exact method. Verified against wip-main aa52fdc4d9e5: K/backend/mod.rs, K/kwin/mod.rs, W/windows_api.rs, W/window.rs, M/macos_api.rs, M/window.rs, M/core_graphics/mod.rs, M/lib.rs. Not verified: how each AX call behaves against real applications (needs a Mac), and the counts are of source text, not of executed calls.
Creates docs/dev/seam.md with sections 1 (purpose and how to read) and the corrections list. Verified against wip-main aa52fdc4d9e5 by reading K/backend/mod.rs, K/kwin/mod.rs, K/kwin/state.rs, M/macos_api.rs, M/window.rs, M/arrival.rs, M/process_event.rs, M/process_command.rs, W/windows_api.rs. Counts quoted here are measured in the next revision. Not verified: any runtime behaviour (the document is reading-only).
The root flake got the code of komorebi-for-kde and komorebi-for-mac through two locked path inputs (kfde, kfm), so the root flake.lock pinned the content of those directories and needed 'nix flake update kfde kfm' after any edit under them; a stale pin gave 'attribute lib missing'.
Now the root imports komorebi-for-kde/flake.nix and komorebi-for-mac/flake.nix as plain files and calls their outputs/lib.mkOutputs with inputs declared in the root under the names kfde-* and kfm-* (nixpkgs, nixpkgs-lib, flake-compat, flake-parts, crane, rust-overlay, treefmt-nix, git-hooks-nix, and gitignore for kfm), pinned by revision in the URL to exactly the revisions of each nested flake.lock, with the same follows structure. The nested flakes are unchanged and still have their own locks. The kfde and kfm nodes are gone from flake.lock. When a nested flake.lock is bumped, update the revisions of the matching kfde-*/kfm-* inputs by hand.
Verified (tier 2): derivation paths unchanged before and after for kfde fmt, deny, nextest, schema-fresh, the Windows workspace clippy check, kfde-komorebic and kfm-komorebic (aarch64-darwin, eval only); every narHash of the nested locks is present in the root lock; nix flake check --no-build passes on x86_64-linux; nixosModules, overlays, darwinModules evaluate; kfde-vm has 34 suites.
Merge revision: wip-main (history merges, fixes, step 0 path dependencies, step 1 komorebi-collections, KDE A3 fixes, flake phase 2) and wip-step2 (the komorebi-protocol crate, goldens and the unified SocketMessage used by all three trees). Conflicts in the root Cargo.toml members line, the trees' Cargo.toml dependency tables and the Cargo.lock files are resolved in this revision by keeping both sides' additions.
The root flake.lock pins the content of komorebi-for-kde and komorebi-for-mac (D14 of the flake phase 2 work: the root passes its own self to the nested mkOutputs, and the lock records the nested directories). Their trees changed with the step 1 crate and the crates directory in the source filter, so the pins are updated with nix flake update kfde kfm. Only flake.lock changes.
Delete macOS's SocketMessage, as_bytes and FromStr and its now unused imports, and re-export the crate's SocketMessage from core. process_command stays an exhaustive match: the 41 variants macOS does not handle (33 Windows only, 6 Windows and KDE, 2 KDE only) get one explicit or-pattern arm that writes the 'not supported on this platform' reply and returns before anything else happens. Behaviour change: those variants used to fail to parse on macOS and now parse and are answered that way.
Verified: fast-check macOS (fake CC) cargo check --workspace --all-targets: PASS (0 errors, only the existing komorebi-bar warnings). macOS tests not run (cannot).
The nested flakes cut the repository down to their own tree and the root crates they depend on by path (rootCrates). Step 1 added crates/komorebi-collections, which both trees now depend on, so crates/ must be in that list or the root flake cannot build kfde (and kfm cannot evaluate its sources). Listing the directory rather than each crate means later shared crates (protocol, config, ...) are picked up without another flake change. Verified: see the following progress entry.
Two tests against the fake desktop: ForceFocus, StackbarMode and ToggleTitleBars (Windows only) are answered with 'X is not supported on this platform', and a message KDE handles (Retile) is not.
Verified: cargo test -p komorebi --test unsupported_messages in komorebi-for-kde: 2 passed, 0 failed.
Merge revision: wip-main (history merges, fixes, step 0 path dependencies, step 1 komorebi-collections, KDE A3 fixes) and wip-flake (the root flake builds the KDE package with the whole repository as source, the macOS package evaluates the same way, the root flake no longer requires dirtyRev). The root flake.lock pins the content of the nested flakes, so it is relocked in the next revision.
Delete KDE's SocketMessage, as_bytes and FromStr and its now unused imports, and re-export the crate's SocketMessage from core. process_command stays an exhaustive match: the 34 variants KDE does not handle (33 Windows only, plus PanGesture which only Windows and macOS have) get one explicit or-pattern arm that writes the 'not supported on this platform' reply and returns before anything else happens (no notification to subscribers). Behaviour change: those variants used to fail to parse on KDE and now parse and are answered that way. The doctest of SocketMessage lives in the crate now.
Verified: cargo check --workspace --all-targets in komorebi-for-kde: 0 errors, no warnings; cargo test -p komorebi --lib --test schemas --test rule_commands: 302 + 5 + 6 passed, 0 failed; komorebic static-config-schema byte-identical to schema.json. Full workspace run at the end of the stage.
Merge revision on the integration line: wip-step1 (the komorebi-collections crate and its wiring in all three trees, on top of the step 0 path dependencies) and wip-a3-kde (the KDE path-coupling, test-isolation, dirtyRev and lock-order fixes). No file needed manual resolution. Verification of this merge: not run separately; each side passed its own gates (step 1: Windows clippy, KDE 885 tests, macOS type-check; KDE A3: 895 tests three times).
The root flake no longer re-exports the nested flakes' own outputs. It keeps them as inputs for their pinned nixpkgs, crane and rust-overlay (inputs.<name>.inputs), but calls their lib.mkOutputs with the whole repository (self) as the source, a nested self carrying the root rev, dirtyRev and inputs, and the tree's directory, then re-exports packages, checks (without vm-*), legacyPackages.kfde-vm, nixosModules, overlays and darwinModules from those. flake.lock is updated for the changed nested flakes: the lock pins their content, so it needs 'nix flake update kfde kfm' whenever a file under komorebi-for-kde or komorebi-for-mac changes.
Verified (Linux, x86_64): nix build -L of packages.kfde-komorebic and kfde-komorebi succeed and both binaries run with --help (exit 0); checks kfde-schema-fresh, nix-options-validation, keybindings-fixtures, komorebi-bridge-js, nixos-module-eval, plasma-guests-eval, run-kde-dry-run, run-kde-doctor, komorebi-workspace-fmt, -deny and -nextest build; kfde-komorebi-workspace-toml-fmt FAILS because komorebi-for-kde/Cargo.toml itself is not taplo-formatted (same result running taplo on the file directly; not caused by this change). nix eval of aarch64-darwin kfm-komorebic and kfm-komorebi drvPath print .drv paths (evaluated, not built). Windows clippy and default drvPaths are identical to those before this revision. nix flake check --no-build passes for x86_64-linux. Not verified: any darwin build, kfde clippy/doc, the VM suites.
Delete the Windows SocketMessage, its as_bytes and FromStr (now in the crate) and re-export komorebi_protocol::message::SocketMessage from core, so komorebi::SocketMessage and komorebi_client::SocketMessage keep working. process_command stays an exhaustive match: the two KDE-only variants (ReloadHotkeys, HotkeysState) get one explicit arm that writes the 'not supported on this platform' reply (SocketMessage::not_supported_reply) and returns before anything else happens, so subscribers are not notified either. Behaviour change: those two used to fail to parse on Windows and now parse and are answered that way.
Verified: Windows clippy --workspace --locked --all-targets -D warnings clean; native cargo test -p komorebi-protocol passes. Windows unit tests and e2e not run (cannot on Linux).
Deletes the KDE copies, adds the komorebi-collections path dependency via the workspace table, re-exports ring and lockable_sequence from lib.rs, #[macro_use] extern crate for impl_ring_elements!, and forwards the schemars feature. Cargo.lock updated.
Verified: fast-check KDE cargo check, --lib tests and schemas test: PASS.
The e2e core was vendored twice (komorebi/e2e/lib and the KDE VM lib), synced by a script. The script now checks the KDE copy against ../e2e/lib in the root, treating the root as the single source, as the plan's A3 requires. Verified: running the script reports the copies in sync.
A path flake (a jj workspace without .git) has neither rev nor dirtyRev, so the commit stamp default in mkKomorebiPackages failed to evaluate. It now falls back to "unknown", as the nested flakes do.
Verified: nix eval --raw .#checks.x86_64-linux.komorebi-workspace-clippy.drvPath now prints z9nb5j12qlfp1j8d71ykp9qnafk553ra-komorebi-workspace-clippy-0.1.0.drv (it failed before); .#packages.x86_64-linux.default.drvPath is cq0i40300hgsm0ih2llcdjpkcg9sfqaf-komorebi-workspace-0.1.0.drv. Neither was built.
message.rs holds the one SocketMessage with the 197 variants of the three trees: the Windows enum verbatim (195 variants, in its order, with ApplyState(StateBlob) and DebugWindow(i64) as converged in the previous revisions) plus the two KDE-only variants (ReloadHotkeys, HotkeysState) at the end, as_bytes and FromStr. platforms.rs has Platform, Platforms and SocketMessage::platforms(), one exhaustive match generated from tests/golden/variants-table.tsv (155 on all three, 33 Windows only, 6 Windows and KDE, 1 Windows and macOS, 2 KDE only). No tree uses it yet.
The golden test now runs the real enum: every golden instance of each platform is accepted with identical wire text (path-expansion instances only with STRICT_PATHS=1, which is meaningful on the target platform only; ApplyState on Windows by tag), every variant of every platform is in the unified schema and every generated instance round-trips, and platforms() matches each platform's variant list both ways.
Verified: native cargo test -p komorebi-protocol: 5 unit + 6 golden + 2 doctests passed, 0 failed. Not run: STRICT_PATHS=1 (fails on Linux for the Windows goldens by design).
Deletes the macOS copies, adds the komorebi-collections path dependency via the workspace table, re-exports ring and lockable_sequence from lib.rs, #[macro_use] extern crate for impl_ring_elements!, and forwards the schemars feature. Cargo.lock updated.
Verified: fast-check macOS fake-CC cargo check --workspace --all-targets: PASS. Not run: tests.
window.rs and static_config.rs locked the float, manage and other rule lists in conflicting orders, which deadlocked KDE tests and could in the daemon. Both now take the locks in one order. Found by test hangs during the merge work. The Windows and macOS trees have the same pattern by reading and were not changed. Verified: the KDE test suite no longer hangs; the VM tier was not re-run.
Same change as for the KDE flake: lib.mkOutputs takes inputs, self, the repository source and the tree's directory; the crane source is the macOS tree plus komorebi-layouts, -scrolling, -themes and the root Cargo.toml; cargoLock, cargoToml and postUnpack point into the tree. The nested flake's own outputs call it with ./. and keep evaluating, but cannot build the Rust workspace on their own.
Verified: nix eval --raw of packages.aarch64-darwin.komorebic.drvPath on the nested flake prints a .drv (evaluated only; nothing darwin was built).
ApplyState(State) becomes ApplyState(StateBlob) (D15): the handler reads the blob into State with serde_json::from_value and applies it as before. Wire bytes for a valid state are unchanged. Behaviour difference: a state that does not parse used to make the whole message fail to parse at the socket; now it is an error returned by the handler (logged). Nothing in this repository sends ApplyState.
Verified: Windows clippy --workspace --locked --all-targets -D warnings clean.
Moves the identical ring.rs and lockable_sequence.rs out of komorebi/src into the crate (rename). Necessary edits: lib.rs with pub use Lockable and a hidden pastey re-export; #[macro_export] on impl_ring_elements! using $crate::pastey::paste!; the doc test now says komorebi_collections::ring::Ring. The Windows tree gets the path dependency, re-exports (pub use komorebi_collections::{ring, lockable_sequence, Lockable}, #[macro_use] extern crate), forwards its schemars feature, and drops pastey again. Windows is bundled here because it is the tree the files move out of.
Verified: fast-check native, Windows clippy --all-targets -D warnings, KDE and macOS checks: PASS.
A path-input flake has no dirtyRev attribute, so evaluation failed. Falls back to "unknown" via self.dirtyRev or. An earlier same-derivation comparison was a false positive because both sides printed the same error; this fix came from retracting it. Verified: the KDE package evaluates and builds from the root flake.
The KDE flake's outputs become a function (lib.mkOutputs) of inputs, self, the repository source and the tree's directory in it. The flake's own outputs still call it with ./. and no directory, so everything evaluates standalone, but the Rust workspace can no longer be built from the nested flake alone: since step 0 it depends on ../komorebi-layouts, -scrolling and -themes, which a nested path input cannot see.
The crane source is now the repository cut down to the KDE tree, those three root crates and the root Cargo.toml (their inherited workspace dependencies come from it). cargoLock and cargoToml point into the tree and postUnpack enters it.
Verified: nix eval of packages.x86_64-linux.komorebic.drvPath on the nested flake prints a .drv; the real build is verified through the root flake (see the revision that wires it). Reindentation by nixfmt makes the diff large; the logic change is the mkOutputs wrapper, the src filter and three commonArgs attributes.
A transparent wrapper of serde_json::Value with a hand written schema (an object, named State), so that SocketMessage can carry ApplyState without the crate knowing the daemon's State type (D15/D16). On the wire it is exactly the state JSON.
Verified: native cargo test -p komorebi-protocol: 5 unit + 3 golden + 1 doctest passed, 0 failed.
New crates/komorebi-collections (edition 2024; deps pastey, serde, optional schemars feature, dev serde_json_lenient) added to the root workspace members, with an empty lib.rs. Cargo.lock for this revision alone is not refreshed (it is in the next revision).
Verified: cargo test -p komorebi-collections --offline built (0 tests yet).
Tests in komorebi/tests/schemas.rs shared one socket path and raced when run in parallel. Each test now gets its own. Verified: cargo test --workspace in the KDE tree.
Empty merge revision joining the step 0 line (path dependencies on the root layouts, scrolling and themes crates) with the KDE A3 line (path-coupling fixes). No file changes of its own, so each parent's content is kept as written. Verified: all three trees type-check on the combined line.
DebugWindow(i64) as in the unified SocketMessage (D15); the comparison with the accessibility window id widens the u32 side, so behaviour for valid ids is unchanged (a negative or oversized id now parses and matches no window).
Verified: fast-check macOS (fake CC) cargo check --workspace --all-targets: PASS.
macOS ring.rs becomes the KDE copy (doc comments, unit tests, std path in the macro; pastey was already used). After this the three ring.rs and lockable_sequence.rs files are byte-identical (cmp).
Verified: fast-check macOS fake-CC cargo check --workspace --all-targets: PASS. Not run: tests (macOS cannot run).
compare-gen.py defaulted to sibling checkouts of the old repos. It now defaults to the Windows tree and macOS tree that sit beside komorebi-for-kde/ in this repository. Verified: runs and finds both trees.
Step 0. KDE depended on komorebi-layouts and komorebi-themes through git revisions (6d862a11 / e8216924) that exist in no komorebi history. It now uses the path crates in the repository root so one copy is built. Cargo.lock is updated. Verified: cargo check --workspace --locked in the KDE tree.