seam, core-model, settings, rule-matching, bar-unification, e2e-to-unit and known-issues are measurements and decision logs written for the old directories. They keep their history; each gets a "Paths (cutover stack)" note under the title that maps the old names (komorebi/, komorebi-for-kde/komorebi/, komorebi-for-mac/komorebi/, nix/, docs/, schema files) to the new ones and says the 0.1.x numbers are history. The seam.md tree table, the test file paths in e2e-to-unit.md and known-issues.md (files that exist and are named as current) and the bar-e2e.md schema path now name the files where they are. Not rewritten: the line numbers, measurements and "at the time" statements. Not touched: backend-switch.md (no old paths), build-and-test.md and flake.md (flake-one). Verified: the files named as current exist (komorebi-linux/tests/*.rs); relative links resolve.
15 KiB
One komorebi-bar for Windows and macOS
Status (wip-cand4): B0-B3 done (one
komorebi-barpackage, a module per platform, schema views); B4 (merging the rendering code) not done and cannot be shown mechanical without a screen; macOS bar never rendered by these changes.
Paths (cutover stack): this document was written before the directories were renamed and keeps the paths of its time. Now:
komorebi/iskomorebi-windows/,komorebi-for-kde/komorebi/iskomorebi-linux/,komorebi-for-mac/komorebi/iskomorebi-macos/,komorebi-for-kde/komorebi-hotkeys/iskomorebi-hotkeys/,komorebi-for-kde/nix/andkomorebi-for-mac/nix/arenix/linux/andnix/macos/,komorebi-for-kde/docs/andkomorebi-for-mac/docs/aredocs/linux/anddocs/macos/,schema*.jsonare inschemas/{windows,linux,macos}/, and every package is at version 0.2.0 (the 0.1.x numbers below are history).
Status at the revision that adds this file. Everything below was measured on this tree with
diff (counts are lines that differ, </> lines of diff, hunks in parentheses). Nothing
here was rendered: the bars cannot run on Linux. Gates that did run are named; the ones that
did not are listed at the end.
KDE has no bar: komorebi-for-kde has no komorebi-bar package and no schema.bar.json.
The plan below is for two platforms; a KDE bar would add a third shell and a third schema view.
What exists
crates/komorebi-bar-core(4,592 lines): the code both bars share, one copy each.selected_frame,ui,statics,alignment,render,config(the leaf types and the wholeKomobarConfigwith the mouse options), the widgetsapplications,battery,cpu,date,memory,storage,time,update,komorebi_layout, the icon cache (widgets/icons.rs), all widget configuration types (komorebi_config,network_config,platform_configfor keyboard, media and systray),WidgetConfigwith a variant for every widget, theBarWidgettrait,platform(BarPlatform,SystemTool, a once-installed global) andschema(per-platform views, see below).BarPlatformhooks:open_system_tool,latest_release_api_url,calendar_icon,command_icon,exec_shell_command,send_komorebi_message,send_komorebi_batch.- Two shells,
komorebi-bar(Windows, root workspace, version 0.1.42) andkomorebi-for-mac/komorebi-bar(own workspace, ownCargo.lock, own flake, version 0.1.1). Each keepsmain.rs,bar.rs,os.rs, the one-lineconfig.rs, and the widgets whose runtime differs:komorebi.rs,network.rs, and on Windowskeyboard.rs,media.rs,systray.rs.widgets/widget.rsis onlyWidgetConfigExt(config -> widget). - The schema oracle regenerates the macOS file natively
(
tests/schema_oracle.rs, modulegenerated); the Windows file is still checked by the out-of-tree harness because three descriptions read differently when compiled for Windows.
Why one package is not possible yet (the structural blocker)
The two trees are two Cargo workspaces with two lockfiles and two flakes. A package belongs to
one workspace, so a single komorebi-bar that builds on both platforms needs one workspace
first: the Windows root Cargo.toml and komorebi-for-mac/Cargo.toml merged, one Cargo.lock,
one version (0.1.42 vs 0.1.0), one komorebi-client (the two lib.rs differ in 150 lines:
Windows re-exports the daemon crate and State/Window/Workspace, macOS has its own
types) and windows/objc2 dependencies under [target.'cfg(...)'.dependencies]. That is a
repository-level cutover (the plan's "final naming of the outputs and the unified app/devShell
is a cutover decision"), not a bar change. Until then the bars share the crate and converge,
they do not merge. Everything in this stack is ordered so the merge later is a package move.
The schema is solved: views of one union
schema.bar.json differs between the platforms in 40 hunks (5,381 lines of 9,091 / 3,774).
Analysed by definition (jq over $defs):
- 42 definitions exist only on Windows: all reachable only through
MouseConfig(which holds aSocketMessage, hence the closure) and theKeyboard/Media/Systraywidgets. Removing themouseproperty and the three widget variants and pruning unreachable definitions removes all 42. - 14 differences remain in the 55 shared definitions, all text or default: root description
(macOS names its own schema URL),
heightdefault50vs50.0, the margin and padding examples (10vs10.0, a sentence about defaults, a trailing comma),show_icon(deprecated flag and backticks),KomorebiLayout(untaggedanyOfon Windows, externally taggedoneOfon macOS),NetworkConfig.default_interface_options(Windows only), four storage descriptions (C:\vs/),TimeConfig.changing_icon(default: falseonly on macOS),TimeFormattitle ofCustom(macOS saysDefault, a mislabel), theWidgetConfigvariants above.
komorebi_bar_core::schema holds this as data (schema/changes.rs, 16 changes) in the same
design as komorebi-config: the union is the Windows text, view_of applies a platform's
changes and prunes. tests/schema_oracle.rs proves that the macOS view of the checked-in Windows
file is byte-identical to komorebi-for-mac/schema.bar.json, that the Windows view is the
identity, and that views are idempotent. Both bars print --schema through their view
(schema::generated_text), so the files and nix/komorebi-bar-options.nix do not change when
code is converged onto the Windows spelling.
The out-of-tree harness (S/bar2/regen.sh, real bar sources over the real
komorebi-protocol/komorebi-config) regenerates both files on Linux. Since config.rs moved, the
in-repo oracle regenerates the macOS file itself (generated tests); only Windows needs the harness.
What is still per platform (measured at this tip)
| file | win / mac lines | differing | what differs and why it is not moved |
|---|---|---|---|
widgets/komorebi.rs |
940 / 986 | 136 (17) | Two things. (1) Real rendering differences: macOS wraps show_label and the "all icons" painter in a Frame with a margin and a minimum height (bar.show_label(...), a method, vs an associated function on Windows), 1.0 vs 1.0_f32. Taking either spelling is a visual change on the other platform: needs a screen. (2) The conversion from the daemon state: Windows uses komorebi_client::{State, Window, Workspace, Container} (hwnd, title(), process_id(), windows-icons), macOS its own client types (details.title, details.icon_path, icns_to_rgba, device, no Layout::Custom). A State-to-snapshot split (WindowInfo/MonitorInfo of komorebi-backend as the carrier) is not clean yet: the macOS and Windows komorebi_client State are different types, the bar subscribes to the daemons with different notification shapes, and I cannot test either subscription here. Not attempted. |
widgets/network.rs |
598 / 578 | 82 (19) | Windows reads default_interface_options (friendly name, IPv4, IPv6), macOS does not (the config type is shared and macOS logs a warning); std::sync::Mutex (poisoning handled) vs parking_lot; netdev 0.46 vs 0.40 and a different interface match key (friendly name vs name); cmd.exe /C ncpa vs open x-apple.... Functional on macOS: BEHAVIOUR, needs a Mac. Known difference, left as is. |
bar.rs |
1,399 / 1,105 | 444 (35) | Windows: PowerShell session (exec_powershell, behind the hook), hwnd, virtual-desktop restore/minimize, position_bar through komorebi_client::Window, CJK font fallbacks, scale_factor, the Windows mouse handling. macOS: unboxed notification type, window shadow and level. Not behaviour-preserving without a screen. |
main.rs |
402 / 388 | 92 (14) | process_hwnd/enum_window, DPI awareness, set_read_timeout; macOS activation policy and window level (AppKit), config dir ~/.config/komorebi. Window and viewport setup belongs behind BarPlatform hooks (init_process, viewport_builder, after_creation), not written: it cannot be exercised here. |
os.rs |
83 / 60 | 71 (14) | the platform implementations themselves; stays per platform (cfg(target_os) modules after the merge). |
widgets/widget.rs, widgets/mod.rs |
41 / 49, 22 / 19 | 20, 5 | WidgetConfigExt (macOS builds a no-op Unsupported for the three Windows-only widgets) and the module lists. |
Windows-only and not shared: widgets/keyboard.rs (167), media.rs (322), systray.rs (1,205);
their config types are in the core. The macOS copies of keyboard and media were dead and are deleted.
Known macOS/Windows differences that were kept (D-coord-1)
network.rs: see above. The macOS bar ignoresdefault_interface_options.- Windows-only config keys are accepted on macOS and skipped with a logged warning (BEHAVIOUR on
macOS, as for
StaticConfig):Keyboard,MediaandSystraywidgets (widgets::widget::warn_unsupported), themouseoptions and the networkdefault_interface_options. Before, the first group failed to deserialize and rejected the whole config, the other two were ignored silently. - macOS commands that spawn programs that do not exist there are preserved, not fixed:
SystemTool::PowerSettings(battery click) spawnscmd.exe /C start ms-settings:...,SystemTool::Url(update click) spawnsexplorer.exe, andUserCommand::launch_if_readyof the applications widget spawnscmd /C <command>in both bars.update.rsstill has a second GitHub API URL for the Windows repository. The macOS spawns live inkomorebi-for-mac/komorebi-bar/src/os.rs; the storage click isSystemTool::StorageLocationand each shell spawns what it spawned before. KomorebiLayoutis#[serde(untagged)]in both bars now (the macOS source converged; the macOS schema view restores the macOS text). ItsDeserializeis hand-written and nothing in the bar serializes it, so this changes only the derived schema andSerialize. The coordinator said to leave it alone; it is a separate revision (mac-bar: converge komorebi.rs config text and komorebi_layout.rs) and can be dropped, at the price of keepingKomorebiLayoutand its widget in the shells.
The merged package layout (for the coordinator's workspace merge)
Not done and not prepared in the tree (no workspace or lockfile structure was changed). When the
root workspace and komorebi-for-mac are merged the bar should look like this:
- Package
komorebi-bar(one, inkomorebi-bar/) pluscrates/komorebi-bar-coreas today. Version: the workspace version. The macOS tree'skomorebi-bar0.1.1 and thev0.1.0text in its schema description are a view concern (schema/changes.rs), not a package one. src/main.rs(shared: the argument parsing, config read,--schema, the event loop shell) andsrc/bar.rssplit intosrc/bar/mod.rs(sharedKomobar) with#[cfg(target_os = "windows")] mod windows;and#[cfg(target_os = "macos")] mod macos;for the window handle, DPI, activation policy, window level, position and the PowerShell session.src/os.rsbecomessrc/os/{windows,macos}.rs(theBarPlatformimplementations, selected bycfg(target_os)and installed first thing inmain). Windows-only widgets (keyboard,media,systray) are#[cfg(target_os = "windows")]modules;komorebi.rsandnetwork.rsstay two files (komorebi/{windows,macos}.rsbehind onewidgets::komorebifacade) until the snapshot split.Cargo.toml:windows,windows-core,windows-icons*,systray-util,font-loaderunder[target.'cfg(windows)'.dependencies];objc2,objc2-app-kit,raw-window-handle,icnsunder[target.'cfg(target_os = "macos")'.dependencies];netdevhas two versions (0.46, 0.40): pick one whennetwork.rsconverges, until then a target-specific rename (netdev-win,netdev-mac).komorebi-client: one crate (the two differ in 150 lines). Features:schemarsas now (it forwards to the core). No new feature per platform: the platform iscfg(target_os).- Schema: the checked-in files stay (
schema.bar.json,komorebi-for-mac/schema.bar.json, or one directory for both after the merge).--schemaprints the view of the running platform (SchemaPlatformfromcfg(target_os)); a--schema-for <platform>flag would let one host regenerate both, as the Windows union is the Windows text. Windows' three platform-dependent descriptions (protocolPathBuf, themes) need the Windows target to regenerate, so the Windows file is only verifiable on Windows or with the harness. - Lock files: the macOS
Cargo.lockfolds into the root one; the lines this stack added to both (image,komorebi-config,komorebi-layouts,komorebi-protocol,komorebi-themes,tracing,lazy_static,color-eyrefor bar-core) are the same crates in both, so the merge adds no new versions beyondnetdevandstarship-battery/sysinfo(already unified here). - Nix:
komorebi-for-mac/nix/komorebi-bar-options.nixis generated from the macOS file and does not change; the two flakes'extractBinary "komorebi-bar"become one derivation per system.
The plan, in order
- Done: schema views and oracle; storage, time, applications, komorebi layout widget, icon
cache, all widget config types,
WidgetConfig,config.rsmoved; hooks for platform spawns, the shell session and the komorebi client. - Not done, needs a screen or a Mac:
bar.rs/main.rswindow code behindBarPlatform(init_process,viewport_builder,after_creation, position/DPI/activation), thenKomobar<P>and the sharedappbody into the core. - Not done, needs the snapshot split:
komorebi.rs. It needsState-to-snapshot conversion per platform and one renderer; the frame/margin difference must be decided by looking at both. - Decision for
network.rs: converge on the Windows widget (macOS gains friendly-name, IPv4/IPv6 and thenetdevbump) or keep two. - Workspace merge (above), then the two shells collapse into one package.
- The oracle then compares generated text with the files for both platforms.
What to check by hand
Windows (coordinator, screenshot e2e): the bar starts; the storage, time, applications (icons
from executables), komorebi layout (click opens the options, choosing one changes the layout,
Monocle/Floating toggles, paused) and komorebi workspaces widgets render; a click on storage
opens Explorer on the drive; a config with mouse options and a Systray/Keyboard/Media
widget still works (this is the Windows path through the moved config.rs, WidgetConfig and
the exec_shell_command hook: a Command mouse message must still reach the PowerShell session);
komorebi-bar --schema equals schema.bar.json.
macOS (also in the section for docs/dev/macos-handcheck.md): the bar starts with your real
config; the time widget renders (format variants, changing_icon); clicking a storage widget
opens the mounted volume in Finder (open <path>); the komorebi layout widget click works as
before; a config that contains a Keyboard, Media or Systray widget, a mouse block, or
default_interface_options under Network starts the bar and logs one warning per item (before:
the widget case failed to load the config); komorebi-bar --schema equals
komorebi-for-mac/schema.bar.json; the battery and update clicks still fail the way they did
(preserved, one-function fix in os.rs).