Commit Graph
642 Commits
Author SHA1 Message Date
LGUG2Z f4715a3465 feat(e2e-agent): the macOS verbs on the shared protocol, in the one agent crate
Move the macOS agent into komorebi-e2e-agent as macos.rs, answering the protocol of protocol.rs
with its own verbs (os_windows, displays, activate, minimize, close, move; a window is found by
its title), and remove the separate komorebi-macos-e2e crate that had copied the protocol. There
is one binary name and one port on every platform, so the host has one client and one description
of the protocol.

AppKit is for the main thread, so the macOS agent serves one connection at a time on it, where
the Windows one serves each on a thread. A spawned program on macOS gets a standard input that
stays open, as the test window leaves when its input closes. The crate is built for macOS and
Windows now and stubbed on Linux, as komorebi-testwin is.
2026-11-06 14:40:49 -08:00
LGUG2Z 6ed535be38 feat(testwin): a window for macOS, on the same command line and commands
An AppKit window of a regular application, so that the daemon sees it as it sees any program: the
same options and standard input commands as the Win32 one (title, colour, size, minimum size,
fixed, late rename, fullscreen as a borderless window over its display, report with the frame in
points from the top left of the main display, close, exit). The main thread runs the event loop
in short turns and takes the lines the input thread queued; the program leaves when its window is
closed. A window class has no meaning on macOS, so --class is accepted and ignored.

The macOS source set now builds the crate; Linux still stubs it.
2026-11-06 14:40:49 -08:00
LGUG2Z 6b8ab7d959 feat(e2e): a guest agent for macOS that answers the host and describes windows
The Windows guest has komorebi-e2e-agent; this is its macOS counterpart, speaking the same
protocol (one JSON line per request, raw bytes after it for put_file and get_file) so that the
host client is the same. Beyond exec, spawn and file transfer it answers with the windows the
accessibility API gives (title, frame, focus, minimized) and the displays with their work areas,
and it can activate, minimize, close and move a window.

It has to be started by a program that holds the Accessibility and Screen Recording grants, so
that the daemon it spawns is attributed to that program.
2026-11-06 14:40:49 -08:00
LGUG2Z 8e1a2b261c refactor(macos): the animation maths, the arrival record and the enhanced-UI rules move into komorebi-macos-core, which needs no macOS 2026-11-05 15:51:50 -08:00
LGUG2Z 622646c3f7 build(workspace): schemars-nixgen is a member of the workspace, not a default member
It is a development tool: a bare cargo build leaves it out, publish is off, and no release
ships it. Its manifest uses the workspace dependencies it shares and keeps its own version.
2026-11-05 15:03:27 -08:00
LGUG2Z c64c71541b build(workspace): komorebi-recorder is a member of the workspace, at 0.1.0-dev 2026-11-05 15:03:27 -08:00
LGUG2Z ae4e7af9f4 chore(repo): the workspace version is 0.2.0-dev
The unified line starts the 0.2.0 development cycle and is not released yet, so the one
workspace version (every package takes it through version.workspace = true) is the
pre-release 0.2.0-dev instead of 0.2.0. The release revision sets it to 0.2.0.

Cargo.lock only changes the version of the workspace's own packages. The schema
descriptions and the macOS schema links keep naming v0.2.0: they document the schema of
the release this line leads to. The update widget of the bar compares version strings, so
a dev build never offers the 0.1.x releases as an update.

Verified: cargo metadata --offline succeeds; cargo test -p komorebi --test linux_version
passes; komorebic --version prints 0.2.0-dev. The other gates were not re-run for this
one-line change.
2026-11-05 15:03:27 -08:00
LGUG2Z 170952596f refactor(repo): delete the shim packages
komorebic-linux, komorebi-client-linux, komorebic-macos, komorebi-client-macos and
komorebi-bar-macos were #[path] includes of the unified komorebic, komorebi-client and
komorebi-bar modules, kept only so the old package names kept building. The unified
packages are the only ones now, so the five directories and their workspace members are
gone (Cargo.lock loses their dependency entries).

Things that named the old packages follow: the clarify entries of the two per-tree
deny.toml files, tools/fast-check, tools/mac-check.sh and tools/kde-closure-check (it now
walks komorebic and komorebi-client), and the doc comment of komorebic/src/main.rs.
komorebi-for-kde/nix/root-crates.json gains komorebic, komorebi-client and
crates/komorebi-version, because those are root crates the KDE build depends on now.
komorebi-for-mac/komorebi/src/pan.rs read its transcripts from the deleted
komorebic/fixtures; they are byte-identical to the root komorebic/fixtures, so the three
paths point there.

Not touched here (done in the flake and justfile revisions of this stack): the nix
flakes and justfiles of the trees, which still name the removed packages, and docs/dev.

Verified: Windows cargo clippy --locked --all-targets -D warnings (default members) passes;
KDE cargo test -p komorebi -p komorebic -p komorebi-client -p komorebi-linux passes; macOS
cargo check --target aarch64-apple-darwin (fake CC) of komorebi, komorebi-macos, komorebic,
komorebi-client, komorebi-bar passes; tools/kde-closure-check passes. The nix flakes were
not run.
2026-11-05 15:03:27 -08:00
LGUG2Z cce2886622 refactor(version): one komorebi-version crate for Linux and macOS
version-linux (komorebi-for-kde/version, shadow-rs 2) and version-macos
(komorebi-for-mac/version, shadow-rs 1) had the same build.rs and the same lib.rs. They
are now one package, crates/komorebi-version (lib name version, shadow-rs from the
workspace), and the KDE and macOS daemons, their command lines and the unified komorebic
depend on it under the key version. The extern crate lines of komorebic/src/main.rs that
renamed the two crates are gone, and the two deny.toml clarify entries name the new
package.

komorebi-daemon/tests/linux_version.rs read the version out of the old crate's Cargo.toml
text, which no longer has a number (it is inherited); it now expects the package version,
which is the workspace version.

Verified: cargo test -p komorebi -p komorebic -p komorebi-client -p komorebi-linux (KDE
side, native Linux) all pass, including the version test; cargo check --target
aarch64-apple-darwin of the macOS packages with the fake C compiler passes. Windows and
nix were not run for this revision (Windows does not use the crate; nix runs at the end of
the stack).
2026-11-05 15:03:27 -08:00
LGUG2Z 87fb8340d0 chore(repo): one workspace version, 0.2.0
Every package of the workspace now takes its version from [workspace.package]
(version.workspace = true) instead of its own number. The numbers before were
0.1.42 (Windows libraries and packages), 0.1.0 (KDE, the macOS version crate,
komorebi-shortcuts and the e2e guest crates) and 0.1.1 (macOS libraries); the
unified release is 0.2.0 for all of them.

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

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

