docs: update paths for crates/ and the komorebi directory, add a contributor path map

This commit is contained in:
LGUG2Z committed 2026-11-05 15:03:27 -08:00
1 parent c234b1d884
commit a81a1120cd
23 files changed
+237 -212

No files matched your search

+3 -3
View File
@@ -64,9 +64,9 @@ one workspace version, the crates under [`crates/`](./crates) and the binaries `
| Platform | Daemon library | Documentation | Schemas |
| --- | --- | --- | --- |
| Windows | [`komorebi-windows`](./komorebi-windows) | this README, [`docs/`](./docs) | [`schemas/windows`](./schemas/windows) |
| KDE Plasma (Linux) | [`komorebi-linux`](./komorebi-linux) | [`docs/linux/README.md`](./docs/linux/README.md) | [`schemas/linux`](./schemas/linux) |
| macOS | [`komorebi-macos`](./komorebi-macos) | [`docs/macos/README.md`](./docs/macos/README.md) | [`schemas/macos`](./schemas/macos) |
| Windows | [`komorebi-windows`](./crates/komorebi-windows) | this README, [`docs/`](./docs) | [`schemas/windows`](./schemas/windows) |
| KDE Plasma (Linux) | [`komorebi-linux`](./crates/komorebi-linux) | [`docs/linux/README.md`](./docs/linux/README.md) | [`schemas/linux`](./schemas/linux) |
| macOS | [`komorebi-macos`](./crates/komorebi-macos) | [`docs/macos/README.md`](./docs/macos/README.md) | [`schemas/macos`](./schemas/macos) |
The rest of this README is about komorebi for Windows. The Mac port used to live in
[its own repository](https://github.com/LGUG2Z/komorebi-for-mac); where this repository will be
+1 -1
View File
@@ -50,7 +50,7 @@
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! `komorebi-client/tests/daemon.rs` sends the same messages to a window manager that listens the
//! `crates/komorebi-client/tests/daemon.rs` sends the same messages to a window manager that listens the
//! way the daemon does, over an in-memory desktop.
use crate::komorebi_linux as komorebi;
@@ -3,7 +3,7 @@
//! three daemons call (`komorebi_config::rules`), so what the `rules`, `rules_class`, `rules_exe`,
//! `title_rule` and `startup_rules` end-to-end scenarios assert about WHICH window a rule catches
//! is asserted here once, with no window manager. These tests are the ones the KDE daemon had
//! (`komorebi-linux/tests/rule_matching.rs`), moved with the function; they run the
//! (`crates/komorebi-linux/tests/rule_matching.rs`), moved with the function; they run the
//! KDE/macOS input shape (`RuleQuirks::UNIX`, a window with a list of classes).
//!
//! Not covered here, and so still end-to-end: that the daemon applies the rule at the right moment
+2 -2
View File
@@ -48,7 +48,7 @@ impl PlatformDefaults {
container_padding: 10,
workspace_padding: 10,
};
/// `komorebi-linux/src/border_manager/mod.rs` and `.../lib.rs`
/// `crates/komorebi-linux/src/border_manager/mod.rs` and `.../lib.rs`
pub const KDE: Self = Self {
border_width: 10,
border_offset: 0,
@@ -56,7 +56,7 @@ impl PlatformDefaults {
container_padding: 5,
workspace_padding: 5,
};
/// `komorebi-macos/src/border_manager/mod.rs` and `.../lib.rs`
/// `crates/komorebi-macos/src/border_manager/mod.rs` and `.../lib.rs`
pub const MACOS: Self = Self {
border_width: 10,
border_offset: 0,
+1 -1
View File
@@ -8,7 +8,7 @@
//!
//! mirrors: commands / <command> (the part "the command is understood: exit status 0", for the
//! command line only; what the daemon does with it is the daemon's tests, see
//! `komorebi-linux/tests/command_sweep.rs`)
//! `crates/komorebi-linux/tests/command_sweep.rs`)
use komorebic_core::cli::Meta;
use komorebic_core::cli::command;
+25 -14
View File
@@ -14,18 +14,27 @@ How to build and test: [build-and-test.md](build-and-test.md). Why things are sh
[settings.md](settings.md), [unified-binaries.md](unified-binaries.md), [bar-unification.md](bar-unification.md),
[backend-switch.md](backend-switch.md). What a person with a Mac has to check: [macos-handcheck.md](macos-handcheck.md).
## 1. Three platforms, one workspace, one directory level
## 1. Three platforms, one workspace, one rule for the directories
The root `Cargo.toml` is the only workspace. Its members are all at the top level or under `crates/`;
the platform-specific parts are:
The root `Cargo.toml` is the only workspace. One rule says where a member lives:
- a **shipped binary** has a directory at the top level: `komorebi/`, `komorebic/`, `komorebic-no-console/`,
`komorebi-bar/`, `komorebi-gui/`, `komorebi-shortcuts/` and `komorebi-recorder/` (with its `wix/` and
`docs/recorder/`). The directory of the package is its name, so `cargo install --path komorebi` installs
the `komorebi` binary;
- every **library** and every **development tool** lives under `crates/<package name>/`: the daemon
libraries of the three platforms, the shared crates, the end-to-end guests (`crates/komorebi-e2e-agent`,
`crates/komorebi-testwin`) and `crates/schemars-nixgen`.
The platform-specific parts are:
| Platform | Where it is | What is in it |
|---|---|---|
| Windows (the original) | `komorebi-windows/` (the daemon library), `komorebi-bar/`, `komorebic/`, `komorebi-gui/`, `komorebi-shortcuts/`, `komorebic-no-console/`, `komorebi-layouts/`, `komorebi-scrolling/`, `komorebi-themes/`, `e2e/`, `wix/`; docs in `docs/` | the Windows daemon library, the unified packages, the Windows-only tools |
| Linux, KDE Plasma on KWin (Wayland) | `komorebi-linux/` (the daemon library), `komorebi-hotkeys/`, `nix/linux/` (NixOS module, VM test suites in `nix/linux/tests/vm`, KWin effects), `scripts/linux/`, `spikes/`; docs in `docs/linux/` | the KDE daemon library, the key binding crate, the NixOS module and the VM tests |
| macOS | `komorebi-macos/` (the daemon library), `nix/macos/`; docs in `docs/macos/` | the macOS daemon library and the nix-darwin module |
| Windows (the original) | `crates/komorebi-windows/` (the daemon library), `komorebi-bar/`, `komorebic/`, `komorebi-gui/`, `komorebi-shortcuts/`, `komorebic-no-console/`, `crates/komorebi-layouts/`, `crates/komorebi-scrolling/`, `crates/komorebi-themes/`, `crates/komorebi-e2e-agent/`, `crates/komorebi-testwin/`, `e2e/`, `wix/`; docs in `docs/` | the Windows daemon library, the unified packages, the Windows-only tools |
| Linux, KDE Plasma on KWin (Wayland) | `crates/komorebi-linux/` (the daemon library), `crates/komorebi-hotkeys/`, `nix/linux/` (NixOS module, VM test suites in `nix/linux/tests/vm`, KWin effects), `scripts/linux/`, `spikes/`; docs in `docs/linux/` | the KDE daemon library, the key binding crate, the NixOS module and the VM tests |
| macOS | `crates/komorebi-macos/` (the daemon library), `nix/macos/`; docs in `docs/macos/` | the macOS daemon library and the nix-darwin module |
Shared: `crates/` (including `crates/komorebi-version`, the version string of the Linux and macOS
Shared: `crates/` (the libraries; including `crates/komorebi-version`, the version string of the Linux and macOS
binaries), `schemas/{windows,linux,macos}/` (the generated JSON schemas), one `deny.toml`, `rustfmt.toml`,
`rust-toolchain.toml`, `.gitignore`, `LICENSE.md` and `justfile` at the root. The old repositories'
workflows, dependabot files, the Homebrew formula template and the macOS docs-site files are kept, inert, in
@@ -36,13 +45,13 @@ workflows, dependabot files, the Homebrew formula template and the macOS docs-si
| Package (binary) | Directory | How the platform is chosen |
|---|---|---|
| `komorebi` (`komorebi`) | `komorebi-daemon/` | `src/main.rs` is a `cfg_select!` that calls `daemon::run()` of the library of the target OS; the libraries are target-gated dependencies in `Cargo.toml` |
| `komorebi` (`komorebi`) | `komorebi/` | `src/main.rs` is a `cfg_select!` that calls `daemon::run()` of the library of the target OS; the libraries are target-gated dependencies in `Cargo.toml` |
| `komorebic` (`komorebic`) | `komorebic/` | `src/windows.rs`, `src/linux/`, `src/macos/`, one `cfg` per target; the arguments are in `crates/komorebic-core` |
| `komorebi-client` (library) | `komorebi-client/` | `src/windows.rs`, `src/linux.rs`, `src/macos.rs` re-export the daemon library of the target OS behind one `Connection` |
| `komorebi-client` (library) | `crates/komorebi-client/` | `src/windows.rs`, `src/linux.rs`, `src/macos.rs` re-export the daemon library of the target OS behind one `Connection` |
| `komorebi-bar` (`komorebi-bar`) | `komorebi-bar/` | `src/windows/` and `src/macos/` modules; shared code in `crates/komorebi-bar-core`. **KDE has no bar** |
The daemon libraries are `komorebi-windows` (`komorebi-windows/`), `komorebi-linux` (`komorebi-linux/`) and
`komorebi-macos` (`komorebi-macos/`). They have no binary: each has a `daemon.rs` with
The daemon libraries are `komorebi-windows` (`crates/komorebi-windows/`), `komorebi-linux` (`crates/komorebi-linux/`) and
`komorebi-macos` (`crates/komorebi-macos/`). They have no binary: each has a `daemon.rs` with
`run()`, the old `main`. `-p komorebi-windows` etc. build them, as libraries.
The shim packages (`komorebic-linux`, `komorebic-macos`, `komorebi-client-linux`, `komorebi-client-macos`,
@@ -50,7 +59,9 @@ The shim packages (`komorebic-linux`, `komorebic-macos`, `komorebi-client-linux`
so were `version-linux` and `version-macos` (now `crates/komorebi-version`). To build a platform use the
one package name, for example `-p komorebic -p komorebi-client -p komorebi-bar -p komorebi-macos` on macOS.
## 3. The shared crates (`crates/`)
## 3. The libraries and tools (`crates/`)
Every library and tool of the workspace is a directory of `crates/`, named as its package; the shared ones are:
| Crate | What it holds | Used by |
|---|---|---|
@@ -64,7 +75,7 @@ one package name, for example `-p komorebic -p komorebi-client -p komorebi-bar -
| `komorebi-bar-core` | the bar's configuration, widgets and platform seam | `komorebi-bar` |
| `komorebic-core` | the command line definitions of every platform (`cli`, `docgen`, `platform::{windows,macos,...}`) | `komorebic` |
Also shared by path from the Windows tree: `komorebi-layouts`, `komorebi-scrolling`, `komorebi-themes`.
Also under `crates/`: `komorebi-layouts`, `komorebi-scrolling`, `komorebi-themes` (Windows-origin, platform-neutral), `komorebi-client`, and the daemon libraries (section 2).
## 4. Where the platforms differ on purpose
@@ -112,7 +123,7 @@ Done in the cutover stack (`jj log -r 'wip-main..wip-cutover'`, one revision per
and 0.1.1 are history); one `komorebi-version` crate instead of `version-linux` and `version-macos`;
- the shim packages `komorebic-linux`, `komorebic-macos`, `komorebi-client-linux`, `komorebi-client-macos`
and `komorebi-bar-macos` deleted;
- the directories renamed: `komorebi/` to `komorebi-windows/`, the KDE and macOS libraries to
- the directories renamed (at that time; since then every library moved under `crates/`, and `komorebi-daemon/` became `komorebi/`, see section 1): `komorebi/` to `komorebi-windows/`, the KDE and macOS libraries to
`komorebi-linux/` and `komorebi-macos/`, `komorebi-hotkeys/` to the top level; `docs/{linux,macos}`,
`nix/{linux,macos}`, `scripts/linux`, `spikes/`, `schemas/{windows,linux,macos}`;
- one `deny.toml`, `rustfmt.toml`, `rust-toolchain.toml`, `.gitignore`, `LICENSE.md` and `justfile`;
+14
View File
@@ -118,6 +118,20 @@ the work clone); the work clone's history of `wip-cand*` bookmarks is local scaf
`git merge-tree` for each head in `gh pr list`.
Plan (master is already frozen): merge or close with a comment those that are ready; for the rest post one comment with the path map (`komorebi/` to `komorebi-windows/`, `schema*.json` to
`schemas/windows/`, `komorebi/src/main.rs` to `komorebi-daemon/src/main.rs`) and keep them open. The 8 dependabot PRs: close them; dependabot recreates them against the new `dependabot.yml` (section 3.7).
- **Contributor path map (final layout).** Libraries and dev tools live under `crates/`, shipped binaries stay at the top level. A patch written against old `master` or against an earlier state of the cutover stack is rewritten with:
| old path | new path |
|---|---|
| `komorebi/` (the OLD Windows daemon, e.g. `komorebi/src/window_manager.rs`) | `crates/komorebi-windows/` (NOT the new `komorebi/`, which is the thin binary package: a PR that touches `komorebi/src/*` of old `master` must be rewritten by hand against `crates/komorebi-windows/src/*`) |
| `komorebi-daemon/` (cutover stack, before the final layout) | `komorebi/` |
| `komorebi-{windows,linux,macos,hotkeys,client,layouts,scrolling,themes}/` | `crates/komorebi-{windows,linux,macos,hotkeys,client,layouts,scrolling,themes}/` |
| `e2e/guest/agent`, `e2e/guest/testwin` | `crates/komorebi-e2e-agent`, `crates/komorebi-testwin` |
| `komorebic/fixtures/` | `crates/komorebic-core/fixtures/` |
| `schema*.json` (root) | `schemas/windows/` |
The rewrite recipe for a patch series (the Windows daemon rule must come first, so that its output is not caught by the `komorebi/` of the last rule):
`git format-patch -o /tmp/p origin/master..mybranch && sed -i -E 's#([ab]/)komorebi/#\1crates/komorebi-windows/#g; s#([ab]/)komorebi-(linux|macos|hotkeys|client|layouts|scrolling|themes)/#\1crates/komorebi-\2/#g; s#([ab]/)komorebi-daemon/#\1komorebi/#g; s#([ab]/)e2e/guest/agent#\1crates/komorebi-e2e-agent#g; s#([ab]/)e2e/guest/testwin#\1crates/komorebi-testwin#g; s#([ab]/)komorebic/fixtures/#\1crates/komorebic-core/fixtures/#g' /tmp/p/*.patch && git checkout -b mybranch-rebased <new master> && git am -3 /tmp/p/*.patch`
(`git am -3` also falls back to rename detection for what the sed misses; the `index` lines of the patches need not be changed).
- **Open issues (89).** They stay: same repository, same numbers. Add labels `windows`, `linux`, `macos` and a platform field in `.github/ISSUE_TEMPLATE/bug_report.yml` (Windows-only today).
- **Forks (376).** Unaffected until they sync. A fork's `master` fast-forwards in GitHub's "Sync fork" (no divergence unless the fork's master has commits, in which case they face the rename conflicts).
- **`master` users.** Anything tracking `master`: `cargo install --git https://github.com/LGUG2Z/komorebi komorebi` still resolves the package `komorebi`
+6 -6
View File
@@ -6,7 +6,7 @@ that made the flake; the rest are documented from `flake.nix`, the justfile, the
README. macOS cannot be built or run on Linux; Linux can only type-check it.
The map of the repository is [ARCHITECTURE-UNIFIED.md](ARCHITECTURE-UNIFIED.md). Package names in this
repository (`cargo metadata --no-deps`, ran): `komorebi` (the daemon, `komorebi-daemon/`), `komorebic`,
repository (`cargo metadata --no-deps`, ran): `komorebi` (the daemon, `komorebi/`), `komorebic`,
`komorebi-client`, `komorebi-bar`, the libraries `komorebi-windows`, `komorebi-linux`, `komorebi-macos`, the
shims `komorebic-linux`, `komorebic-macos`, `komorebi-client-linux`, `komorebi-client-macos`,
`komorebi-bar-macos`, and `komorebi-backend`, `-bar-core`, `komorebic-core`, `-collections`, `-config`,
@@ -22,7 +22,7 @@ shims `komorebic-linux`, `komorebic-macos`, `komorebi-client-linux`, `komorebi-c
- Without a `.git` (a jj workspace) the build script of the macOS and Linux crates needs `COMMIT_HASH=dev`. Do
not run a plain `nix flake check` on the root flake (it boots the VM suites); name the check, or run
`nix flake check --no-build --all-systems` for the evaluation only.
- Text edits under `komorebi-linux/`, `komorebi-hotkeys/` or `komorebi-macos/` change only that platform's nix
- Text edits under `crates/komorebi-linux/`, `crates/komorebi-hotkeys/` or `crates/komorebi-macos/` change only that platform's nix
derivations (each platform builds from its own filtered source, `nix/workspace-src.nix`); a docs-only edit
elsewhere changes none, because the commit stamp is a constant in the checks (`COMMIT_HASH=nix-check`) and
only the native `default` and `windows-default` packages carry the real commit.
@@ -97,7 +97,7 @@ cargo test -p komorebi-linux --test schemas -- --test-threads=1 #
cargo test -p komorebi -p komorebic -p komorebi-client -p komorebi-hotkeys # daemon-binary, CLI and client tests (tests/linux_*.rs)
```
A single test file: `cargo test -p komorebi-linux --test NAME` (the files are in `komorebi-linux/tests`).
A single test file: `cargo test -p komorebi-linux --test NAME` (the files are in `crates/komorebi-linux/tests`).
The `-p komorebi --lib` that older notes use is the thin binary package now: the unit tests are in
`komorebi-linux`.
@@ -216,9 +216,9 @@ A change to the Windows daemon or bar needs these before it is considered landed
| Change touches | Run |
|---|---|
| `crates/*` (not bar/komorebic) | section 1 native crate tests, then Windows clippy (section 1), KDE (section 2) and macOS type-check (section 3) |
| `komorebi-windows/` (Windows daemon) | Windows clippy and nextest, then e2e (section 4) |
| `komorebi-linux/`, `komorebi-hotkeys/` | section 2 cargo, then KDE checks, VM `fast` tier |
| `komorebi-macos/` | macOS type-check on Linux; build and tests on a Mac |
| `crates/komorebi-windows/` (Windows daemon) | Windows clippy and nextest, then e2e (section 4) |
| `crates/komorebi-linux/`, `crates/komorebi-hotkeys/` | section 2 cargo, then KDE checks, VM `fast` tier |
| `crates/komorebi-macos/` | macOS type-check on Linux; build and tests on a Mac |
| `komorebi-bar/`, `komorebi-bar-core` | Windows clippy, `cargo test -p komorebi-bar-core`, macOS type-check, e2e `bar` |
| `komorebic*`, `komorebic-core` | `cargo test -p komorebic-core` (CLI doc oracle), all three platforms' checks |
| `flake.nix`, `nix/**`, `flake.lock` | `nix flake check --no-build --all-systems`, then the checks of the platform edited |
+2 -2
View File
@@ -103,7 +103,7 @@ loads every member in every build. `nix/workspace-src.nix` cuts one source per p
- `real` is the filtered source: the platform's members, the root manifest, lock and toolchain files, the
platform's own files of the crates the platforms share (`komorebic`, `komorebi-client`, `komorebi-bar`,
`komorebi-daemon`: the `linux`, `macos` and `windows` modules and tests are told apart by name) and the data
`komorebi`: the `linux`, `macos` and `windows` modules and tests are told apart by name) and the data
files the sources and tests read (docs, schemas, fixtures).
- `src` is `real` plus a stub for every other member: its manifest with an empty library and a `main` that does
nothing. Stubs are needed: cargo refuses a workspace with a member that is not there, and `--locked` refuses
@@ -124,7 +124,7 @@ crates and `crates/`.
Every platform's checks run on its own source, so a change in one platform's directories does not rebuild the
others' derivations. A change in a crate under `crates/` (or in `komorebic`, `komorebi-client`,
`komorebi-daemon`), in `Cargo.toml`, `Cargo.lock`, `rust-toolchain.toml` or `deny.toml` rebuilds those that read it.
`komorebi`), in `Cargo.toml`, `Cargo.lock`, `rust-toolchain.toml` or `deny.toml` rebuilds those that read it.
- `windows-clippy`, `windows-fmt`, `windows-toml-fmt`, `windows-deny`, `windows-e2e-tests`
- `linux-clippy`, `linux-doc`, `linux-nextest`, `linux-fmt`, `linux-toml-fmt`, `linux-deny`, `linux-bridge-js`,
+1 -1
View File
@@ -115,7 +115,7 @@ prerequisites](https://rust-lang.github.io/rustup/installation/windows-msvc.html
Clone the git repository, enter the directory, and build the following binaries:
```powershell
cargo +stable install --path komorebi-daemon --locked
cargo +stable install --path komorebi --locked
cargo +stable install --path komorebic --locked
cargo +stable install --path komorebic-no-console --locked
cargo +stable install --path komorebi-gui --locked
+6 -6
View File
@@ -46,17 +46,17 @@ KVM.
## The bridge
[`bridge.js`](../../komorebi-linux/src/kwin/bridge.js), the script komorebi loads into
[`bridge.js`](../../crates/komorebi-linux/src/kwin/bridge.js), the script komorebi loads into
KWin, is JavaScript that KWin runs as it is: there is no package.json and no
build step. Its types are JSDoc comments, which `tsc` checks against
[`kwin-api.d.ts`](../../komorebi-linux/src/kwin/kwin-api.d.ts), the part of KWin's
[`kwin-api.d.ts`](../../crates/komorebi-linux/src/kwin/kwin-api.d.ts), the part of KWin's
scripting API the bridge uses; something the bridge starts to use is declared
there first. Its tests, [`bridge.test.js`](../../komorebi-linux/src/kwin/bridge.test.js),
there first. Its tests, [`bridge.test.js`](../../crates/komorebi-linux/src/kwin/bridge.test.js),
run under `node --test` against a fake KWin. `just check-js` runs both, with the
`tsc` and `node` of the dev shell.
The messages between the bridge and the daemon are in
[`komorebi-linux/src/kwin/fixtures`](../../komorebi-linux/src/kwin/fixtures), which the tests of
[`crates/komorebi-linux/src/kwin/fixtures`](../../crates/komorebi-linux/src/kwin/fixtures), which the tests of
both sides read. A change to a message changes the fixture, the bridge and the
daemon in the same commit.
@@ -106,7 +106,7 @@ for Windows and komorebi for Mac, and its tables are generated by
this checkout and from checkouts of the other two. The script is stale: it was written when
komorebi for KDE lived in `komorebi-for-kde/` of a repository next to `komorebi-for-mac/`, and
it looks for the other two trees there (or in `~/komorebi` and `~/komorebi-for-mac`). Since the
consolidation they are `komorebi-windows/` and `komorebi-macos/` of this repository, and the
consolidation they are `crates/komorebi-windows/` and `crates/komorebi-macos/` of this repository, and the
script and `COMPARE.md` have not been made again. Continuous
integration has no checkouts, so it does not run the script. A change to a
`komorebic` command, a `SocketMessage`, a key of `komorebi.json`, a
@@ -187,7 +187,7 @@ nixpkgs is not pinned back.
## Releases
A release is a tag. Set `version` in
[`komorebi-linux/Cargo.toml`](../../komorebi-linux/Cargo.toml) (which the flake reads) to the new version, commit it, and push the tag
[`crates/komorebi-linux/Cargo.toml`](../../crates/komorebi-linux/Cargo.toml) (which the flake reads) to the new version, commit it, and push the tag
`vVERSION` on that commit. For every run, the `build` job of `ci.yaml` builds
`komorebi` and `komorebic` with nix on an x86_64 and an arm64 runner, and keeps
them as an artifact of the run for 14 days. On a tag, once `lint`, `vm-fast` and
+6 -6
View File
@@ -41,7 +41,7 @@ directory): a message can ask for the state of the window manager, ask which
monitor, workspace or container has the focus, give the focus to another
window, move the focused window to another tile, change the layout, resize a
tile, float a window, give one window the whole work area or have KWin maximize it, retile every
monitor, or stop the daemon. [`komorebi-client`](../../komorebi-client) writes them, and `komorebic`,
monitor, or stop the daemon. [`komorebi-client`](../../crates/komorebi-client) writes them, and `komorebic`,
the command line, is how a person sends them. `komorebic start` runs the
`komorebi` on the `PATH`, and passes it what follows a `--`. In a Plasma
session:
@@ -95,8 +95,8 @@ komorebi from source.
## Crates
- [`komorebi-linux`](../../komorebi-linux): the library behind the daemon (the `komorebi` binary is the
package [`komorebi-daemon`](../../komorebi-daemon), which calls its `daemon::run` on Linux). The library has
- [`komorebi-linux`](../../crates/komorebi-linux): the library behind the daemon (the `komorebi` binary is the
package [`komorebi`](../../komorebi), which calls its `daemon::run` on Linux). The library has
the vocabulary the window manager is written in (`core`), the `Backend` trait
through which it reaches a compositor and the in-memory desktop the tests use
(`backend`), the backend that reaches KWin through a script it runs and edits
@@ -123,15 +123,15 @@ komorebi from source.
key binding file, and the desktop it runs on, for mistakes without the daemon
(`check`). With a key binding file, it registers keys with KWin's global
shortcut daemon and runs their commands (`kwin::hotkeys`).
- [`komorebi-client`](../../komorebi-client): a library (shared with Windows and macOS, with a `linux` module) that sends messages to the
- [`komorebi-client`](../../crates/komorebi-client): a library (shared with Windows and macOS, with a `linux` module) that sends messages to the
daemon, reads its answers, subscribes to its notifications, and re-exports
the types they are made of.
- [`komorebi-hotkeys`](../../komorebi-hotkeys): reads the key binding files of skhd,
- [`komorebi-hotkeys`](../../crates/komorebi-hotkeys): reads the key binding files of skhd,
whkd and sxhkd into one model, with the keys as KDE stores them, plans each
binding as a KDE shortcut file or as a key komorebi registers itself, and has
the engine that decides, with no I/O of its own, which keys komorebi holds
and what each press does. It does not depend on the daemon. Its tests read the files in
[`komorebi-hotkeys/tests/fixtures`](../../komorebi-hotkeys/tests/fixtures), where
[`crates/komorebi-hotkeys/tests/fixtures`](../../crates/komorebi-hotkeys/tests/fixtures), where
each case is written in every format that can express it.
- [`komorebic`](../../komorebic): the command line (one package for the three platforms, with a `linux` module). A subcommand that asks something
of the daemon is one message on its socket, and the others work without the daemon:
+137 -137
View File
@@ -2,7 +2,7 @@
komorebi is a tiling window manager. It decides where every window goes and asks a
compositor to put it there. Everything it needs from the compositor is behind one trait,
[`Backend`](../../../komorebi-linux/src/backend/mod.rs), so the window manager is written, and
[`Backend`](../../../crates/komorebi-linux/src/backend/mod.rs), so the window manager is written, and
tested, without one.
This page describes that trait, who implements and calls it, where each of its rules is
@@ -93,9 +93,9 @@ same and what is different in komorebi for Windows and komorebi for Mac.
is the effect that draws the border, and Geometry Change the one that animates windows.
- **Compositor**: the program that owns the screen and the windows. On KDE Plasma it is
KWin.
- **Backend**: the implementation of the [`Backend`](../../../komorebi-linux/src/backend/mod.rs)
- **Backend**: the implementation of the [`Backend`](../../../crates/komorebi-linux/src/backend/mod.rs)
trait that talks to a compositor.
- **Fake**: [`FakeBackend`](../../../komorebi-linux/src/backend/fake.rs), the in-memory backend
- **Fake**: [`FakeBackend`](../../../crates/komorebi-linux/src/backend/fake.rs), the in-memory backend
the tests use.
- **Bridge**: the script komorebi loads into KWin ([`bridge.js`]). It reports what KWin
tells it and carries out what the daemon asks.
@@ -635,7 +635,7 @@ monocle that is maximized leaves the monocle. While a window is maximized, the m
about the tiles are dropped before they are handled: `MoveWindow`, `CycleMoveWindow`, the stack
messages, the resize, promote and preselect messages, `ToggleLock`, `ToggleFloat`,
`ToggleMonocle`, and the messages that send a container to another monitor or workspace
(`is_layout_command` in [`process_command`](../../../komorebi-linux/src/process_command.rs)). A window that
(`is_layout_command` in [`process_command`](../../../crates/komorebi-linux/src/process_command.rs)). A window that
closes while it is maximized leaves the workspace like any other. `FocusWindow` finds no
container on any side of the maximized window, so the focus goes to the monitor on that side and
fails where there is none, and a maximized window, or a monocle, on the workspace it reaches is
@@ -1091,7 +1091,7 @@ Without a border, because they are off or the compositor has no effect to draw o
given back the next time the workspace is tiled.
The KWin backend draws the border with the effect KDE Rounded Corners
([`kwin::effects`](../../../komorebi-linux/src/kwin/effects.rs)). `apply_look` writes the effect's settings
([`kwin::effects`](../../../crates/komorebi-linux/src/kwin/effects.rs)). `apply_look` writes the effect's settings
into the user's `kwinrc`, group `[Round-Corners]`, through [`Kwinrc`]; loads the effect with
`loadEffect` unless it is loaded; and always asks it to read its settings again
(`reconfigureEffect`), since KWin hands an effect the copy of `kwinrc` it read when it started. A
@@ -1264,18 +1264,18 @@ too.
## The parts
- [`backend`](../../../komorebi-linux/src/backend/mod.rs): the trait, the two data types, and the
- [`backend`](../../../crates/komorebi-linux/src/backend/mod.rs): the trait, the two data types, and the
process-wide handle ([`set_backend`], [`backend`], [`with_backend`]).
- [`backend::fake`](../../../komorebi-linux/src/backend/fake.rs): the fake.
- [`backend::fake`](../../../crates/komorebi-linux/src/backend/fake.rs): the fake.
- [`ring`](../../../crates/komorebi-collections/src/ring.rs): the [`Ring`], and the macro that gives every type
holding one the same accessors (`containers()`, `focused_container_mut()`, ...).
- [`monitor`](../../../komorebi-linux/src/monitor.rs), [`workspace`](../../../komorebi-linux/src/workspace.rs),
[`container`](../../../komorebi-linux/src/container.rs), [`window`](../../../komorebi-linux/src/window.rs):
- [`monitor`](../../../crates/komorebi-linux/src/monitor.rs), [`workspace`](../../../crates/komorebi-linux/src/workspace.rs),
[`container`](../../../crates/komorebi-linux/src/container.rs), [`window`](../../../crates/komorebi-linux/src/window.rs):
the four levels of the tree; `window` also has the rule engine ([`should_act`]).
- [`lockable_sequence`](../../../crates/komorebi-collections/src/lockable_sequence.rs): inserting, removing and
swapping in a list where some elements are locked in place, which is how a workspace
changes its containers.
- [`window_manager`](../../../komorebi-linux/src/window_manager.rs): the [`WindowManager`] and the
- [`window_manager`](../../../crates/komorebi-linux/src/window_manager.rs): the [`WindowManager`] and the
operations on it (tile the workspace in front, tile every monitor, take a minimized
window out, move the focus, move the focused container, change the layout, resize or
promote the focused container, float a window, switch the layer, put a container in
@@ -1285,59 +1285,59 @@ too.
something else, name a workspace and find it by its name, set the layout of a workspace
that is not in front, focus another monitor, and move containers and workspaces between
monitors).
- [`desktop`](../../../komorebi-linux/src/desktop.rs): loads the monitors and the open windows from
- [`desktop`](../../../crates/komorebi-linux/src/desktop.rs): loads the monitors and the open windows from
the backend, and reads the sizes of the monitors again.
- [`window_manager_event`](../../../komorebi-linux/src/window_manager_event.rs) and
[`process_event`](../../../komorebi-linux/src/process_event.rs): the events, and what the window
- [`window_manager_event`](../../../crates/komorebi-linux/src/window_manager_event.rs) and
[`process_event`](../../../crates/komorebi-linux/src/process_event.rs): the events, and what the window
manager does with each.
- [`window_manager_event_listener`](../../../komorebi-linux/src/window_manager_event_listener.rs): the
- [`window_manager_event_listener`](../../../crates/komorebi-linux/src/window_manager_event_listener.rs): the
channel that carries events from the backend to the window manager, and
[`listen_for_events`], the thread that takes them off it.
- [`monitor_reconciliator`](../../../komorebi-linux/src/monitor_reconciliator.rs): the channel the KWin
- [`monitor_reconciliator`](../../../crates/komorebi-linux/src/monitor_reconciliator.rs): the channel the KWin
backend sends [`MonitorNotification`]s on, [`listen_for_notifications`], the thread that
takes them, and [`reconcile_display_change`], which brings the window manager's monitors in
line with the outputs, and [`wake_up`], which puts the desktop in order after a wake;
[`reconcile`](../../../komorebi-linux/src/reconcile.rs): moves what was on a monitor that went to the
[`reconcile`](../../../crates/komorebi-linux/src/reconcile.rs): moves what was on a monitor that went to the
monitors that are left, and every container whose window is on another monitor to that
monitor.
- [`kwin`](../../../komorebi-linux/src/kwin/mod.rs): the KWin backend, its D-Bus service and the held
call; [`kwin::state`](../../../komorebi-linux/src/kwin/state.rs), the table;
[`kwin::power`](../../../komorebi-linux/src/kwin/power.rs), the watchers of logind's sleep signal and the
- [`kwin`](../../../crates/komorebi-linux/src/kwin/mod.rs): the KWin backend, its D-Bus service and the held
call; [`kwin::state`](../../../crates/komorebi-linux/src/kwin/state.rs), the table;
[`kwin::power`](../../../crates/komorebi-linux/src/kwin/power.rs), the watchers of logind's sleep signal and the
lock screen's;
[`kwin::kwinrc`](../../../komorebi-linux/src/kwin/kwinrc.rs), the editor of the user's `kwinrc`, which
[`kwin::kwinrc`](../../../crates/komorebi-linux/src/kwin/kwinrc.rs), the editor of the user's `kwinrc`, which
keeps the values it changes and puts them back; the parking desktop is made, swept and removed
in `kwin` and tracked in `kwin::state`; and
[`bridge.js`](../../../komorebi-linux/src/kwin/bridge.js), the bridge.
- [`static_config`](../../../komorebi-linux/src/static_config.rs): `komorebi.json`, [`StaticConfig`], and
[`bridge.js`](../../../crates/komorebi-linux/src/kwin/bridge.js), the bridge.
- [`static_config`](../../../crates/komorebi-linux/src/static_config.rs): `komorebi.json`, [`StaticConfig`], and
how it is loaded, reloaded and generated.
- [`border_manager`](../../../komorebi-linux/src/border_manager/mod.rs): the border settings, and the
- [`border_manager`](../../../crates/komorebi-linux/src/border_manager/mod.rs): the border settings, and the
[`Look`] they make, which it asks the backend for.
- [`animation`](../../../komorebi-linux/src/animation/mod.rs): the animation settings, which the look has.
- [`theme_manager`](../../../komorebi-linux/src/theme_manager.rs): a theme's colors for the borders, and the
- [`animation`](../../../crates/komorebi-linux/src/animation/mod.rs): the animation settings, which the look has.
- [`theme_manager`](../../../crates/komorebi-linux/src/theme_manager.rs): a theme's colors for the borders, and the
palettes made from pictures.
- [`kwin::wallpaper`](../../../komorebi-linux/src/kwin/wallpaper.rs): the Plasma shell's side of a
- [`kwin::wallpaper`](../../../crates/komorebi-linux/src/kwin/wallpaper.rs): the Plasma shell's side of a
wallpaper: the screen of an output, what it shows, and the picture set.
- [`transparency_manager`](../../../komorebi-linux/src/transparency_manager.rs): which windows are
- [`transparency_manager`](../../../crates/komorebi-linux/src/transparency_manager.rs): which windows are
see-through, and the opacity they are given.
- [`kwin::effects`](../../../komorebi-linux/src/kwin/effects.rs): the KWin effect that draws the border,
- [`kwin::effects`](../../../crates/komorebi-linux/src/kwin/effects.rs): the KWin effect that draws the border,
its settings and the state komorebi keeps of it.
- [`check`](../../../komorebi-linux/src/check.rs): the checks behind `komorebic check` (the configuration,
- [`check`](../../../crates/komorebi-linux/src/check.rs): the checks behind `komorebic check` (the configuration,
and the desktop it runs on), the [`Finding`]s they return and the [`Report`] `komorebic` gathers
them in.
- [`process_command`](../../../komorebi-linux/src/process_command.rs): the thread that listens on the
- [`process_command`](../../../crates/komorebi-linux/src/process_command.rs): the thread that listens on the
socket, and what the window manager does with each message.
- [`state`](../../../komorebi-linux/src/state.rs): the [`State`] a `State` message is answered with,
- [`state`](../../../crates/komorebi-linux/src/state.rs): the [`State`] a `State` message is answered with,
and whether an event or a message changed it.
- [`lib.rs`](../../../komorebi-linux/src/lib.rs): the subscribers, the [`Notification`], and
- [`lib.rs`](../../../crates/komorebi-linux/src/lib.rs): the subscribers, the [`Notification`], and
[`notify_subscribers`].
- [`komorebi-client`](../../../komorebi-client/src/lib.rs): a library that writes messages on
- [`komorebi-client`](../../../crates/komorebi-client/src/lib.rs): a library that writes messages on
the socket and reads the answers, and subscribes to notifications, for programs that talk
to the daemon.
- [`komorebic`](../../../komorebic/src/linux/mod.rs): the command line. A subcommand that asks
something of the daemon is one message, sent with `komorebi-client`; `start` runs the
daemon, `log` follows its log file in [`LOG_DIR`], and the hidden `docgen` writes
`docs/linux/cli`.
- [`daemon.rs`](../../../komorebi-linux/src/daemon.rs): the daemon. It connects to KWin, or installs the
- [`daemon.rs`](../../../crates/komorebi-linux/src/daemon.rs): the daemon. It connects to KWin, or installs the
fake with `--fake-backend`, makes the window manager from `komorebi.json` when there is one,
which binds the socket, loads the desktop, gives the monitors their configuration, asks for the
borders and tiles, starts the threads that listen on the socket, handle events and take the
@@ -1509,14 +1509,14 @@ the fake. The window manager is its only caller, through [`backend`]. The contra
| A subscriber that wants only changes of the state is sent every change of the monitors | framework path: [`notify_subscribers`] treats a monitor notification as an override of the filter | `a_change_of_the_monitors_is_sent_to_a_subscriber_that_filters_state_changes_too` | none |
| Moving the focus moves no window | test | `focus_gives_the_focus_to_the_window_on_that_side_and_moves_nothing`, `vm-core-e2e` ("moving the focus moved no window") | none |
| A subscriber that is gone is dropped, not retried | test | `a_subscriber_that_is_gone_is_dropped_and_not_tried_again` | none |
| The bridge holds no window manager logic | convention, with every decision about an event in the table, which the `kwin::state` unit tests pin | the unit tests in `komorebi-linux/src/kwin/state.rs` | none |
| The bridge holds no window manager logic | convention, with every decision about an event in the table, which the `kwin::state` unit tests pin | the unit tests in `crates/komorebi-linux/src/kwin/state.rs` | none |
| What the bridge sends is what the table reads | type checker: the JSDoc types of the messages in [`bridge.js`]; tests: the events of [`fixtures`] are what the bridge's tests check it sends and what the table's tests feed it | `what the bridge sends for a session is what the daemon's tests read`, `the_bridges_events_for_a_session_are_the_window_events_komorebi_expects` | none |
| What the backend sends is what the bridge carries out | tests: the commands of [`fixtures`] are what the backend's tests check it sends and what the bridge's tests answer it with, checking what KWin is asked to do for each | `the_commands_of_a_session_go_to_the_bridge_as_the_bridges_tests_answer_it`, `what the bridge sends for a session is what the daemon's tests read`, `a command for a window KWin no longer has is given back, and the rest are carried out` | none |
| Everything the bridge sends over D-Bus is one string | type checker: [`kwin-api.d.ts`] gives `callDBus` one string argument | `tsc`, `every call goes to the daemon's names, with one JSON string` | none |
| The bridge uses nothing a KWin script does not have | type checker: the library is ECMAScript 2016 alone, and KWin's API is what [`kwin-api.d.ts`] declares | `tsc` | a declaration KWin does not match: the VM tests run the bridge in KWin |
| A border takes room around the windows only while the compositor draws it | framework path: [`border_manager::send_notification`] keeps the backend's answer in [`BORDER_DRAWN`], which [`Monitor::update_workspace_globals`] reads | `a_border_the_compositor_draws_takes_room_around_each_window_and_none_is_taken_without_one`, `a_look_is_a_command_once_and_says_whether_borders_are_drawn` | none |
| The compositor is asked for the look after every event, every message and every retile, and only a changed look reaches it | framework path: [`WindowManager::process_event`], [`WindowManager::process_command`] and [`WindowManager::retile_all`] call [`border_manager::send_notification`], and a backend compares with the look it applied last | `the_border_messages_set_the_border_and_the_compositor_is_asked_for_it`, `a_look_is_a_command_once_and_says_whether_borders_are_drawn` | the same look applied twice by the KWin backend is not tested |
| No outline is drawn inside a window, and a border is never thicker than the effect can draw | framework path: [`kwin::effects`](../../../komorebi-linux/src/kwin/effects.rs) sets every inner outline to 0 and clamps the width to 20 | `the_border_is_the_outer_outline_and_nothing_is_drawn_inside_the_window`, `a_border_thicker_than_the_effect_can_draw_is_the_thickest_it_can`, `vm-look` | none |
| No outline is drawn inside a window, and a border is never thicker than the effect can draw | framework path: [`kwin::effects`](../../../crates/komorebi-linux/src/kwin/effects.rs) sets every inner outline to 0 and clamps the width to 20 | `the_border_is_the_outer_outline_and_nothing_is_drawn_inside_the_window`, `a_border_thicker_than_the_effect_can_draw_is_the_thickest_it_can`, `vm-look` | none |
| Every window has the border color of what it is to the layout, and a window whose kind changes has the new one at once | framework path: [`border_manager::update_colours`] is called after every event and every message, from [`border_manager::window_kinds`], and the backend sends the colors it did not send last time | `the_focused_window_has_the_focus_colour_and_the_others_do_not`, `a_locked_container_that_is_not_focused_is_marked`, `a_stack_has_its_own_colour_when_it_has_the_focus`, `a_monocled_window_has_the_monocle_colour`, `a_floating_window_has_the_floating_colour_while_it_has_the_focus`, `border_colours_are_a_command_only_when_they_change`, `vm-features` (section C) | the stock effect: two colors for every window |
| With borders off no window has a color | framework path: [`border_manager::update_colours`] tells the backend an empty list when `BORDER_ENABLED` is false | `with_borders_off_no_window_has_a_colour` | none |
| The settings of one kind of animation win over the global ones, and a global setting clears them | framework path: the arms of [`WindowManager::process_command`] for `Animation`, `AnimationDuration` and `AnimationStyle`, and [`animation::movement_animation`] and [`animation::movement_style`], which read the kind's setting before the global one | `the_animation_messages_set_the_animation_and_the_compositor_is_asked_for_it` | none |
@@ -1608,7 +1608,7 @@ A window is shown, and ends up on a tile:
## Key bindings
[`komorebi-hotkeys`](../../../komorebi-hotkeys/src/lib.rs) is a crate of its own, which does not
[`komorebi-hotkeys`](../../../crates/komorebi-hotkeys/src/lib.rs) is a crate of its own, which does not
depend on the daemon. Its model is the content of a key binding file of any of three hotkey
daemons: skhd (macOS), whkd (Windows) and sxhkd (X11).
@@ -1641,38 +1641,38 @@ daemons: skhd (macOS), whkd (Windows) and sxhkd (X11).
### The parts of the key bindings
- [`qt`](../../../komorebi-hotkeys/src/qt.rs): key names to Qt key codes, in the vocabulary of each
- [`qt`](../../../crates/komorebi-hotkeys/src/qt.rs): key names to Qt key codes, in the vocabulary of each
format (skhd's literals and macOS keycodes, whkd's virtual key names, sxhkd's X keysyms), and
`Combo`, which applies the shifted symbol rule: KWin matches the character a key press
produced, so Alt+Shift+1 is registered as Alt+!.
- [`ir`](../../../komorebi-hotkeys/src/ir.rs): the model.
- [`skhd`](../../../komorebi-hotkeys/src/skhd.rs): reads an skhdrc. A mode may be used before it
- [`ir`](../../../crates/komorebi-hotkeys/src/ir.rs): the model.
- [`skhd`](../../../crates/komorebi-hotkeys/src/skhd.rs): reads an skhdrc. A mode may be used before it
is declared, so each binding waits for the end of the file to be put in its modes. skhd.zig's
`.define` templates and application groups are expanded where they are used.
- [`whkd`](../../../komorebi-hotkeys/src/whkd.rs): reads a whkdrc, in any order of its sections,
- [`whkd`](../../../crates/komorebi-hotkeys/src/whkd.rs): reads a whkdrc, in any order of its sections,
where whkd requires one. `tests/whkd_parser.rs` compares it with whkd's own parser,
`whkd-parser` (a dev-dependency), on every whkdrc of the corpus.
- [`sxhkd`](../../../komorebi-hotkeys/src/sxhkd.rs): reads an sxhkdrc. Braces are expanded first,
- [`sxhkd`](../../../crates/komorebi-hotkeys/src/sxhkd.rs): reads an sxhkdrc. Braces are expanded first,
into one binding per alternative. A chord chain (`a ; b`) is one binding with several combos;
a chain that stays open (`a : b`) is a mode named after its prefix, entered by the prefix and
left by Escape.
- [`parse`](../../../komorebi-hotkeys/src/lib.rs) picks the reader by format.
- [`plan`](../../../komorebi-hotkeys/src/plan.rs): sorts a keymap into static shortcuts and the
- [`parse`](../../../crates/komorebi-hotkeys/src/lib.rs) picks the reader by format.
- [`plan`](../../../crates/komorebi-hotkeys/src/plan.rs): sorts a keymap into static shortcuts and the
engine's keymap, by mode: `Auto` (static where it can be), `Engine` (the default: everything
through the engine) or `Static` (no engine; what needs it is left out with a warning).
- [`engine`](../../../komorebi-hotkeys/src/engine.rs): the engine, a state machine with no I/O and
- [`engine`](../../../crates/komorebi-hotkeys/src/engine.rs): the engine, a state machine with no I/O and
no clock. Its inputs are a press or a release of an active combo, a change of focus, and the
time; after each it computes the active set it wants from the mode, the chord chain being
typed, the focused application and whether it is paused, and returns the commands to run and
the difference with the active set as effects. The daemon carries them out with kglobalacceld
(`setShortcutKeys`, `setInactive`) and feeds it kglobalacceld's signals.
- [`kde`](../../../komorebi-hotkeys/src/kde.rs): writes static shortcuts as `.desktop` files for
- [`kde`](../../../crates/komorebi-hotkeys/src/kde.rs): writes static shortcuts as `.desktop` files for
kglobalacceld (`X-KDE-Shortcuts`, `X-KDE-GlobalAccel-CommandShortcut`, an `Exec` line quoted as
the desktop entry specification requires), and replaces the files it wrote before, and no
other.
- [`text`](../../../komorebi-hotkeys/src/text.rs): what the readers share: line numbers, comments,
- [`text`](../../../crates/komorebi-hotkeys/src/text.rs): what the readers share: line numbers, comments,
continued lines and the diagnostics' wording.
- [`tests/fixtures`](../../../komorebi-hotkeys/tests/fixtures): the corpus, `<case>.skhdrc`,
- [`tests/fixtures`](../../../crates/komorebi-hotkeys/tests/fixtures): the corpus, `<case>.skhdrc`,
`<case>.whkdrc` and `<case>.sxhkdrc`, each case in every format that can express it.
### The front end
@@ -1698,7 +1698,7 @@ the ones `kde::diff` says that plan would write. It reads no file the desktop ha
### The engine in the daemon
[`komorebi-linux/src/kwin/hotkeys.rs`](../../../komorebi-linux/src/kwin/hotkeys.rs) runs the engine against
[`crates/komorebi-linux/src/kwin/hotkeys.rs`](../../../crates/komorebi-linux/src/kwin/hotkeys.rs) runs the engine against
kglobalaccel, on a session bus connection and a thread of its own. The daemon reads the file
it is given with `--keybindings` (or the first it finds in the config directory), plans it in
`--keybindings-mode`, and hands the plan's engine keymap to `kwin::hotkeys::start`, unless the
@@ -1785,56 +1785,56 @@ plan needs no engine. A failure to start is logged, and the window manager runs
## Where to look in the code
- [`komorebi-linux/src/backend/mod.rs`](../../../komorebi-linux/src/backend/mod.rs): the trait.
- [`komorebi-linux/src/backend/fake.rs`](../../../komorebi-linux/src/backend/fake.rs): the fake and its
- [`crates/komorebi-linux/src/backend/mod.rs`](../../../crates/komorebi-linux/src/backend/mod.rs): the trait.
- [`crates/komorebi-linux/src/backend/fake.rs`](../../../crates/komorebi-linux/src/backend/fake.rs): the fake and its
tests.
- [`komorebi-linux/src/core/mod.rs`](../../../komorebi-linux/src/core/mod.rs): the vocabulary the rest is written
- [`crates/komorebi-linux/src/core/mod.rs`](../../../crates/komorebi-linux/src/core/mod.rs): the vocabulary the rest is written
in.
- [`komorebi-linux/src/workspace.rs`](../../../komorebi-linux/src/workspace.rs): tiling, in
- [`crates/komorebi-linux/src/workspace.rs`](../../../crates/komorebi-linux/src/workspace.rs): tiling, in
`Workspace::update`.
- [`komorebi-linux/src/monitor.rs`](../../../komorebi-linux/src/monitor.rs): the work area, padding and
- [`crates/komorebi-linux/src/monitor.rs`](../../../crates/komorebi-linux/src/monitor.rs): the work area, padding and
offset a monitor gives the workspace it shows.
- [`komorebi-linux/src/static_config.rs`](../../../komorebi-linux/src/static_config.rs): `komorebi.json`.
[`komorebi-linux/tests/config.rs`](../../../komorebi-linux/tests/config.rs) loads files over the fake
desktop, [`komorebi-linux/tests/config_displays.rs`](../../../komorebi-linux/tests/config_displays.rs) one
with several monitors, [`komorebi-daemon/tests/linux_hot_reload.rs`](../../../komorebi-daemon/tests/linux_hot_reload.rs) the
- [`crates/komorebi-linux/src/static_config.rs`](../../../crates/komorebi-linux/src/static_config.rs): `komorebi.json`.
[`crates/komorebi-linux/tests/config.rs`](../../../crates/komorebi-linux/tests/config.rs) loads files over the fake
desktop, [`crates/komorebi-linux/tests/config_displays.rs`](../../../crates/komorebi-linux/tests/config_displays.rs) one
with several monitors, [`komorebi/tests/linux_hot_reload.rs`](../../../komorebi/tests/linux_hot_reload.rs) the
daemon following a file, and
[`komorebi-linux/tests/config_parity.rs`](../../../komorebi-linux/tests/config_parity.rs) the files of other
[`crates/komorebi-linux/tests/config_parity.rs`](../../../crates/komorebi-linux/tests/config_parity.rs) the files of other
platforms and the example, which load;
[`komorebi-linux/tests/replace_configuration.rs`](../../../komorebi-linux/tests/replace_configuration.rs)
[`crates/komorebi-linux/tests/replace_configuration.rs`](../../../crates/komorebi-linux/tests/replace_configuration.rs)
the `ReplaceConfiguration` message;
[`komorebi-linux/tests/workspace_rules.rs`](../../../komorebi-linux/tests/workspace_rules.rs) the workspace
rules; [`komorebi-linux/tests/schemas.rs`](../../../komorebi-linux/tests/schemas.rs) the schemas the daemon answers
[`crates/komorebi-linux/tests/workspace_rules.rs`](../../../crates/komorebi-linux/tests/workspace_rules.rs) the workspace
rules; [`crates/komorebi-linux/tests/schemas.rs`](../../../crates/komorebi-linux/tests/schemas.rs) the schemas the daemon answers
with; [`schemas/linux/schema.json`](../../../schemas/linux/schema.json), [`schemas/linux/schema.asc.json`](../../../schemas/linux/schema.asc.json) and
[`nix/linux/komorebi-options.nix`](../../../nix/linux/komorebi-options.nix), which are generated;
[`nix/linux/tests/default.nix`](../../../nix/linux/tests/default.nix) and
[`nix/linux/tests/komorebi-example.nix`](../../../nix/linux/tests/komorebi-example.nix), the check of the options
and the example it evaluates them against; [`komorebi-linux/tests/asc.rs`](../../../komorebi-linux/tests/asc.rs)
the applications files; [`komorebi-linux/src/core/asc.rs`](../../../komorebi-linux/src/core/asc.rs) their
and the example it evaluates them against; [`crates/komorebi-linux/tests/asc.rs`](../../../crates/komorebi-linux/tests/asc.rs)
the applications files; [`crates/komorebi-linux/src/core/asc.rs`](../../../crates/komorebi-linux/src/core/asc.rs) their
format.
- [`komorebi-linux/src/check.rs`](../../../komorebi-linux/src/check.rs): the checks of `komorebic check`, with
- [`crates/komorebi-linux/src/check.rs`](../../../crates/komorebi-linux/src/check.rs): the checks of `komorebic check`, with
their tests; [`komorebic/tests/linux_check.rs`](../../../komorebic/tests/linux_check.rs) runs the command on
configurations, on key binding files and on buses that are not there, and reads what it prints
and its exit status;
[`nix/linux/tests/vm/suites/check/test.py`](../../../nix/linux/tests/vm/suites/check/test.py), the desktop check against
a real KWin, with the daemon running, with its script gone, with no daemon and with no KWin.
- [`komorebi-linux/src/process_event.rs`](../../../komorebi-linux/src/process_event.rs): what each event
- [`crates/komorebi-linux/src/process_event.rs`](../../../crates/komorebi-linux/src/process_event.rs): what each event
does, and the thread that handles them.
- [`komorebi-linux/src/process_command.rs`](../../../komorebi-linux/src/process_command.rs): the socket, what
- [`crates/komorebi-linux/src/process_command.rs`](../../../crates/komorebi-linux/src/process_command.rs): the socket, what
each message does, and the tests that send messages through a real socket.
- [`komorebi-client/src/lib.rs`](../../../komorebi-client/src/lib.rs): the client side of the
- [`crates/komorebi-client/src/lib.rs`](../../../crates/komorebi-client/src/lib.rs): the client side of the
socket.
- [`komorebi-client/tests/linux_subscribe.rs`](../../../komorebi-client/tests/linux_subscribe.rs):
- [`crates/komorebi-client/tests/linux_subscribe.rs`](../../../crates/komorebi-client/tests/linux_subscribe.rs):
subscribers and the notifications they are sent, through real sockets.
- [`komorebic/src/linux/mod.rs`](../../../komorebic/src/linux/mod.rs): the subcommands, and
[`komorebic/tests/linux_cli.rs`](../../../komorebic/tests/linux_cli.rs), what each writes on the socket.
- [`komorebi-linux/src/kwin/mod.rs`](../../../komorebi-linux/src/kwin/mod.rs): the KWin backend, its D-Bus
- [`crates/komorebi-linux/src/kwin/mod.rs`](../../../crates/komorebi-linux/src/kwin/mod.rs): the KWin backend, its D-Bus
service and the held call.
- [`komorebi-linux/src/kwin/state.rs`](../../../komorebi-linux/src/kwin/state.rs): the table, with the
- [`crates/komorebi-linux/src/kwin/state.rs`](../../../crates/komorebi-linux/src/kwin/state.rs): the table, with the
shapes of the bridge's events, and its tests.
- [`komorebi-linux/src/kwin/bridge.js`](../../../komorebi-linux/src/kwin/bridge.js): the bridge, with the
- [`crates/komorebi-linux/src/kwin/bridge.js`](../../../crates/komorebi-linux/src/kwin/bridge.js): the bridge, with the
types of its messages; [`kwin-api.d.ts`] and
[`tsconfig.json`](../../../komorebi-linux/src/kwin/tsconfig.json), what `tsc` checks it against;
[`tsconfig.json`](../../../crates/komorebi-linux/src/kwin/tsconfig.json), what `tsc` checks it against;
[`bridge.test.js`], its tests; [`fixtures`], the messages both sides' tests read.
- [`nix/linux/tests/vm/suites/kwin-events/test.py`](../../../nix/linux/tests/vm/suites/kwin-events/test.py): the
events of a real KWin, through the daemon.
@@ -1853,65 +1853,65 @@ plan needs no engine. A failure to start is logged, and the window manager runs
curve a setting; and
[`nix/linux/tests/effects.nix`](../../../nix/linux/tests/effects.nix), the checks of the files each effect
package installs.
- [`komorebi-linux/tests/borders.rs`](../../../komorebi-linux/tests/borders.rs) and
[`komorebi-linux/tests/border_commands.rs`](../../../komorebi-linux/tests/border_commands.rs): the room a drawn
- [`crates/komorebi-linux/tests/borders.rs`](../../../crates/komorebi-linux/tests/borders.rs) and
[`crates/komorebi-linux/tests/border_commands.rs`](../../../crates/komorebi-linux/tests/border_commands.rs): the room a drawn
border takes, and the messages that set the border, against the fake;
[`komorebi-linux/tests/animation.rs`](../../../komorebi-linux/tests/animation.rs), the messages that set the
animation, [`komorebi-linux/tests/animation_config.rs`](../../../komorebi-linux/tests/animation_config.rs), its
key of the file, and [`komorebi-linux/tests/animation_stack.rs`](../../../komorebi-linux/tests/animation_stack.rs),
the stack commands that turn it off; [`komorebi-linux/tests/themes.rs`](../../../komorebi-linux/tests/themes.rs),
a named theme and [`komorebi-linux/tests/theme_config.rs`](../../../komorebi-linux/tests/theme_config.rs), the
colors and the theme of the file; [`komorebi-linux/tests/focus_follows_mouse.rs`](../../../komorebi-linux/tests/focus_follows_mouse.rs),
focus follows mouse; [`komorebi-linux/tests/transparency.rs`](../../../komorebi-linux/tests/transparency.rs)
and [`komorebi-linux/tests/transparency_config.rs`](../../../komorebi-linux/tests/transparency_config.rs),
transparency and its keys of the file; [`komorebi-linux/tests/border_colours.rs`](../../../komorebi-linux/tests/border_colours.rs) and
[`komorebi-linux/tests/borders_off.rs`](../../../komorebi-linux/tests/borders_off.rs), the color of each
[`crates/komorebi-linux/tests/animation.rs`](../../../crates/komorebi-linux/tests/animation.rs), the messages that set the
animation, [`crates/komorebi-linux/tests/animation_config.rs`](../../../crates/komorebi-linux/tests/animation_config.rs), its
key of the file, and [`crates/komorebi-linux/tests/animation_stack.rs`](../../../crates/komorebi-linux/tests/animation_stack.rs),
the stack commands that turn it off; [`crates/komorebi-linux/tests/themes.rs`](../../../crates/komorebi-linux/tests/themes.rs),
a named theme and [`crates/komorebi-linux/tests/theme_config.rs`](../../../crates/komorebi-linux/tests/theme_config.rs), the
colors and the theme of the file; [`crates/komorebi-linux/tests/focus_follows_mouse.rs`](../../../crates/komorebi-linux/tests/focus_follows_mouse.rs),
focus follows mouse; [`crates/komorebi-linux/tests/transparency.rs`](../../../crates/komorebi-linux/tests/transparency.rs)
and [`crates/komorebi-linux/tests/transparency_config.rs`](../../../crates/komorebi-linux/tests/transparency_config.rs),
transparency and its keys of the file; [`crates/komorebi-linux/tests/border_colours.rs`](../../../crates/komorebi-linux/tests/border_colours.rs) and
[`crates/komorebi-linux/tests/borders_off.rs`](../../../crates/komorebi-linux/tests/borders_off.rs), the color of each
window's border, and none with borders off;
[`nix/linux/tests/vm/suites/look/test.py`](../../../nix/linux/tests/vm/suites/look/test.py), the border in a real
Plasma session, read from the pixels of a screenshot, and
[`nix/linux/tests/vm/suites/features/test.py`](../../../nix/linux/tests/vm/suites/features/test.py), the colors of the
kinds of window; [`nix/linux/tests/vm/suites/focus-follows-mouse/test.py`](../../../nix/linux/tests/vm/suites/focus-follows-mouse/test.py),
focus follows mouse with a real pointer, which [`Pointer`](../../../nix/linux/tests/vm/lib/komorebi_vm/pointer.py)
moves from inside the guest; [`komorebi-linux/tests/wallpaper.rs`](../../../komorebi-linux/tests/wallpaper.rs), the
moves from inside the guest; [`crates/komorebi-linux/tests/wallpaper.rs`](../../../crates/komorebi-linux/tests/wallpaper.rs), the
wallpapers and the colors made of them, against the fake; and
[`nix/linux/tests/vm/suites/wallpaper/test.py`](../../../nix/linux/tests/vm/suites/wallpaper/test.py), against the
real Plasma shell.
- [`komorebi-linux/tests/wm_events.rs`](../../../komorebi-linux/tests/wm_events.rs): the window manager
- [`crates/komorebi-linux/tests/wm_events.rs`](../../../crates/komorebi-linux/tests/wm_events.rs): the window manager
driven end to end against the fake.
- [`komorebi-daemon/tests/linux_socket.rs`](../../../komorebi-daemon/tests/linux_socket.rs): the daemon over its socket,
- [`komorebi/tests/linux_socket.rs`](../../../komorebi/tests/linux_socket.rs): the daemon over its socket,
from its start to a `Stop`.
- [`komorebi-linux/tests/focus.rs`](../../../komorebi-linux/tests/focus.rs),
[`komorebi-linux/tests/moving.rs`](../../../komorebi-linux/tests/moving.rs) and
[`komorebi-linux/tests/layouts.rs`](../../../komorebi-linux/tests/layouts.rs): the focus, move and layout
- [`crates/komorebi-linux/tests/focus.rs`](../../../crates/komorebi-linux/tests/focus.rs),
[`crates/komorebi-linux/tests/moving.rs`](../../../crates/komorebi-linux/tests/moving.rs) and
[`crates/komorebi-linux/tests/layouts.rs`](../../../crates/komorebi-linux/tests/layouts.rs): the focus, move and layout
commands against the fake;
[`komorebi-linux/tests/layout_options.rs`](../../../komorebi-linux/tests/layout_options.rs) and
[`komorebi-linux/tests/scrolling.rs`](../../../komorebi-linux/tests/scrolling.rs), the layout options and the
scrolling layout; [`komorebi-linux/tests/resize.rs`](../../../komorebi-linux/tests/resize.rs), resizing;
[`komorebi-linux/tests/promote.rs`](../../../komorebi-linux/tests/promote.rs), promoting;
[`komorebi-linux/tests/float.rs`](../../../komorebi-linux/tests/float.rs), floating;
[`komorebi-linux/tests/lock.rs`](../../../komorebi-linux/tests/lock.rs), locking;
[`komorebi-linux/tests/floating_layer.rs`](../../../komorebi-linux/tests/floating_layer.rs), the layers;
[`komorebi-linux/tests/monocle.rs`](../../../komorebi-linux/tests/monocle.rs), the monocle;
[`komorebi-linux/tests/maximize.rs`](../../../komorebi-linux/tests/maximize.rs) and
[`komorebi-linux/tests/maximize_commands.rs`](../../../komorebi-linux/tests/maximize_commands.rs), maximizing;
[`komorebi-linux/tests/user_maximize.rs`](../../../komorebi-linux/tests/user_maximize.rs) and
[`komorebi-linux/tests/user_maximize_cases.rs`](../../../komorebi-linux/tests/user_maximize_cases.rs), a window
[`crates/komorebi-linux/tests/layout_options.rs`](../../../crates/komorebi-linux/tests/layout_options.rs) and
[`crates/komorebi-linux/tests/scrolling.rs`](../../../crates/komorebi-linux/tests/scrolling.rs), the layout options and the
scrolling layout; [`crates/komorebi-linux/tests/resize.rs`](../../../crates/komorebi-linux/tests/resize.rs), resizing;
[`crates/komorebi-linux/tests/promote.rs`](../../../crates/komorebi-linux/tests/promote.rs), promoting;
[`crates/komorebi-linux/tests/float.rs`](../../../crates/komorebi-linux/tests/float.rs), floating;
[`crates/komorebi-linux/tests/lock.rs`](../../../crates/komorebi-linux/tests/lock.rs), locking;
[`crates/komorebi-linux/tests/floating_layer.rs`](../../../crates/komorebi-linux/tests/floating_layer.rs), the layers;
[`crates/komorebi-linux/tests/monocle.rs`](../../../crates/komorebi-linux/tests/monocle.rs), the monocle;
[`crates/komorebi-linux/tests/maximize.rs`](../../../crates/komorebi-linux/tests/maximize.rs) and
[`crates/komorebi-linux/tests/maximize_commands.rs`](../../../crates/komorebi-linux/tests/maximize_commands.rs), maximizing;
[`crates/komorebi-linux/tests/user_maximize.rs`](../../../crates/komorebi-linux/tests/user_maximize.rs) and
[`crates/komorebi-linux/tests/user_maximize_cases.rs`](../../../crates/komorebi-linux/tests/user_maximize_cases.rs), a window
the user maximizes;
[`komorebi-linux/tests/fullscreen.rs`](../../../komorebi-linux/tests/fullscreen.rs), a window that goes
[`crates/komorebi-linux/tests/fullscreen.rs`](../../../crates/komorebi-linux/tests/fullscreen.rs), a window that goes
fullscreen and comes back;
[`komorebi-linux/tests/placement.rs`](../../../komorebi-linux/tests/placement.rs) and
[`komorebi-linux/tests/placement_cases.rs`](../../../komorebi-linux/tests/placement_cases.rs), the placement
[`crates/komorebi-linux/tests/placement.rs`](../../../crates/komorebi-linux/tests/placement.rs) and
[`crates/komorebi-linux/tests/placement_cases.rs`](../../../crates/komorebi-linux/tests/placement_cases.rs), the placement
rules;
[`komorebi-linux/tests/manage.rs`](../../../komorebi-linux/tests/manage.rs), minimizing, closing,
[`crates/komorebi-linux/tests/manage.rs`](../../../crates/komorebi-linux/tests/manage.rs), minimizing, closing,
unmanaging and managing the focused window, and pausing;
[`komorebi-linux/tests/padding.rs`](../../../komorebi-linux/tests/padding.rs), the paddings and the work area
offsets; [`komorebi-linux/tests/rules.rs`](../../../komorebi-linux/tests/rules.rs) and
[`komorebi-linux/tests/rule_commands.rs`](../../../komorebi-linux/tests/rule_commands.rs), the rules and the
[`crates/komorebi-linux/tests/padding.rs`](../../../crates/komorebi-linux/tests/padding.rs), the paddings and the work area
offsets; [`crates/komorebi-linux/tests/rules.rs`](../../../crates/komorebi-linux/tests/rules.rs) and
[`crates/komorebi-linux/tests/rule_commands.rs`](../../../crates/komorebi-linux/tests/rule_commands.rs), the rules and the
messages that add and show them;
[`komorebi-linux/tests/drag_swap.rs`](../../../komorebi-linux/tests/drag_swap.rs), dragging a window onto
[`crates/komorebi-linux/tests/drag_swap.rs`](../../../crates/komorebi-linux/tests/drag_swap.rs), dragging a window onto
another tile and onto another monitor;
[`komorebi-linux/tests/drag_resize.rs`](../../../komorebi-linux/tests/drag_resize.rs), dragging an edge;
[`komorebi-linux/tests/live_resize.rs`](../../../komorebi-linux/tests/live_resize.rs), the neighbors following
[`crates/komorebi-linux/tests/drag_resize.rs`](../../../crates/komorebi-linux/tests/drag_resize.rs), dragging an edge;
[`crates/komorebi-linux/tests/live_resize.rs`](../../../crates/komorebi-linux/tests/live_resize.rs), the neighbors following
it.
- [`nix/linux/tests/vm/suites/scrolling/test.py`](../../../nix/linux/tests/vm/suites/scrolling/test.py): the scrolling
strip in a real KWin, with its columns out of view off the screen.
@@ -1927,26 +1927,26 @@ plan needs no engine. A failure to start is logged, and the window manager runs
corners dragged with a pointer in a Plasma session;
[`nix/linux/tests/vm/suites/live-resize/test.py`](../../../nix/linux/tests/vm/suites/live-resize/test.py), the
neighbors read while the edge is held.
- [`komorebi-linux/tests/monitor_resize.rs`](../../../komorebi-linux/tests/monitor_resize.rs),
[`komorebi-linux/tests/hotplug.rs`](../../../komorebi-linux/tests/hotplug.rs) and
[`komorebi-linux/tests/follow_output.rs`](../../../komorebi-linux/tests/follow_output.rs): a monitor that
- [`crates/komorebi-linux/tests/monitor_resize.rs`](../../../crates/komorebi-linux/tests/monitor_resize.rs),
[`crates/komorebi-linux/tests/hotplug.rs`](../../../crates/komorebi-linux/tests/hotplug.rs) and
[`crates/komorebi-linux/tests/follow_output.rs`](../../../crates/komorebi-linux/tests/follow_output.rs): a monitor that
changes size, monitors that are unplugged and plugged in, and windows that move to another
output, against the fake;
[`nix/linux/tests/vm/suites/hotplug/test.py`](../../../nix/linux/tests/vm/suites/hotplug/test.py), both against a real
KWin with two outputs.
- [`komorebi-linux/tests/wake.rs`](../../../komorebi-linux/tests/wake.rs): the desktop after a wake, against the
fake; [`komorebi-linux/tests/power.rs`](../../../komorebi-linux/tests/power.rs), the signals of logind and
- [`crates/komorebi-linux/tests/wake.rs`](../../../crates/komorebi-linux/tests/wake.rs): the desktop after a wake, against the
fake; [`crates/komorebi-linux/tests/power.rs`](../../../crates/komorebi-linux/tests/power.rs), the signals of logind and
of the lock screen, on private buses;
[`nix/linux/tests/vm/suites/lock-sleep/test.py`](../../../nix/linux/tests/vm/suites/lock-sleep/test.py), the lock
screen of a real Plasma session.
- [`komorebi-linux/tests/workspaces.rs`](../../../komorebi-linux/tests/workspaces.rs): workspaces as the
- [`crates/komorebi-linux/tests/workspaces.rs`](../../../crates/komorebi-linux/tests/workspaces.rs): workspaces as the
fake's desktops;
[`komorebi-linux/tests/workspace_commands.rs`](../../../komorebi-linux/tests/workspace_commands.rs), naming,
[`crates/komorebi-linux/tests/workspace_commands.rs`](../../../crates/komorebi-linux/tests/workspace_commands.rs), naming,
cycling and the other workspace commands;
[`komorebi-linux/tests/monitors.rs`](../../../komorebi-linux/tests/monitors.rs), two monitors: crossing from
one to the other, the monitor commands and `EagerFocus`; [`komorebi-linux/src/kwin/kwinrc.rs`](../../../komorebi-linux/src/kwin/kwinrc.rs), the
[`crates/komorebi-linux/tests/monitors.rs`](../../../crates/komorebi-linux/tests/monitors.rs), two monitors: crossing from
one to the other, the monitor commands and `EagerFocus`; [`crates/komorebi-linux/src/kwin/kwinrc.rs`](../../../crates/komorebi-linux/src/kwin/kwinrc.rs), the
`kwinrc` editor and its tests.
- [`komorebi-linux/tests/stacks.rs`](../../../komorebi-linux/tests/stacks.rs): stacking, unstacking and the windows
- [`crates/komorebi-linux/tests/stacks.rs`](../../../crates/komorebi-linux/tests/stacks.rs): stacking, unstacking and the windows
a stack hides, the behavior of new windows and the float override, against the fake;
[`nix/linux/tests/vm/suites/stacks/test.py`](../../../nix/linux/tests/vm/suites/stacks/test.py), the same in a real
KWin, with the parking desktop, a crash and a stop.
@@ -1958,25 +1958,25 @@ plan needs no engine. A failure to start is logged, and the window manager runs
[`nix/linux/tests/vm/suites/kwin-contract/test.py`](../../../nix/linux/tests/vm/suites/kwin-contract/test.py), the
behavior of KWin's per-output virtual desktops komorebi relies on, with two outputs and no
komorebi.
- [`komorebi-hotkeys/src/lib.rs`](../../../komorebi-hotkeys/src/lib.rs): the key binding model,
[`komorebi-hotkeys/src/qt.rs`](../../../komorebi-hotkeys/src/qt.rs) the keys, and one module per
format, [`skhd.rs`](../../../komorebi-hotkeys/src/skhd.rs),
[`whkd.rs`](../../../komorebi-hotkeys/src/whkd.rs) and
[`sxhkd.rs`](../../../komorebi-hotkeys/src/sxhkd.rs);
[`plan.rs`](../../../komorebi-hotkeys/src/plan.rs) and [`kde.rs`](../../../komorebi-hotkeys/src/kde.rs)
for the shortcuts, [`engine.rs`](../../../komorebi-hotkeys/src/engine.rs) for the engine.
- [`crates/komorebi-hotkeys/src/lib.rs`](../../../crates/komorebi-hotkeys/src/lib.rs): the key binding model,
[`crates/komorebi-hotkeys/src/qt.rs`](../../../crates/komorebi-hotkeys/src/qt.rs) the keys, and one module per
format, [`skhd.rs`](../../../crates/komorebi-hotkeys/src/skhd.rs),
[`whkd.rs`](../../../crates/komorebi-hotkeys/src/whkd.rs) and
[`sxhkd.rs`](../../../crates/komorebi-hotkeys/src/sxhkd.rs);
[`plan.rs`](../../../crates/komorebi-hotkeys/src/plan.rs) and [`kde.rs`](../../../crates/komorebi-hotkeys/src/kde.rs)
for the shortcuts, [`engine.rs`](../../../crates/komorebi-hotkeys/src/engine.rs) for the engine.
- [`komorebic/src/linux/hotkeys.rs`](../../../komorebic/src/linux/hotkeys.rs): `export-kde-shortcuts` and
`hotkeys compile`, and the key bindings section of `komorebic check`;
[`komorebic/tests/linux_hotkeys.rs`](../../../komorebic/tests/linux_hotkeys.rs), what they write.
- [`nix/linux/tests/vm/suites/keys-static/test.py`](../../../nix/linux/tests/vm/suites/keys-static/test.py): static
shortcuts run by a real KWin.
- [`komorebi-linux/src/kwin/hotkeys.rs`](../../../komorebi-linux/src/kwin/hotkeys.rs): the engine against
- [`crates/komorebi-linux/src/kwin/hotkeys.rs`](../../../crates/komorebi-linux/src/kwin/hotkeys.rs): the engine against
kglobalaccel, and
[`nix/linux/tests/vm/suites/keys-engine/test.py`](../../../nix/linux/tests/vm/suites/keys-engine/test.py), keys
pressed in a real KWin with the daemon running;
[`nix/linux/tests/vm/suites/restart-survival/test.py`](../../../nix/linux/tests/vm/suites/restart-survival/test.py),
the keys when the daemon and KWin go away.
- [`komorebi-hotkeys/tests`](../../../komorebi-hotkeys/tests): the corpus test and the comparison
- [`crates/komorebi-hotkeys/tests`](../../../crates/komorebi-hotkeys/tests): the corpus test and the comparison
with `whkd-parser`.
- [`nix/linux/tests/keybindings.nix`](../../../nix/linux/tests/keybindings.nix): `keybindings-fixtures`, and
[`nix/linux/tests/vm/keys-corpus.py`](../../../nix/linux/tests/vm/keys-corpus.py), the corpus case `vm`
@@ -2260,8 +2260,8 @@ plan needs no engine. A failure to start is logged, and the window manager runs
[`WindowManager::process_command`]: ../../komorebi/src/process_command.rs
[`listen_for_commands`]: ../../komorebi/src/process_command.rs
[`read_commands_uds`]: ../../komorebi/src/process_command.rs
[`send_query`]: ../../komorebi-client/src/lib.rs
[`send_message`]: ../../komorebi-client/src/lib.rs
[`send_batch`]: ../../komorebi-client/src/lib.rs
[`subscribe`]: ../../komorebi-client/src/lib.rs
[`subscribe_with_options`]: ../../komorebi-client/src/lib.rs
[`send_query`]: ../../crates/komorebi-client/src/lib.rs
[`send_message`]: ../../crates/komorebi-client/src/lib.rs
[`send_batch`]: ../../crates/komorebi-client/src/lib.rs
[`subscribe`]: ../../crates/komorebi-client/src/lib.rs
[`subscribe_with_options`]: ../../crates/komorebi-client/src/lib.rs
+3 -3
View File
@@ -173,7 +173,7 @@ from the enum rather than the hand-written deserializer, describes the type as o
description of the case and the reason, and records the case that way, whether the daemon does not
start or puts the windows elsewhere. The other four cases give the same order on both ports.
Fixed upstream in kfw (`3b424dd7`: accept an integer as well as a string, and a schema written by hand);
kfde already had the same fix, and its unit test is in `komorebi-linux/src/core/mod.rs`. A Windows run
kfde already had the same fix, and its unit test is in `crates/komorebi-linux/src/core/mod.rs`. A Windows run
of kfw's `next` passes all 5 cases.
**`hotplug` on kfw (fixed upstream).** After a display is unplugged, Windows reports one display within a second,
@@ -244,7 +244,7 @@ window it did not have again as a `Show` on a title change, so that a rule on th
decided (windows are often announced before their title is set), and a window that renamed itself
away from an ignore rule was tiled. The `title_rule` scenario found the difference (kfw's first
Windows run: the window was never managed). The decision is that the ports match, and kfde changed:
`WindowManagerEvent::TitleUpdate` does nothing, the unit tests in `komorebi-linux/tests/rule_commands.rs`
`WindowManagerEvent::TitleUpdate` does nothing, the unit tests in `crates/komorebi-linux/tests/rule_commands.rs`
say so, and `title_rule` asserts it on both ports. Passes on a real KWin (5 checks). The price on
KDE: a window that opens with no title and gets one later is decided by the rules on the empty
title only.
@@ -314,7 +314,7 @@ set of five had one run lose its agent for over a minute, mid-sweep, which nothi
## Does a broken daemon turn them red
On kfde, with a real KWin: `komorebi-linux/src/workspace.rs` was changed, for one run and never
On kfde, with a real KWin: `crates/komorebi-linux/src/workspace.rs` was changed, for one run and never
committed, to make every tile 200 pixels too wide after the layout is calculated, so that tiles
overlap. `core-e2e` failed 7 checks and passed 139: the overlap checks of the suite's own first
tiling and of the `tiling` scenario (two each), the one in the suite that says two windows share
+13 -13
View File
@@ -295,7 +295,7 @@ window in the task manager would leave the monitor showing the parking desktop,
on it but hidden windows. The table sends the monitor straight back to the desktop it showed
before, and the window's own focus change then brings it to the front of its stack.
komorebi keeps a table of the windows it hid, [`HIDDEN_WINDOWS`](../../../komorebi-linux/src/lib.rs), and
komorebi keeps a table of the windows it hid, [`HIDDEN_WINDOWS`](../../../crates/komorebi-linux/src/lib.rs), and
records a window in it before it asks the backend to hide it. What the compositor reports about a
hidden window (a minimize, a move to another desktop) is the echo of a command komorebi sent, and
the window manager has to be able to tell that from the user's own: a window that the user
@@ -304,9 +304,9 @@ minimizes leaves the layout, and one komorebi hid does not.
## Why is the monocle container not one of the containers?
Because a layout gives every container a tile, and the monocle container is the one that has the
whole work area. [`Workspace::new_monocle_container`](../../../komorebi-linux/src/workspace.rs) takes the
whole work area. [`Workspace::new_monocle_container`](../../../crates/komorebi-linux/src/workspace.rs) takes the
focused container out of the workspace's containers and remembers its index, and
[`Workspace::update`](../../../komorebi-linux/src/workspace.rs) puts the window of the monocle container on
[`Workspace::update`](../../../crates/komorebi-linux/src/workspace.rs) puts the window of the monocle container on
the work area and gives the other containers no tile. The container is taken out and put back
with the plain remove and insert of the ring, and not the ones that respect locked containers:
the comments of the code say that a monocle, like a maximize, takes over the whole screen before
@@ -325,7 +325,7 @@ adjustment of the container in monocle would be lost when it came back (the comm
Because KWin has a maximize of its own, and komorebi asks for it. The window gets the work area of
its output with the panels left alone, and a restore goes back to where the window was
(see the comment in the bridge where it carries the command out). It is the work
area and not the padded one that [`Workspace::update`](../../../komorebi-linux/src/workspace.rs) maximizes
area and not the padded one that [`Workspace::update`](../../../crates/komorebi-linux/src/workspace.rs) maximizes
a window to ("the compositor's own maximize, which is the work area and not the padded one"), so
the window cannot be a container: a layout would give it a tile, less the padding. It is held in
`maximized_window` instead, with the index it came from, and when it is restored it goes back to
@@ -427,7 +427,7 @@ default, and its check asserts it, so that an update of the effect cannot change
Because the compositor has the frames, the corners and the shadows of the windows, and komorebi
has none of them. komorebi decides what the windows look like and describes it to the backend as a
`Look` ([`Backend::apply_look`](../../../komorebi-linux/src/backend/mod.rs)); on KWin the effect KDE
`Look` ([`Backend::apply_look`](../../../crates/komorebi-linux/src/backend/mod.rs)); on KWin the effect KDE
Rounded Corners draws it, and komorebi writes the effect's settings. The same code that decides the
look then runs against the fake desktop, which records the look it was asked for.
@@ -470,7 +470,7 @@ build every kind falls back to the two colors of the look, and komorebi says so
Because the compositor draws the windows: an animation komorebi made would be a series of frames
asked of KWin, each a command, where the Geometry Change effect animates what is painted, in the
compositor, at the refresh rate of the screen. komorebi tells the effect how long an animation
lasts ([`border_manager::current_look`](../../../komorebi-linux/src/border_manager/mod.rs)). That is why
lasts ([`border_manager::current_look`](../../../crates/komorebi-linux/src/border_manager/mod.rs)). That is why
`animation-fps` is accepted and does nothing, and why the frame KWin reports for a window is the
final one from the start of the animation: the effect moves what is painted and not the window
([PLATFORM.md](PLATFORM.md#kwin-effects)).
@@ -485,7 +485,7 @@ resize, and what the window shows does not change.
Because KWin animates with `QEasingCurve`, and a style is a curve KWin has when it is Qt's name
without the "Ease": `EaseInOutSine` is `InOutSine`
([`QtCurve::qt_curve`](../../../komorebi-linux/src/core/animation.rs)). A custom cubic Bézier is not
([`QtCurve::qt_curve`](../../../crates/komorebi-linux/src/core/animation.rs)). A custom cubic Bézier is not
one of Qt's curves, and is drawn as an ease out, the kind of curve a window moving to its place
wants. The stock Geometry Change has one curve, an exponential ease out, so komorebi's build of
it reads a `Curve` setting ([PLATFORM.md](PLATFORM.md#the-patches)).
@@ -493,7 +493,7 @@ it reads a `Curve` setting ([PLATFORM.md](PLATFORM.md#the-patches)).
## Why does the window manager keep the opacity it gave each window?
So that the backend is told only what changed. `transparency_manager::apply`
([`transparency_manager.rs`](../../../komorebi-linux/src/transparency_manager.rs)) is called after every
([`transparency_manager.rs`](../../../crates/komorebi-linux/src/transparency_manager.rs)) is called after every
event and every message, and most of them change no window's opacity: the window manager keeps
the opacity it gave each window that is not opaque (`WindowManager::opacity_applied`), sends the
difference, makes a window opaque again when it should no longer be see-through (and only if it is
@@ -683,7 +683,7 @@ already as it asked, but the user's title bar does it without komorebi's knowing
stayed a tile would be asked to move at the next retile: the code that reads the windows that are
open when komorebi starts says a window that is already maximized is "the maximized window, not a tile
that would be asked to leave the maximized state". So
[`WindowManager::adopt_maximize_change`](../../../komorebi-linux/src/window_manager.rs) takes the window out of
[`WindowManager::adopt_maximize_change`](../../../crates/komorebi-linux/src/window_manager.rs) takes the window out of
the layout as `toggle-maximize` makes a window leave it, and what is asked of the layout does
nothing "until it is restored, by `toggle-maximize` or by the user" (the comment in
`process_command`). Because the report is the same either way, one comparison serves both: a window
@@ -692,7 +692,7 @@ that is, or is not, already the workspace's maximized window changes nothing.
## Why does komorebi leave a fullscreen window alone, and tile the workspace when it comes back?
Because the window covers the monitor on purpose. The comment in
[`Window::set_position`](../../../komorebi-linux/src/window.rs) says that "moving it would take it out of
[`Window::set_position`](../../../crates/komorebi-linux/src/window.rs) says that "moving it would take it out of
fullscreen, or be ignored", and that "it goes back to its tile when it leaves fullscreen". The
window stays in its container, so the other windows are tiled as if it were not fullscreen, and
every move the window manager makes goes through `set_position`, which is where the window is
@@ -700,13 +700,13 @@ skipped. When the window comes back, "KWin gives it the frame it had before, whi
tile it has now" (the comment in `handle_event`), so the workspace is tiled again. The bridge's
second request for a position gives up after three tries for the same reason: so that a window that
cannot go where it was asked, "a fullscreen one, say", is left alone rather than chased (the comment
on `settle` in [`bridge.js`](../../../komorebi-linux/src/kwin/bridge.js)).
on `settle` in [`bridge.js`](../../../crates/komorebi-linux/src/kwin/bridge.js)).
## Why does `initial_window_placement_rules` take a number as well as text?
Because the documentation of the setting shows a number (`"initial_window_placement_rules": 3`),
and a JSON object's keys can only be text: the doc comment on the `Deserialize` of
[`PlacementTarget`](../../../komorebi-linux/src/core/mod.rs) says both. The place is read from `"Primary"`,
[`PlacementTarget`](../../../crates/komorebi-linux/src/core/mod.rs) says both. The place is read from `"Primary"`,
`"3"` and `3`, so the form the page shows works as well as the form a map's keys force. In komorebi
for Windows, at its commit 83c4e11d, the deserializer reads only text, so the number its page shows
is refused. [The page of this repository](../initial-window-placement-rules.md#on-kde) says which
@@ -714,7 +714,7 @@ forms are read.
The JSON schema of the type is written by hand, so that it says the same. The one `schemars`
derives for the enum is an object with a `Placement` or an `Index` key, which the comment on the
`JsonSchema` impl of [`PlacementTarget`](../../../komorebi-linux/src/core/mod.rs) calls "not what
`JsonSchema` impl of [`PlacementTarget`](../../../crates/komorebi-linux/src/core/mod.rs) calls "not what
`Serialize` and `Deserialize` read and write". The schema `schemas/linux/schema.json` has says a name, a number,
or text that is a number, which is also what the module's typed `config` takes.
+3 -3
View File
@@ -19,7 +19,7 @@ tests of this repository run against the nixpkgs that `flake.lock` pins: at time
- **Session bus**: the D-Bus bus of the session. komorebi and KWin talk over it.
- **KWin**: the compositor and window manager of Plasma, `kwin_wayland`.
- **Script**: a JavaScript program that KWin runs inside itself, through its scripting API.
komorebi's is the **bridge**, [`bridge.js`](../../../komorebi-linux/src/kwin/bridge.js).
komorebi's is the **bridge**, [`bridge.js`](../../../crates/komorebi-linux/src/kwin/bridge.js).
- **Output**: KWin's name for a monitor.
- **Desktop**: one of KWin's virtual desktops. Each output shows one; komorebi's workspace `i`
is desktop `i`.
@@ -517,7 +517,7 @@ configuration it has.
What the KWin scripting API offers a script, and what it does not, at time of writing
(2026-10-27). The bridge is written around these, and
[`kwin-api.d.ts`](../../../komorebi-linux/src/kwin/kwin-api.d.ts) declares the part of the API it
[`kwin-api.d.ts`](../../../crates/komorebi-linux/src/kwin/kwin-api.d.ts) declares the part of the API it
uses, which `tsc` checks it against with ECMAScript 2016's library and nothing else. Node and
TypeScript are needed only for those checks: in the session the bridge needs KWin alone.
@@ -620,7 +620,7 @@ with two outputs of 1920x1080:
At time of writing (2026-10-27), a real suspend and resume is not tested: the QEMU guests the VM
tests run in have no way to wake from one. The signals are tested on private buses
(`komorebi-linux/tests/power.rs`), and the lock screen against a real KWin in a Plasma session
(`crates/komorebi-linux/tests/power.rs`), and the lock screen against a real KWin in a Plasma session
(`vm-lock-sleep`, which locks and unlocks with `loginctl lock-session` and `unlock-session`).
## How long a retile takes
+4 -4
View File
@@ -17,8 +17,8 @@ is, whether it is hidden, how wide it really is) is a call to the backend in kfd
| Commit | What it changes | kfde |
|---|---|---|
| `9ccf2efce` model of a scrollable strip | New crate `komorebi-scrolling`: columns of tiles, widths (proportion or fixed, limits), heights, view offset, centring (`Never`, `Always`, `OnOverflow`), pan, swipe tracker. No Windows code. Tests in the crate. | **Ported by dependency.** `komorebi-scrolling` is a git dependency at the same revision as the layouts. Its tests are upstream's; kfde tests the glue. |
| `abd4fde3e` lay out with the model | The workspace keeps a `ScrollingSpace` keyed by container id; `update()` places containers from it instead of recomputing equal columns from the last layout. | **Ported** (`komorebi-linux/src/scrolling.rs`, `Workspace::update`). |
| `cb127204c` platform-free glue | `komorebi_layouts::scrolling` (options, `place`, `resize`, hand-over between workspaces), `ScrollingCentering` replaces the `bool` of `center_focused_column`; Workspace methods for focus, order, consume, expel, stack. | **Ported:** the layouts half by the bump, the Workspace half in `komorebi-linux/src/scrolling.rs`. |
| `abd4fde3e` lay out with the model | The workspace keeps a `ScrollingSpace` keyed by container id; `update()` places containers from it instead of recomputing equal columns from the last layout. | **Ported** (`crates/komorebi-linux/src/scrolling.rs`, `Workspace::update`). |
| `cb127204c` platform-free glue | `komorebi_layouts::scrolling` (options, `place`, `resize`, hand-over between workspaces), `ScrollingCentering` replaces the `bool` of `center_focused_column`; Workspace methods for focus, order, consume, expel, stack. | **Ported:** the layouts half by the bump, the Workspace half in `crates/komorebi-linux/src/scrolling.rs`. |
| `249709e60` commands and config | Socket messages and `komorebic` commands `consume`, `expel`, `toggle-column-stack`, `scrolling-layout-full-width`, `center-focus`, `expand`; focus, move, resize, retile and close go through the strip. The message says a top level `scrolling` section too. | **Ported**, except the `scrolling` section: neither kfw nor kfde has one (only komorebi for Mac has; COMPARE.md says so). |
| `9ff278eb5` schemas | `center_focused_column` is a boolean or a name; docs for the new commands; `schema.bar.json`. | **Ported:** `schema.json`, `nix/linux/komorebi-options.nix`, `docs/linux/cli/`. `schema.bar.json` is kfw's (kfde has no bar). |
| `2dff53095` room for windows that will not get narrow | After windows are placed, a window wider than its column widens the column (never narrower again, never wider than the screen), for an overhang of 16 px or more. | **Ported, with a different trigger.** kfde cannot ask a window how wide it is right after moving it: the frame comes back from KWin a moment later. The widths are read at the first layout after the frames have settled (`WIDTH_SETTLE`), as upstream does with animations on. Covered by unit tests in `scrolling.rs`; no VM check, because it needs a client that will not get narrower and foot has no minimum width. |
@@ -47,11 +47,11 @@ is, whether it is hidden, how wide it really is) is a call to the backend in kfd
## What is tested, and where
- `komorebi-linux/src/scrolling.rs`: the glue against a workspace with no desktop (widths, consume, expel,
- `crates/komorebi-linux/src/scrolling.rs`: the glue against a workspace with no desktop (widths, consume, expel,
moving a column, stacking and spreading out with the windows that are hidden, expanding, panning,
where a window rests, which monitors are the others, what a window that will not get narrow
says). The model itself has its tests in upstream's `komorebi-scrolling`.
- `komorebi-linux/tests/scrolling.rs` and `layout_options.rs`: the commands through
- `crates/komorebi-linux/tests/scrolling.rs` and `layout_options.rs`: the commands through
`WindowManager::process_command` against the fake desktop, a strip next to another monitor, and a
drag of the left edge of a column.
- `komorebic/tests/linux_cli.rs`: each new subcommand sends its message.
+3 -3
View File
@@ -98,21 +98,21 @@ of a column.
## How it is tested
- `komorebi-linux/tests/drag_resize.rs`, against the fake desktop: a drag of the split between two
- `crates/komorebi-linux/tests/drag_resize.rs`, against the fake desktop: a drag of the split between two
tiles; a long drag of the narrow right-hand stack of the ultrawide vertical stack; a drag past
what the neighbor can give; a shrink past what the tile can lose; a drag of a window that is
short of its tile, which must not move the divider on its other side; a drag of a window that is
not the focused one; an edge with no neighbor; a drag that changed nothing; a corner; the edge
of a stack; a floating window and the window of a monocle; a drag whose frame had not got to
where the user took the edge when the window manager read the end.
- `komorebi-linux/src/kwin/state.rs`: the end of a resize is the frame the user asked for and a frame
- `crates/komorebi-linux/src/kwin/state.rs`: the end of a resize is the frame the user asked for and a frame
event after it does not change that, the end of a move is the frame, and the frame a drag began
with is kept while the frame changes.
- `vm-drag-resize`, in a Plasma session with a pointer device: edges and corners of three tiles
are dragged with the pointer, and the tiles are checked exactly (the dragged edge moved by what
the pointer moved, the neighbor's with it, nothing else), the frames within a cell of the
terminal's font.
- `komorebi-linux/tests/live_resize.rs`, against the fake desktop: the neighbors follow a drag while it
- `crates/komorebi-linux/tests/live_resize.rs`, against the fake desktop: the neighbors follow a drag while it
goes on and the dragged window is left alone; the same result with steps as without; a drag
taken back; a step with no drag going on; a window that opens part way through.
- `vm-live-resize`, in the same session: the edge is held part way and then all the way, and the
+1 -1
View File
@@ -180,7 +180,7 @@ version string builds libgit2, and zlib when the system has none. Then:
```sh
git clone https://github.com/LGUG2Z/komorebi-for-kde
cd komorebi-for-kde
cargo install --locked --path komorebi-daemon
cargo install --locked --path komorebi
cargo install --locked --path komorebic
```
+1 -1
View File
@@ -8,7 +8,7 @@ Base16 palette of your own.
There is no `komorebic` command for it: the daemon takes it from the `theme` key of
[`komorebi.json`](configuration.md#borders), or as a message on its socket, the `Theme` message,
which a program sends with [`komorebi-client`](../../../komorebi-client/src/lib.rs) or a script writes
which a program sends with [`komorebi-client`](../../../crates/komorebi-client/src/lib.rs) or a script writes
as a line of JSON.
```rust
+1 -1
View File
@@ -101,7 +101,7 @@ compiler toolchain.
Clone the git repository, enter the directory, and build the following binaries:
```powershell
cargo +stable install --path komorebi-daemon --locked --target-dir ~/.cargo/bin
cargo +stable install --path komorebi --locked --target-dir ~/.cargo/bin
cargo +stable install --path komorebic --locked --target-dir ~/.cargo/bin
cargo +stable install --path komorebi-bar --locked --target-dir ~/.cargo/bin
```
@@ -195,7 +195,7 @@ An agent's findings keep their annotation id (`a-3f9c1e02`).
```
komorebi-recorder annotate <session> add --kind finding --about <bug id> \
--text "the Show handler tiles the window onto the display that is going away" \
--ref event:12 --ref log:340 --ref code:komorebi/src/process_event.rs:512
--ref event:12 --ref log:340 --ref code:crates/komorebi-macos/src/process_event.rs:512
```
A finding with no evidence is refused, and every reference is checked to exist: the event, the log line, the video time,
+2 -2
View File
@@ -8,8 +8,8 @@ exits with "cannot find ^enum SubCommand". It runs only against the pre-consolid
named in COMPARE.md. Port it to the crates before using it again, or retire it with COMPARE.md.
NOTE (layout): STALE in a second way, and NOT repaired on purpose. This file now lives in
scripts/linux/ of the consolidated repository, and the three trees it compares are komorebi-windows/,
komorebi-linux/ and komorebi-macos/ of that one repository (the old komorebi-for-kde/ and
scripts/linux/ of the consolidated repository, and the three trees it compares are crates/komorebi-windows/,
crates/komorebi-linux/ and crates/komorebi-macos/ of that one repository (the old komorebi-for-kde/ and
komorebi-for-mac/ directories, the `komorebi/src` paths below, and the MONOREPO / HERE.parent
logic describe the layout before the consolidation). `HERE` below is scripts/linux/, not a tree.