Commit Graph
606 Commits
Author SHA1 Message Date
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
LGUG2Z c5e13a2d91 refactor(komorebic-core): replace the gen_* macros by generic clap argument blocks
The ten gen_* macros of komorebic (textually the same in the three trees) become plain structs in komorebic-core: Target, NamedTarget, WorkspaceTarget, Size, NamedPadding, WorkspacePadding, PaddingAdjustment, ApplicationTarget and the generic OneEnum<T>, WorkspaceEnum<T> and NamedWorkspaceEnum<T>, which flatten the shared blocks instead of repeating them. A generic positional would be named VALUE, so ValueName gives OneEnum<T> the name the field of the macro struct had (OPERATION_DIRECTION, CYCLE_DIRECTION, ...) and the help stays the same. Limits of generic clap structs (T needs Send + Sync + 'static; a doc comment on a generic field is the help of every instantiation, so the String workspace name has its own struct; flattening two instantiations into one command panics at run time) are in the module docs. The blocks carry plain comments, not doc comments: clap takes the doc comment of an Args struct as the about of the command it is flattened into. Nothing uses the blocks yet.

Verified: native cargo test -p komorebic-core: 6 passed, 0 failed.
2026-10-31 01:37:54 -07:00
LGUG2Z e09f3591bd build(komorebic-core): add the crate with the docgen renderer
A new workspace member crates/komorebic-core, the home of the clap definitions the three komorebic packages share (step 4, D20-D22). This revision only has the docgen renderer: DocFormat keeps what differs between the trees (KDE pins the width at 100, fences with ```text, ends with a newline and writes a page for a subcommand of a subcommand; Windows and macOS set no width) and the list of commands that get no page, which is the same in all three. Nothing uses it yet.

Verified: native cargo test -p komorebic-core: 3 passed, 0 failed.
2026-10-31 01:37:54 -07:00
LGUG2Z d55b6daeb7 refactor(transport): add EventChannel
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.
2026-10-31 01:37:54 -07:00
LGUG2Z 79c9af95d1 refactor(config): move the behaviour enums into komorebi-config
WindowContainerBehaviour, FloatingLayerBehaviour (with should_float), Placement (with should_center and should_resize), CrossBoundaryBehaviour, WindowHidingPosition (KDE and macOS), WindowHandlingBehaviour and ZOrder (with its From<ZOrder> for isize; Windows) in behaviour.rs. The text is the KDE copy for the five that all trees share (identical to the Windows and macOS copies after the previous converge revision) and the Windows copy for the two Windows-only enums. A platform-only enum is defined here without a cfg: the daemon that does not read the key says so at load time. The trees keep their copies until the next revisions. The crate gains the clap dependency (ValueEnum) and the three Cargo.lock files the package entry.

The oracle gains a check that the generated definition of each enum equals the $defs entry of every checked-in schema.json that has it (all three trees for four of them, KDE and macOS for WindowHidingPosition, Windows for the other two).

Verified: native cargo test -p komorebi-config: 4 unit + 4 schemas passed, 0 failed (tier 1).
2026-10-31 01:37:54 -07:00
LGUG2Z 5294f20278 refactor(transport): add the generic command listener
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.
2026-10-31 01:37:54 -07:00
LGUG2Z baeb64de55 refactor(windows): use the shared pause filter
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.
2026-10-31 01:37:53 -07:00
LGUG2Z dc0b9751a5 refactor(windows): use the matching types of komorebi-config
komorebi depends on komorebi-config and core::config_generation re-exports MatchingRule, WorkspaceMatchingRule, IdWithIdentifier, MatchingStrategy and IdWithIdentifierAndComment from it, so no call site changes. The 84 duplicated lines (five types and the From impl) are removed; ApplicationOptions, ApplicationConfiguration and the generator stay.

Verified: Windows cargo clippy --workspace --locked --all-targets -D warnings: clean (tier 2, persistent target). Schema files untouched.
2026-10-31 01:37:53 -07:00
LGUG2Z 9e39fcbbf4 build(transport): add the komorebi-transport crate with the pause filter
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.
2026-10-31 01:37:53 -07:00
LGUG2Z 67c1189bd8 build(config): add the komorebi-config crate skeleton
Add crates/komorebi-config (edition 2024, root workspace member) with the feature-gated schema module that prints a schema the way komorebic does (pretty JSON plus a newline). No type has moved yet: the crate depends on komorebi-layouts, komorebi-themes and komorebi-protocol, which every type that follows needs.

Verified: native cargo test -p komorebi-config compiles (tier 1). Cargo.lock gains only the new package. Windows, KDE and macOS trees do not depend on the crate yet.
2026-10-31 01:37:53 -07:00
LGUG2Z 374ad1bad5 chore(repo): combine step 2 with the integration line
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.
2026-10-31 01:37:53 -07:00
LGUG2Z 4a5733eb1d refactor(collections): move ring.rs and lockable_sequence.rs into komorebi-collections
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.
2026-10-31 01:37:53 -07:00
LGUG2Z 11e38c8c8a build(collections): add the komorebi-collections crate
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).
2026-10-31 01:37:53 -07:00
LGUG2Z b3519814c8 refactor(ring): make the Windows ring.rs identical to the documented one and use pastey
Windows ring.rs is replaced by the KDE copy (doc comments, tests, pastey::paste!, std::collections::VecDeque path). pastey 0.2 added to the root workspace deps and komorebi/Cargo.toml (paste stays: windows_api.rs and komorebic use it). The VecDeque imports in container.rs and workspace.rs only served the old macro text and are removed.

Verified: fast-check Windows clippy --all-targets -D warnings: PASS (tests compiled, not run: Windows-only).
2026-10-31 01:37:53 -07:00
LGUG2Z b5f9016a12 refactor(protocol): use pathext from komorebi-protocol in KDE
Delete komorebi-for-kde/komorebi/src/core/pathext.rs (identical to the crate's copy) and re-export komorebi_protocol::pathext from core, so every existing path keeps working. komorebi-protocol becomes a workspace dependency of komorebi-for-kde (schemars feature on); the crate no longer lists dirs (unused until the client moves), so the root Cargo.lock loses that edge. KDE's Cargo.lock gains komorebi-protocol and cargo re-resolved one windows-sys entry.

Verified: cargo check --workspace --all-targets in komorebi-for-kde: 0 errors; cargo test -p komorebi --lib --test schemas: 305 + 5 passed, 0 failed. Full KDE workspace test run is done at the end of the stage.
2026-10-31 01:37:53 -07:00
LGUG2Z c8f79d99d5 refactor(protocol): move core/pathext.rs into komorebi-protocol (Windows)
Pure move of the converged pathext.rs (identical in all three trees, cmp checked) to crates/komorebi-protocol/src/pathext.rs. The Windows daemon depends on the crate (schemars feature forwarded) and re-exports it as komorebi::core::pathext, so every existing path keeps working. Cargo.lock gains the dependency edge.

Verified: Windows clippy --workspace --locked --all-targets -D warnings clean; native cargo test -p komorebi-protocol: 4 passed 0 failed, including the moved pathext unit test (unix branch). The Windows branch of that test cannot run on Linux (not verified).
2026-10-31 01:37:53 -07:00
LGUG2Z 280bbc668b build(protocol): add the komorebi-protocol crate skeleton
Add crates/komorebi-protocol (edition 2024, member of the root workspace) with empty modules message, platforms, types, animation and pathext. The client transport stays out of the crate (D16). Cargo.lock gains the new package only.

Verified: native cargo build -p komorebi-protocol succeeds. Windows, KDE and macOS gates not run for this revision (no tree depends on the crate yet).
2026-10-31 01:37:53 -07:00
LGUG2Z eee24dad36 feat(e2e): add the guest agent and the test window for the Windows guest
komorebi-e2e-agent runs in the interactive session of the guest and answers
the host over a forwarded TCP port: exec, spawn, os_windows (DWM frame, cloak
and focus), displays, window verbs and file transfer. komorebi-testwin is a
plain Win32 window with a stable exe name and class and a control channel on
stdin. Both cross-build from Linux and pass clippy; neither has run in a
guest yet.
2026-10-30 18:22:44 -07:00
LGUG2Z 8c7327fd31 feat(layouts): share the platform-free half of the scrolling glue
komorebi-layouts now carries what a host needs of the Scrolling layout
without touching an operating system: the scrolling config section and its
checked settings, the layout options for the model, placement of containers
in a work area, resizing a column or tile, and the hand-over of column
records between workspaces. It re-exports the model as
komorebi_layouts::scrolling::model, so komorebi-for-mac can pick all of it up
through its existing komorebi-layouts git dependency.

Also add the Workspace methods for columns, consume/expel/stack, focus and
ordering, which sit on top of it.
2026-10-30 15:45:37 -07:00
LGUG2Z 6c4eb621d3 feat(scrolling): add a platform-free model of a scrollable strip of columns
Ported from komorebi-for-mac (feature/moar-scrolling). The crate has no
dependencies and no knowledge of windows; it is not used by komorebi yet.
2026-10-30 15:45:37 -07:00
LGUG2Z 0b57006053 chore(deps): update libz-sys to 1.1.31 for RUSTSEC-2026-0418
libz-sys before 1.1.31 logs the compiler command of its zlib probe, which
with cc 1.6.0 or later includes every environment variable of the build,
and cargo stores that output under target/. It is a build dependency of
shadow-rs via git2 and libgit2-sys; bump it in the lockfile.
2026-10-30 12:13:42 -07:00
LGUG2Z f08aa55511 chore(deps): cargo update 2026-10-27 09:59:57 -07:00
LGUG2Z e0709f02bf chore(deps): cargo update 2026-08-22 14:26:23 -07:00
dependabot[bot] 1b263b9496 chore(deps): bump shadow-rs from 1.7.1 to 2.0.0
Bumps [shadow-rs](https://github.com/baoyachi/shadow-rs) from 1.7.1 to 2.0.0.
- [Release notes](https://github.com/baoyachi/shadow-rs/releases)
- [Commits](https://github.com/baoyachi/shadow-rs/compare/v1.7.1...v2.0.0)

---
updated-dependencies:
- dependency-name: shadow-rs
  dependency-version: 2.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-02 16:22:35 -07:00
dependabot[bot] e4e1b6da18 chore(deps): bump sysinfo from 0.38.4 to 0.39.6
Bumps [sysinfo](https://github.com/GuillaumeGomez/sysinfo) from 0.38.4 to 0.39.6.
- [Changelog](https://github.com/GuillaumeGomez/sysinfo/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GuillaumeGomez/sysinfo/compare/v0.38.4...v0.39.6)

---
updated-dependencies:
- dependency-name: sysinfo
  dependency-version: 0.39.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-02 16:22:20 -07:00
LGUG2Z fd3d52c477 chore(deps): cargo update 2026-07-21 10:53:14 -07:00
LGUG2Z d29069398b chore(cargo): address clippy warnings 2026-07-21 10:50:26 -07:00
dependabot[bot] ccb39abd2e chore(deps): bump starship-battery from 0.10.3 to 0.11.0
Bumps [starship-battery](https://github.com/starship/rust-battery) from 0.10.3 to 0.11.0.
- [Release notes](https://github.com/starship/rust-battery/releases)
- [Changelog](https://github.com/starship/rust-battery/blob/main/CHANGELOG.md)
- [Commits](https://github.com/starship/rust-battery/compare/v0.10.3...v0.11.0)

---
updated-dependencies:
- dependency-name: starship-battery
  dependency-version: 0.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-25 16:12:27 -07:00
dependabot[bot] f22fb8086c chore(deps): bump nanoid from 0.4.0 to 0.5.0
Bumps [nanoid](https://github.com/mrdimidium/nanoid) from 0.4.0 to 0.5.0.
- [Changelog](https://github.com/mrdimidium/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mrdimidium/nanoid/compare/v0.4.0...v0.5.0)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-version: 0.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-25 16:11:37 -07:00
LGUG2Z 538053c9c8 chore(deps): cargo update 2026-06-24 14:58:47 -07:00
LGUG2Z 937b28a7d9 chore(dev): begin 0.1.42-dev 2026-05-03 16:06:46 -07:00
LGUG2Z e9a541d12b chore(deps): bump flavours 2026-05-01 17:10:20 -07:00
LGUG2Z 53ad7a2224 chore(deps): cargo update 2026-05-01 14:59:04 -07:00
LGUG2Z dce3c91c22 chore(deps): various dependency bumps 2026-03-22 16:11:43 -07:00
LGUG2Z 529d93595e chore(deps): cargo update 2026-03-21 12:38:45 -07:00
Csaba ea35d818a1 feat(bar): windows systray widget
A new System Tray widget has been added to komorebi-bar, bringing native
Windows system tray functionality directly into the bar.

Special thanks to the Zebar project and its contributors for developing
the systray-util crate library that makes Windows system tray
integration possible.

The widget intercepts system tray icon data by creating a hidden "spy"
window that mimics the Windows taskbar. When applications use the
Shell_NotifyIcon API to manage their tray icons, the widget receives the
same broadcast messages, allowing it to monitor all system tray activity
while forwarding messages to the real taskbar to avoid disruption.

Users can configure which icons to hide using flexible rules. A plain
string matches by exe name (case-insensitive). A structured object can
match on exe, tooltip, and/or GUID fields using AND logic. Each field
supports matching strategies from komorebi's window rules (Equals,
StartsWith, EndsWith, Contains, Regex, and their negated variants),
allowing precise filtering even when multiple icons share the same exe
and GUID. An info button opens a floating panel listing all icons with
their properties and copy buttons, making it easy to identify which
values to use in filter rules.

The widget fully supports mouse interactions including left-click,
right-click, middle-click, and double-click actions on tray icons.
Double-click support uses the LeftDoubleClick action from systray-util
0.2.0, which sends WM_LBUTTONDBLCLK and NIN_SELECT messages. It handles
right-aligned placement correctly by adjusting the rendering order and
toggle button arrow directions to maintain consistent visual appearance
regardless of which panel the widget is placed in.

Some system tray icons register a click callback but never actually
respond to click messages, effectively becoming "zombie" icons from an
interaction standpoint. The widget includes fallback commands for known
problematic icons that override the native click action with a direct
shell command (e.g. opening Windows Security or volume settings).

The implementation uses a background thread with its own tokio runtime
to handle the async systray events, communicating with the UI thread
through crossbeam channels. Icon images are cached efficiently using
hash-based keys that update when icons change. Rapid icon updates are
deduplicated to prevent UI freezing, and image conversion (RgbaImage to
ColorImage) is performed on the background thread to keep the UI
responsive.

The widget automatically detects and removes stale icons whose owning
process has exited, using the Win32 IsWindow API on a configurable
interval. A manual refresh button is also available for immediate
cleanup.

A shortcuts button can be configured to toggle komorebi-shortcuts by
killing the process if running or starting it otherwise. The refresh,
info, and shortcuts buttons can each be placed in the main visible area
or in the overflow section.
2026-03-21 12:35:39 -07:00
LGUG2Z 6ca49d4301 chore(deps): cargo update 2026-02-20 16:58:40 -08:00