Verified: cargo metadata --offline --locked succeeds.
2026-11-05 15:03:27 -08:00
LGUG2Z fab53bd1f8 refactor(core,kde,mac): the unmanaged-window gate of the router is the CommandHost::gate_message hook
Section 22.1 of core-model.md: KDE and macOS refuse every message before
the router's match while the focused window is not managed
(handle_unmanaged_window_behaviour); Windows gates inside 18 functions.
CommandHost gets a defaulted gate_message(&mut self, &SocketMessage)
that lets everything through (the Windows form, its impl is untouched);
the KDE and macOS impls call handle_unmanaged_window_behaviour and their
routers call the hook where they called the method, so behaviour is
identical per daemon. komorebi-core now depends on komorebi-protocol
(for SocketMessage; Cargo.lock gains that one edge).

This is the groundwork only: the router itself is still per daemon,
because a shared router needs WindowManager<P> in core (see the
struct-move analysis in core-model.md). No BEHAVIOUR change.
Verified: KDE cargo test -p komorebi-linux 670 passed, 0 failed; fake-CC
clippy -D warnings for the four macOS packages passes; cargo clippy -p
komorebi-windows -p komorebi-core --all-targets -D warnings passes;
tools/format-all --check clean. Not verified: KDE VM, macOS hand check
(no behaviour change expected).
2026-11-05 15:03:27 -08:00
LGUG2Z c424c03e34 build(bar): enable eframe's wgpu feature for the Windows bar
komorebi-bar gets a second renderer, wgpu, for machines without OpenGL 2.0
(the Windows e2e guest is one: egui_glow refuses its generic OpenGL 1.1).
wgpu draws through Direct3D 12 on Windows, which has the software adapter
WARP, so it needs no driver. The feature is on only in the
`[target.cfg(windows)]` table of komorebi-bar, so the macOS bar and the
shared bar-core are untouched and nothing here compiles for them.

Cargo.lock gains exactly one entry, `pollster` 0.4.0 (eframe's optional
block_on helper) and two dependency lines of eframe and nothing else: the
wgpu stack (wgpu 27, naga, wgpu-hal, egui-wgpu, ash, gpu-allocator ...) was
already locked as optional dependencies. pollster was not in the offline
registry, so `cargo metadata` fetched it from crates.io; no other version
changed.

Cost measured with `cargo tree -e normal --target x86_64-pc-windows-msvc -p
komorebi-bar`: 622 -> 664 distinct crate versions (+42) for the Windows bar.
With both features compiled, eframe's default renderer becomes Wgpu, so the
next revision names the renderer explicitly.

Verified: lock diff reviewed; not built yet (the next revision builds).
2026-11-05 15:03:26 -08:00
LGUG2Z b3bcf4a2c3 refactor(config): add the shared window-rule matching
komorebi_config::rules holds should_act and should_act_individual, the
evaluation of MatchingRule/MatchingStrategy against a window
(RuleSubject: title, exe_name, classes, path). The body is the KDE/macOS
copy moved verbatim; the single difference of the Windows copy (a rule id
is compared as written, no `.exe` stripping) is RuleQuirks::WINDOWS vs
RuleQuirks::UNIX, and Windows' single class is a one-element slice. The
regex cache is passed in (the daemons keep REGEX_IDENTIFIERS and its lock
order). regex 1 becomes a dependency of komorebi-config (already in the
lock; one Cargo.lock line).

Nothing calls it yet, so no daemon behaviour changes. Verified: cargo
clippy -p komorebi-config --all-targets -D warnings, fmt check.
2026-11-05 15:03:26 -08:00
LGUG2Z 7330c8e8ec refactor(daemon): one komorebi package and binary, the daemon of each platform is a library
Step 8 (Option A of docs/dev/unified-binaries.md). The main.rs of komorebi-windows, komorebi-linux and
komorebi-macos becomes daemon.rs of the library (pub fn run; komorebi:: paths are crate:: paths now, the
inner attributes and the unit tests move with it), and their [[bin]] is gone, so each is a library only.
The new package komorebi (komorebi-daemon/, version 0.1.42) is the one binary: its main calls
komorebi_windows::daemon::run, komorebi_linux::daemon::run or komorebi_macos::daemon::run by cfg_select! on
the target OS, through target-gated dependencies (one key per library, cargo allows one path per key),
and forwards the features deadlock_detection and schemars. The binary name komorebi now comes from exactly
one package. The four KDE integration tests that run the binary (no_kwin, socket, hot_reload, version)
move to komorebi-daemon/tests/linux_*.rs; the version test compares with the KDE version crate, since
the package version is now shared. Old names: komorebi-windows, komorebi-linux and komorebi-macos still
build, as libraries (no binary any more: use -p komorebi). The flakes build -p komorebi with the KDE and
macOS packages, the source filters take komorebi-daemon (manifest, main.rs, linux tests), the Windows
filter leaves its linux tests out, deny.toml clarify entries gain komorebi, the release workflow's cargo wix
and the justfile version lookup name komorebi, tools/fast-check checks -p komorebi on KDE and macOS.
Behaviour: the same code runs, the same binary name; the Windows executable is rebuilt from the library
(BEHAVIOUR for the e2e gate: the Windows e2e must run).

Gates run: Windows clippy --all-targets -D warnings PASS; KDE check; macOS fake-CC check of -p komorebi
-p komorebi-macos PASS (type check only); KDE cargo test -p komorebi -p komorebi-linux -p komorebic -p
komorebi-client -p komorebi-hotkeys -p komorebi-core: 903 passed, 0 failed (the four moved tests and the
unit test of daemon.rs included); CLI docs oracle identical x3; bar schema harness identical both bars;
kde-closure-check ok; nix evaluation of the root and both nested flakes PASS; by evaluation an edit of
komorebi/src/daemon.rs changes the Windows derivations only, of the KDE daemon.rs kfde only, of the macOS
one neither (the shared komorebi-daemon/src/main.rs changes all, as expected). Not run: nix builds, VM,
e2e, any Mac run.
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 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 2429e3d5fa refactor(windows): take the default constants from komorebi-settings
DEFAULT_RESIZE_DELTA, DEFAULT_MOUSE_FOLLOWS_FOCUS and the initial values of
DEFAULT_WORKSPACE_PADDING and DEFAULT_CONTAINER_PADDING now come from
komorebi_settings::shared (PlatformDefaults::WINDOWS: 10, 10; 50; true); the
statics keep their names and types, so no reader changes. Adds the
komorebi-settings dependency edge to komorebi-windows (Cargo.lock edge only;
the crate is already a workspace member). Plan step 10, S1. Pure refactor.

Verified: Windows clippy -D warnings --all-targets on komorebi-windows
(dev shell, cross, target-fast-win): clean. e2e not run; tools/e2e-needed
will report the crate as an input of komorebi.exe, behaviour is unchanged.
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 f225e51982 feat(core): Workspace<P> with the shared half of workspace.rs
komorebi-core gets Workspace<P: WorkspacePlatform>, moved from
komorebi-for-kde/komorebi/src/workspace.rs (KDE is the base), together
with WorkspaceLayer, WorkspaceWindowLocation, CachedLayoutDefault and the
two threshold helpers, and these 52 functions of its impl, whose text is
the same on both daemons (add_container_to_back/front, the container
focus and removal family, insert_container_at_idx, swap_containers,
preselect and monocle operations, new_container_for_window and
resolve_placement_index, location_from_exe, visible_windows, the
enforce_resize_* family, the window lookups, remove_floating_window and
the floating focus helpers, is_scrolling). They are generic over
P::Window (Container<P::Window>, PlatformWindowId<P>), and every private
function is pub so the daemons' own methods can call it. The accessors
the impl_ring_elements! macro made are written out.

WorkspacePlatform is the hook trait: Window (a WorkspaceWindow), State
(what only a platform keeps in a workspace; skipped in the JSON and the
schema), default_padding, foreground_window_id, cursor_position,
should_act_window and should_act_window_individual (the platform holds
the compiled regexes), the three scrolling lookups and
after_floating_removed (KDE refocuses a floating window). Default for
Workspace<P> is the KDE one with the padding from the hook. serde and
schemars bounds are on P::Window; the schema is named Workspace.

Not used by any daemon yet; the next revisions make each daemon use it.
Four tests with a stub platform cover new_container_for_window, the
focus, the JSON keys and the default.

Verified: cargo test -p komorebi-core --features schemars (native): 20
passed, 0 failed; Windows clippy --workspace --locked --all-targets
-D warnings: PASS (compiles the crate). Not run: the daemons.
2026-10-31 12:50:34 -07:00
LGUG2Z 7d4ea893cc refactor(bar): one komorebi-bar package with a module per platform
The macOS bar module moves from komorebi-for-mac/komorebi-bar/src/macos to komorebi-bar/src/macos (the
include_str! path follows), komorebi-bar/src/main.rs is a cfg_select! over target_os that runs
windows::main or macos::main, and komorebi-bar/Cargo.toml has what both share in [dependencies] and the
rest in per-target tables (Windows: windows, windows-core, windows-icons x2, systray-util, tokio, regex,
which, egui_extras, netdev 0.46, sysinfo 0.39, komorebi-themes without default features; macOS: objc2,
objc2-app-kit, icns, raw-window-handle, netdev 0.40, sysinfo 0.38, komorebi-themes with defaults), so each
platform keeps the versions it had. The old komorebi-bar-macos package stays as a shim that includes the
moved module. The macOS flake builds -p komorebi-bar and its source filter takes the unified package's
manifest, main.rs and src/macos; the Windows filter leaves src/macos out. The bar does not build for
Linux (no arm of the cfg_select), as before.

Gates run: Windows clippy --all-targets -D warnings PASS; macOS fake-CC check --locked --all-targets of
-p komorebi-bar and -p komorebi-bar-macos PASS (type check only); bar-core schema oracle (3 + 6) PASS; the
S/bar2 harness regenerates schema.bar.json for Windows (9091 lines) and macOS (3774) byte-identical to the
checked-in files; tools/kde-closure-check ok; CLI docs oracle identical x3; nix evaluation PASS and by
evaluation an edit of komorebi-bar/src/windows changes the Windows derivations only (the macOS side cannot
be evaluated on this Linux host). Not run: nix builds, any bar run (Windows screenshot gate and the Mac
hand check are owed).
2026-10-31 12:45:25 -07:00
LGUG2Z b558acbe17 refactor(bar): the macOS bar uses the unified komorebi-client
komorebi-for-mac/komorebi-bar depends on komorebi-client (the one package, path ../../komorebi-client)
instead of komorebi-client-macos; same module, same API. Cargo.lock only rewires that edge.
Gates: macOS fake-CC check of komorebi-bar-macos --locked --all-targets PASS (type check only); bar-core
schema oracle (cargo test -p komorebi-bar-core: 3 unit + 6 oracle) PASS. Not run: any bar run.
2026-10-31 12:38:51 -07:00
LGUG2Z 19162f3367 refactor(client): one komorebi-client package that re-exports the daemon of the target OS
The root komorebi-client package (0.1.42) is the one client: src/lib.rs is a cfg_select! over target_os
that re-exports the module of the platform. The three lib.rs files move to komorebi-client/src/{windows,
linux,macos}.rs (they were made equal in socket code by the previous revision), the KDE integration tests to
tests/linux_{daemon,subscribe}.rs (#![cfg(target_os = "linux")]). The daemon crate of each platform has a
dependency key of its own (cargo allows one path per key) and the module names it (use crate::komorebi_linux
as komorebi). The old komorebi-client-linux and komorebi-client-macos packages stay as shims that include
the moved module, so the old names build until the cutover (the macOS bar and komorebic-macos still use
them). komorebic now depends on the one komorebi-client on all three platforms. The KDE and macOS flakes
build the unified client (-p komorebi-client) and take its manifest, lib.rs and their module in the source
filter; the Windows filter leaves the other platforms' modules and tests out. Windows API for komorebi-bar,
komorebi-gui and komorebic is unchanged.

Gates run: Windows clippy --all-targets -D warnings PASS (client, bar, gui, komorebic); KDE cargo test -p
komorebi-client -p komorebi-client-linux -p komorebic -p komorebi-linux: 775 passed 0 failed (the client
tests and doctests included); cargo check of komorebic-linux and komorebi-client-linux PASS; macOS fake-CC
check --locked of komorebi-client, komorebic, komorebi-client-macos, komorebi-bar-macos, komorebic-macos
--all-targets PASS (type check only); CLI docs oracle byte-identical x3; nix evaluation PASS; by evaluation an
edit of komorebi-client/src/windows.rs changes only Windows derivations, linux.rs only kfde, macos.rs
neither. Not run: nix builds, the e2e (komorebi-client is in the closure of komorebi.exe's users: Windows e2e
OWED), any macOS link or run.
2026-10-31 12:34:59 -07:00
LGUG2Z 88afd37d36 feat(core): WorkspaceGlobals moves into komorebi-core
The plain data a monitor gives the workspaces it shows (padding, border
width and offset, work area, offsets, floating layer behaviour), moved
from komorebi-for-kde/komorebi/src/workspace.rs (the Windows struct is
the same nine fields with the same derives) into komorebi-core, with the
KDE doc comments and two unit tests. komorebi-core now depends on
komorebi-config (for FloatingLayerBehaviour, default features off) and
komorebi-layouts (for Rect); its schemars feature enables theirs. The
struct derives JsonSchema under the feature, as Windows' did; a workspace
skips the field when serialised and in its schema, so no schema changes.

No daemon uses it yet: the next two revisions converge KDE and Windows.

Verified: cargo test -p komorebi-core --features schemars (native): 15
passed, 0 failed. Not run: the daemons.
2026-10-31 12:14:35 -07:00
LGUG2Z a72b25dc89 refactor(komorebic): one komorebic package that builds the CLI of the target OS
The root komorebic package (version 0.1.42) is now the one komorebic: src/main.rs is a cfg_select! over
target_os that runs the CLI module of the platform. The Windows main is moved to src/windows.rs
(pub fn main); the Linux and macOS CLIs are included from where they live
(#[path = "../../komorebi-for-kde/komorebic/src/main.rs"], likewise macOS), so no file moves yet and
the old komorebic-linux and komorebic-macos packages still build from the same files. Dependencies are
in per-target tables; cargo allows one path per dependency key, so the Linux and macOS crates keep
their renamed keys and main.rs aliases them (extern crate komorebi_client_linux as komorebi_client).
The unified package needs no reqwest build dependency (committed applications.json) so it builds
natively on Linux without openssl. hotkeys.rs: crate::HOME_DIR -> super::HOME_DIR (same crate root in
the old package).

Gates run: Windows clippy --all-targets -D warnings PASS; KDE check + 294 lib + 5 schemas (old package)
PASS; macOS fake-CC check of -p komorebic --target aarch64-apple-darwin --locked --all-targets PASS (type
check only); native Linux cargo check/build of -p komorebic PASS and its docgen output is byte-identical
to the KDE oracle (166 pages, diff 0); CLI docs oracle byte-identical for windows, macos, kde
(S/step4/regen.sh reads komorebic/src/windows.rs now); nix eval of komorebic and the kfde packages OK.
Not run: nix builds, e2e (komorebic.exe inputs changed: Windows e2e gate OWED), any macOS link or run
(the user must check on a Mac: komorebic --help, --version, start, stop, state, docgen output).
2026-10-31 12:09:39 -07:00
LGUG2Z 03072f4fdb build(workspace): merge the KDE and macOS crates into the root workspace
komorebi-for-kde/*, komorebi-for-mac/* crates become members of the root Cargo workspace: one
Cargo.lock (901 packages; the 859 Windows entries are unchanged, checked by name and version), the
two nested [workspace] manifests and lock files are deleted, their inherited dependencies are written
out per crate (script S/pkg-merge.py), KDE's .cargo/config.toml (COMMIT_HASH default) moves to the
root .cargo/config.toml (non-forcing, nix still wins). default-members is the Windows set, so a bare
cargo command (and crane, which passes no --workspace) builds only Windows crates; the KDE and macOS
crates are selected with -p. Crates only KDE used were re-resolved newer by cargo; pinned back to the
KDE lock (zbus, zbus_macros 6.1.0, zbus_utils 6.0.0, zruntime 0.2.1, sysinfo 0.40.0). Two small
differences remain: unicode-width 0.2.2 (KDE locked 0.2.3) and libz-sys 1.1.31 (macOS locked 1.1.30).

The root flake and the two nested flakes still read the old workspaces and do not evaluate at this
revision: they are fixed in the next one, which must land with this one (nix cannot be half-merged).
Not behaviour.

Gates run: Windows clippy --all-targets -D warnings (default-members) PASS; KDE check + 294 lib + 5
schemas PASS from the root workspace; macOS fake-CC check of the four macOS packages --locked PASS.
Not run: nix (broken until the next revision), VM, e2e. tools/fast-check now detects the merged
layout.
2026-10-31 11:51:10 -07:00
LGUG2Z 660e67b707 refactor(pkg): rename the Windows daemon package to komorebi-windows
The package name komorebi is needed for the single komorebi binary package (Option A of
docs/dev/unified-binaries.md). The daemon library becomes komorebi-windows with [lib] name and
[[bin]] name unchanged (komorebi); komorebi-client uses package = ...; the version lookup in the
justfile and cargo wix -p in the release workflow follow. Cargo.lock only renames one entry (checked).
Not behaviour: same sources, same binary name.

Gates run: fast-check --since base: Windows clippy PASS, KDE and macOS PASS, nix eval PASS.
tools/e2e-needed lists the e2e binaries as affected (the closure crate's manifest changed), so the
Windows e2e gate is OWED by the coordinator; the produced komorebi.exe should be unchanged code. Not
run: nix builds, e2e.
2026-10-31 11:51:10 -07:00
LGUG2Z 375571d063 refactor(windows): the container is komorebi-core's Container over the Windows Window
BEHAVIOUR (Windows runtime): not verified on a machine; see below.

komorebi/src/container.rs is now `type Container =
komorebi_core::Container<Window>` plus the ContainerWindow impl for the
Windows Window (id is the hwnd, exe_name is Window::exe().ok(), hide and
restore are backend().hide / .restore exactly as the container called
them, and the stacked pair is hide_with_border(false) /
restore_with_border(false) as load_focused_window used). hwnd_from_exe,
which only Windows has, is the ContainerExt trait that workspace.rs
imports. The container's operations, their order and the serialised form
are the ones in the crate (Container.locked keeps its serde default, and
the schemars schema is still named Container). The generic container
tests moved into komorebi-core; the JSON pin and the deserialize tests
stay here. komorebi-core is a path dependency, with its schemars feature
under komorebi's.

Why BEHAVIOUR: the container is the type of every container in the
state JSON and the code of every stack and tile operation, and I could
not run it. By construction the calls are the same, in the same order.
Windows e2e scenarios needed: the tiled, stack and float state
scenarios whose fixtures are e2e/lib/tests/fixtures/kfw-{tiled,stack,
float}.json (komorebic state must be byte-identical), stack/unstack and
cycle-stack commands, a stack on a monitor move, monocle and
move-to-workspace of a stacked container, and the schema check
(schema.json unchanged).

Verified: tools/fast-check windows step = nix develop cargo clippy
--workspace --locked --all-targets -D warnings: PASS (komorebi tests
compiled, not run); komorebi-core tests PASS (native); macOS fake-CC
type-check PASS (it does not use the crate). Not verified: any run of the
Windows tests or daemon.
2026-10-31 11:36:54 -07:00
LGUG2Z caf24494a7 feat(core): komorebi-core with Container generic over the platform window
New crate crates/komorebi-core, a member of the root workspace (KDE and
macOS take it by path when they adopt it). It holds Container<W>, moved
from komorebi-for-kde/komorebi/src/container.rs (KDE is the base) and
made generic: W is any type that implements ContainerWindow, a small
trait for what the container asks of a platform window (its id, the
executable name, hide and restore, and the hide and restore that
load_focused_window uses, which on Windows leave the border alone).
Container keeps no Backend calls; hiding and restoring is the window's
own business.

The serialised form is unchanged: id, locked (which may be missing when
read, as on Windows), windows with elements and focused. The schemars
schema of Container<W> is named Container whatever W is
(schemars(rename)), so schema.json keeps its definition name; a test
checks it. The tests of container.rs that need no daemon moved with it,
over a stub window, plus tests for the JSON, the hide/restore calls and
the missing locked field.

No daemon uses it yet: the next revisions converge KDE and Windows.

Verified: cargo test -p komorebi-core --features schemars (native):
13 passed, 0 failed. Not run: Windows, KDE, macOS builds (nothing
depends on the crate yet).
2026-10-31 11:36:54 -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 1fb5e74fe3 feat(settings): add komorebi-settings with the snapshot handle
New crate crates/komorebi-settings (workspace member, Cargo.lock +1
package, no new third-party dependency). Settings<P> is a shared part and a
platform part P; Handle<P> holds the current value as an Arc that readers
snapshot once per unit of work and writers replace through update (writers
serialised, one publish, nothing published if the edit panics). Handle::scoped
sets one field and restores the previous value on drop only if the field
still holds the value it set, replacing the save-and-restore store pairs in
the daemons (Windows WINDOW_HANDLING_BEHAVIOUR, KDE ANIMATION_ENABLED_GLOBAL).
Shared starts with the border and the per-platform defaults; the rest follows
in the next revision. See docs/dev/settings.md.

No daemon uses the crate yet.

Verified: native cargo test -p komorebi-settings: 9 passed (snapshot
isolation, concurrent updates lose nothing, no torn reads under a writer,
scoped restore and 'change made meanwhile wins'); clippy clean for the crate.
komorebi-config warns about an unused import when built without its schemars
feature (not touched here). KDE, macOS and Windows trees not touched.
2026-10-31 11:25:28 -07:00
LGUG2Z ef89899bd9 refactor(bar-core): move config.rs (KomobarConfig and the mouse options) into the core
The (now identical) config.rs of both bars becomes
crates/komorebi-bar-core/src/config/komobar.rs; each shell config.rs is one
line, `pub use komorebi_bar_core::config::*;`. Import edits only: statics
from crate::statics, PathExt/SocketMessage from komorebi-protocol, Rect from
komorebi-layouts, the platform hooks and WidgetConfig as in the core. The
core gains komorebi-themes (KomobarTheme, Colour; schemars forwarded): one
line in each Cargo.lock. About 590 lines per bar are gone.

Because the configuration types are now all in the core, the oracle test
regenerates the macOS schema natively: the macOS view of
`schema_for!(KomobarConfig)` is byte-identical to
komorebi-for-mac/schema.bar.json (new test `generated`). Windows is still
compared by the out-of-tree harness: three descriptions in komorebi-protocol
and komorebi-themes read differently when compiled for Windows, which a
Linux test cannot do.

Verified: native bar-core tests 3 unit + 6 oracle (incl. the generated macOS
view); schema harness macOS and Windows byte-identical (3,774 / 9,091
lines); Windows clippy -D warnings --locked clean; macOS fake-CC check
--locked 0 errors (core files touched first). Not run: the bars.
2026-10-31 10:54:51 -07:00
LGUG2Z c2e6b01f89 refactor(bar-core): move the komorebi widget config types and KomorebiLayout into the core
The seven Komorebi*Config structs (komorebi.rs) and the KomorebiLayout enum
with its hand-written Deserialize and Display (komorebi_layout.rs) are data:
they move to crates/komorebi-bar-core/src/widgets/komorebi_config.rs, which
needs komorebi-layouts (DefaultLayout; schemars forwarded) and color-eyre
in the core: two lines in each Cargo.lock. The two shells re-export them.
The inherent impl of KomorebiLayout (is_default, on_click, show_icon, show,
the egui painting) cannot stay an inherent impl of a foreign type: it
becomes the extension trait `KomorebiLayoutExt` in each shell with the same
bodies; komorebi.rs imports the trait. Because the types are no longer in
the shell file, the two komorebi_layout.rs differ no more than the Windows
one; the macOS widget files keep their own komorebi.rs runtime.

Verified: schema harness macOS and Windows byte-identical (3,774 / 9,091
lines); native bar-core tests 3+5; Windows clippy -D warnings --locked
clean; macOS fake-CC check --locked 0 errors (core files touched first). I
reverted a stray `cargo fmt --all` that had reformatted unrelated files.
Not run: the bars.
2026-10-31 10:47:01 -07:00
LGUG2Z e1820d9bbe refactor(bar-core): move the config types of the Keyboard, Media and Systray widgets into the core
KeyboardConfig, MediaConfig, SystrayConfig, OverflowTogglePosition,
ButtonPosition, FieldMatch and HiddenIconRule (pure data: serde and schemars
derives, no platform code) move from the Windows widget files to
crates/komorebi-bar-core/src/widgets/platform_config.rs, so that the next
revision can give WidgetConfig a variant for every widget. The Windows
widget files re-export them (`pub use`), so no other file changes; the
runtime halves (Win32, systray_util) stay in komorebi-bar. The core gains the
komorebi-config dependency (for MatchingStrategy; the schemars feature now
forwards to komorebi-config and komorebi-protocol); one line in each
Cargo.lock. Nothing on macOS refers to the types yet, so the macOS schema
cannot change. The schema harness (out of tree) no longer slices systray.rs
by line number.

Verified: schema harness macOS and Windows byte-identical (3,774 / 9,091
lines); native bar-core tests 3+5; Windows clippy -D warnings --locked
clean; macOS fake-CC check --locked 0 errors. Not run: the bars.
2026-10-31 10:42:45 -07:00
LGUG2Z a290449763 refactor(bar-core): move the applications widget into komorebi-bar-core
Move of the (now byte-identical) applications.rs of both bars to
crates/komorebi-bar-core/src/widgets/applications.rs. Edits: `PathExt` comes
from komorebi_protocol::pathext (what komorebi_client re-exports; it picks
%VAR% handling by target_os), `ImageIcon` from widgets::icons. The core
gains the komorebi-protocol (default features off) and tracing dependencies:
two lines in each Cargo.lock. Both bars re-export the module. 409 lines per
bar are gone. The schema harness now builds a copy of the core next to its
copy of komorebi-protocol (out of tree).

Verified: schema harness macOS and Windows byte-identical (3,774 / 9,091
lines); native bar-core tests 3+5; Windows clippy -D warnings --locked
clean; macOS fake-CC check --locked 0 errors. Not run: the bars.
2026-10-31 10:40:07 -07:00
LGUG2Z 0c197e8652 refactor(bar-core): move ImageIcon, ImageIconId and the icons cache into the core
The icon cache (IconsCache, ICONS_CACHE, ImageIcon, ImageIconId,
rgba_to_color_image) was in widgets/mod.rs of both bars with two small
differences: Windows has `Hwnd(isize)`, `SystrayIcon(String)` and `remove`,
macOS has `WindowId(u32)` and a private rgba_to_color_image. The core file
is the Windows one with the macOS variant and `From<u32>` added (an enum
with every variant, as D26 does for WidgetConfig); both bars re-export the
items from widgets/mod.rs so no widget changes. The core gains the `image`
dependency (one line in each Cargo.lock) and a Default impl for IconsCache
(clippy).

Verified: schema harness macOS and Windows byte-identical (3,774 / 9,091
lines); native bar-core tests 3+5; Windows clippy -D warnings --locked
clean; macOS fake-CC check --locked 0 errors (re-run after touching the core
files). Not run: the bars.
2026-10-31 10:30:21 -07:00
LGUG2Z 60fcd3071a refactor(bar-core): move the time widget into komorebi-bar-core
Pure move of the (now byte-identical) time.rs of both bars into
crates/komorebi-bar-core/src/widgets/time.rs; the only edit is the path of
Alignment. komorebi-bar-core gains the lazy_static dependency (TIME_RANGES);
Cargo.lock of the root and of komorebi-for-mac get that one line. Both bars
re-export the module. 541 lines per bar are gone.

Verified: schema harness: macOS byte-identical (3,774 lines), Windows
byte-identical (9,091 lines); native bar-core tests 3+5 passed; Windows
clippy -D warnings clean (--locked); macOS fake-CC check --locked 0 errors.
Not run: the bars.
2026-10-31 10:18:21 -07:00
LGUG2Z 76d25c8843 feat(windows): WindowsBackend, a compile-only adapter for the shared Backend
komorebi::windows_backend::WindowsBackend implements komorebi_backend::Backend over the existing static WindowsApi and Window methods. It is NOT used by the daemon (no call site changed; that is step 8). A window is WindowId::from_hwnd(hwnd) (every bit kept), a monitor MonitorId::from_hmonitor; maximize, opacity and focus-follows-mouse are supported, the five workspace methods answer Unsupported, batches are no-ops.

Methods that cannot be written without a difference in semantics are commented where they are and will be listed in docs/dev/seam.md section 9 (next revision): set_rect (the top flag is dropped; Window::set_position keeps its animation, slide-in, live-resize guard and same-frame skip), hide/restore/minimize/unminimize/maximize (ShowWindow results are ignored, so only an IsWindow pre-check can say WindowGone; hide and restore also drive the border and HIDDEN_HWNDS), windows() (alt-tab list, not the core's filtered candidates), set_opacity (plain write, not the animated, globally-configured Window::transparent), monitor_from_point (nearest monitor, never None).

Verified: nix develop cargo clippy --workspace --locked --all-targets -- -D warnings finished with no warnings or errors. Not run: unit tests (Windows code cannot run here).
2026-10-31 01:37:54 -07:00
LGUG2Z f08237d402 feat(backend): the shared Backend trait, WindowId, plain-data infos and the error type
New crate crates/komorebi-backend (edition 2024, root workspace member, depends only on komorebi-layouts for Rect).

- WindowId and MonitorId: opaque u64 newtypes. KDE and macOS ids convert with from_u32/to_u32; a Windows HWND/HMONITOR goes through from_hwnd/to_hwnd, which keep the bits of the isize unchanged (isize as usize as u64), so no handle is lost whether or not it fits in 32 bits (the e2e samples stay below 2^32, which is an observation, not a guarantee).
- WindowInfo and MonitorInfo: plain data; only id, pid, rect, minimized and alive are required, the rest (title, class, exe, path, fullscreen, maximized, normal; name and serial id of a monitor) are Option (seam.md consequence 6).
- Error: WindowGone(id) (finding 9: macOS uses a failed write as its signal that a window died), Unsupported(Capability) and Platform(cause).
- Backend: only the operations of seam.md section 2.1 that at least two platforms have (5 queries, 9 commands), a Capability query for workspaces, maximize, opacity and focus-follows-mouse (their methods default to Unsupported), begin_batch/end_batch with a no-op default plus the Batch guard (finding 8), the documented set_rect contract (a request; reads after a write return what the platform defines, consequence 2 as corrected) and the thread contract (any non-main thread, no waiting for the platform's main thread: consequences 3 and 4, written as TARGET rules). Every doc comment says which platforms implement the method.

Verified: native cargo test -p komorebi-backend (2 unit tests, 3 doctests, 0 failed) and cargo clippy -p komorebi-backend --all-targets -- -D warnings clean. The Windows/KDE/macOS gates are not affected yet (new crate, nothing depends on it).
2026-10-31 01:37:54 -07:00
LGUG2Z 6da27dda3c refactor(bar-core): move the memory, date and update widgets into komorebi-bar-core
Pure move of the three widget files that are byte-identical in the two bars since the previous revision. Each bar's widgets/mod.rs re-exports them (pub use komorebi_bar_core::widgets::memory / date / update). The core takes chrono, chrono-tz, reqwest (blocking) and serde_json (now a normal dependency, it was only a dev-dependency).

Removed: 541 lines from each bar (138 + 245 + 158), 541 added once.

Verified: Windows cargo clippy --workspace --locked --all-targets -D warnings clean; macOS fake-CC cargo check --locked --workspace --all-targets finished, 0 errors; native cargo test -p komorebi-bar-core 3 unit + 2 oracle passed; harness regeneration byte-identical for both (macOS 3,774 lines, Windows 9,091 lines). Not verified: rendering.
2026-10-31 01:37:54 -07:00
LGUG2Z 98f9e184a2 refactor(bar-core): move the battery and cpu widgets into komorebi-bar-core
Pure move of the two widget files that are byte-identical in the Windows and macOS bars. Each bar's widgets/mod.rs re-exports them (pub use komorebi_bar_core::widgets::battery / cpu), so crate::widgets::battery::... resolves as before; the files themselves are unchanged.

Dependencies: the core takes sysinfo from the root workspace (0.39) and starship-battery 0.11, the versions the Windows bar already used. The macOS bar therefore now gets these two widgets built against sysinfo 0.39 (its own workspace pins 0.38, still used by its other widgets until they move) and starship-battery 0.11 (was 0.10; its own dependency on the crate is removed). Both compile unchanged; behaviour of the libraries is not verified on macOS.

Not changed on purpose: the macOS bug that these two files spawn cmd.exe (taskmgr.exe, explorer.exe) on click is still there, identically; it is fixed behind the platform hook, not inside a move.

Removed: 325 lines from each bar (191 + 134), 325 added once.

Verified: Windows cargo clippy --workspace --locked --all-targets -D warnings clean; macOS fake-CC cargo check --locked --workspace --all-targets finished, 0 errors (bar warnings 6, unchanged; macOS Cargo.lock: starship-battery 0.10.3 -> 0.11.1 with its dependencies (uom, plist, nix), sysinfo 0.39.6 added next to 0.38.4); native cargo test -p komorebi-bar-core 3 unit + 2 oracle passed; harness regeneration (S/bar2/regen.sh, which now fails when a harness does not build): macOS byte-identical (3,774 lines), Windows byte-identical (9,091 lines). Not verified: rendering, sysinfo and starship-battery behaviour on macOS.
2026-10-31 01:37:54 -07:00
LGUG2Z 3b641c04ce refactor(bar-core): move the leaf types of config.rs and their three tests into komorebi-bar-core
Pure move of the tail of config.rs, which both bars have byte-identical: Position (with its Vec2 and Pos2 conversions), LabelPrefix, DisplayFormat, the extend_enum! macro, WorkspacesDisplayFormat, MediaDisplayFormat and the three extend_* unit tests, to komorebi_bar_core::config::types. Each config.rs re-exports the module (pub use komorebi_bar_core::config::types::*), so crate::config::LabelPrefix and the others resolve as before; the Windows config.rs keeps its own pub use of KomobarTheme.

Two differences, neither visible in a schema: the macOS bar had no MediaDisplayFormat (it has no media widget), so it now has the unused type; the unit tests count as 3 in komorebi-bar-core instead of 3 in each bar, and run natively on Linux. The bars take the crate's schemars feature from their own (komorebi-bar-core/schemars).

Removed: 170 lines from the Windows config.rs and 149 from the macOS one; 174 added once (170 moved, 4 import lines).

Verified: Windows cargo clippy --workspace --locked --all-targets -D warnings clean; macOS fake-CC cargo check --locked --workspace --all-targets finished, 0 errors (bar warnings 6, unchanged); native cargo test -p komorebi-bar-core: 3 unit tests (the moved extend_* tests) + 2 schema oracle passed, 0 failed; harness regeneration (S/bar2/regen.sh): macOS byte-identical (3,774 lines), Windows byte-identical (9,090 lines). Not verified: rendering.
2026-10-31 01:37:54 -07:00
LGUG2Z 8ad6213b04 refactor(bar-core): move selected_frame.rs and ui.rs into komorebi-bar-core
Pure move of the two files of the bar that depend on nothing else in it, byte-identical in the Windows and macOS bars (selected_frame.rs since the previous revision). Each bar keeps its paths: main.rs re-exports the modules (pub use komorebi_bar_core::selected_frame / ui), so every crate::selected_frame::... and crate::ui::... in the widgets and bar.rs resolves as before. The crate takes eframe from the workspace; the macOS bar takes the crate by path.

Removed: 111 lines (89 + 22) from each of the two bars, 111 added once.

Verified: Windows cargo clippy --workspace --locked --all-targets -D warnings clean; macOS fake-CC cargo check --locked --workspace --all-targets finished, 0 errors (bar warnings 10 -> 6, the four strokes of the previous revision); native cargo test -p komorebi-bar-core 2 passed, 0 failed; harness schema regeneration (S/bar2/regen.sh): macOS byte-identical to its schema.bar.json (3,774 lines), Windows byte-identical to the regenerated schema.bar.json (9,090 lines). Not verified: rendering.
2026-10-31 01:37:54 -07:00
LGUG2Z eaf43a2ca4 build(bar-core): add the komorebi-bar-core crate with the schema oracle test
Skeleton of the shared bar crate (D25/D26): an empty library and the oracle that every later move of bar code is held to. tests/schema_oracle.rs pins the checked-in schema.bar.json of the Windows bar (9,090 lines, FNV-1a 0x557301341968bff9) and of the macOS bar (3,774 lines, 0xc99e02949424e5d7), so any change to either file, intended or not, fails the test until the pin is updated in a reviewed revision. Once config.rs moves into the crate the test generates the schema and compares it with the file instead.

The pins are of the files as they are after the previous revision (the regenerated Windows file) and are the values the out-of-tree harness (S/bar2/regen.sh over the real sources) reproduces: macOS byte-identical, Windows byte-identical to the regenerated file.

Verified: native cargo test -p komorebi-bar-core: 2 passed, 0 failed; Windows cargo clippy --workspace --locked --all-targets -D warnings clean; macOS fake-CC cargo check --locked --workspace --all-targets finished, 0 errors.
2026-10-31 01:37:54 -07:00
LGUG2Z e950c8f967 chore(repo): combine step 3 with the integration line
Merge revision: wip-main (history merges, fixes, step 0, steps 1, 2, 4 and 5, flake work, seam document) and wip-step3 (komorebi-config: matching types, behaviour enums, AspectRatio/PerAnimationPrefixConfig, asc and the application configuration data, placement types, the one StaticConfig with per-platform schema views, the daemons wired to it). Conflicts between step 3's edits and step 4's restructuring of komorebic (the schema-printing arms moved into the WindowsCommands/MacosCommands/KdeCommands matches) and in the Cargo.lock files are resolved here once, instead of through 35 separate rebases.
2026-10-31 01:37:54 -07:00
LGUG2Z be3d1cd6b6 refactor(komorebic-core): the Launcher skeleton for start, and the stop message
start is the same dance in all three komorebic: look whether komorebi is running, start it, wait three seconds and look again, give up after three attempts by running it in front of the user so its stderr can be read. launcher::start runs that loop over a Launcher (daemon_name, spawn, is_running, diagnose) that each platform implements by hand; what follows a successful start (companions, the licence text) stays in each komorebic, as does stop's handling of companions, whose order differs per platform; only stop_message(ignore_restore) is shared. The loop flushes standard output after 'Waiting for ... to start...' (KDE did, macOS and Windows did not) and puts the same space after it; both are invisible in the text printed. Nothing uses it yet.

Verified: native cargo test -p komorebic-core: 31 passed, 0 failed (4 new launcher tests with a fake launcher: already running, second try, three tries then diagnose, stop message).
2026-10-31 01:37:54 -07:00
LGUG2Z 2200bec995 refactor(config): add the one StaticConfig and its schema views to komorebi-config
static_config.rs holds the union: StaticConfig with all 56 keys and no cfg on a field, BorderColours, ThemeOptions, Wallpaper, WorkspaceConfig, MonitorConfig, AppSpecificConfigurationPath, AnimationsConfig, TabsConfig and StackbarConfig, taken from the Windows text (the superset) plus the KDE/macOS keys (border_radius, titleless_applications, tabbed_applications, window_hiding_position). A key that not every platform reads carries x-komorebi-platforms (22 Windows-only, 5 Windows+KDE, 4 KDE+macOS); the five #[deprecated] attributes became schemars deprecated markers so no daemon gets a deprecation warning for a key it still reads. The schema defaults that read daemon run-time statics are constants in defaults.rs (Windows values).

changes.rs holds what a platform's schema says differently from the union as data: descriptions (spelling and platform sentences), the defaults that are platform facts (paddings 10/5/5, border width 8/10/10, offset -1/0/0, no transparency default on KDE) and the nine komorebi-themes stackbar fields KDE and macOS never had. It was generated from the difference between the union view and each tree's checked-in schema.json; every entry is a candidate for a converge revision. schema::view applies it after pruning.

The oracle test builds the KDE and macOS views of StaticConfig and compares them with schema.json byte for byte: both identical (KDE 127164 bytes, macOS 120057 bytes). Windows is added when komorebi-themes drops its target_os cfgs (a Linux build omits those nine fields). No tree uses the new types yet.

Verified: native cargo test -p komorebi-config: 4 unit + 8 schemas passed, 0 failed (tier 1).
2026-10-31 01:37:54 -07:00
LGUG2Z 001b7c98cd refactor(komorebic-core): move the macOS subcommand definitions into the crate
MacosCommands and the argument structs of the subcommands that are not in Messages (start, stop, quickstart, permissions, pan, the animation commands and the 18 whose help still differs between the trees) move from komorebi-for-mac/komorebic/src/main.rs to komorebic-core::platform::macos with their fields made pub; the macOS main.rs keeps the handlers (1293 to about 600 lines). The definitions have no macOS-only dependency, so the pages of the macOS command line can now be written on any host: the docgen-all example of the crate does it, and replaces the harness that compiled the clap section of main.rs. clap_complete joins the crate for Completions.

Verified: oracle (step4/oracle-check.sh, macOS pages now from the docgen-all example): macos 158 of 158 pages byte-identical (windows 187 and kde 166 still pass); macOS fake-CC cargo check --locked --workspace --all-targets: 0 errors; KDE cargo check -p komorebic: ok.
2026-10-31 01:37:54 -07:00
LGUG2Z 2bd0269df6 refactor(windows): use asc and the application configuration data of komorebi-config
core::asc re-exports ApplicationSpecificConfiguration, AscApplicationRules and AscApplicationRulesOrSchema, and config_generation re-exports ApplicationOptions and ApplicationConfiguration, from komorebi-config. The From<Vec<ApplicationConfiguration>> conversion that komorebic uses moved with them (orphan rule). The YAML generator stays. 215 lines removed.

AscApplicationRules is now the union, so komorebic's application-specific-configuration-schema prints the Windows view of it (komorebic gains the komorebi-config dependency; a three-line change in the arm, the minimum that keeps its output equal to schema.asc.json; step 4 owns the rest of the file). The daemon's own socket answer for this message is a different schema (Vec<ApplicationConfiguration>) and is untouched.

Verified: Windows cargo clippy --workspace --locked --all-targets -D warnings: clean (tier 2). Not verified: running komorebic.exe; the oracle test proves the Windows view equals schema.asc.json byte for byte.
2026-10-31 01:37:54 -07:00
LGUG2Z 89c729e731 refactor(config): move asc and the application configuration data into komorebi-config
ApplicationSpecificConfiguration, AscApplicationRulesOrSchema and AscApplicationRules are code-identical in the trees except that AscApplicationRules differs in its rule kinds: five Windows-only kinds, titleless and tabbed on KDE and macOS. The crate holds the union (declaration order floating-first as before; the platform-only fields carry x-komorebi-platforms, so a view prunes them) and, for the Windows From<Vec<ApplicationConfiguration>> conversion that the orphan rule keeps next to its types, ApplicationOptions and ApplicationConfiguration (data only: the YAML generator stays in the Windows daemon). The crate gains the color-eyre dependency.

The oracle test builds the view of ApplicationSpecificConfiguration for Windows, KDE and macOS and compares it with each tree's checked-in schema.asc.json byte for byte: all three are identical. This is the first proof that per-platform views of one union reproduce the checked-in files exactly (D17/D18); the three trees still use their own copies.

Verified: native cargo test -p komorebi-config: 4 unit + 6 schemas passed, 0 failed (tier 1).
2026-10-31 01:37:54 -07:00
LGUG2Z 6b9d79574d refactor(komorebic): use the argument blocks of komorebic-core in the Windows komorebic
Same change as for KDE and macOS in the Windows komorebic: the ten gen_* macros, BooleanState and the paste dependency (only the macros used it) are replaced by the blocks of komorebic-core, with the arms reading args.value or args.target.monitor. About 395 lines of macros and invocations are removed.

Verified: the oracle (step4/oracle-check.sh, harness over the real protocol crate): 187 of 187 Windows pages byte-identical to the pre-move output (after normalising the one cfg(target_os) line of ApplicationIdentifier::Class that a Linux build words differently); Windows clippy --workspace --locked --all-targets -D warnings clean; macOS fake-CC cargo check --locked --workspace --all-targets: 0 errors.
2026-10-31 01:37:54 -07:00