From 8ab0c8958d0bbca590adfb5dca0ea6a0e99abafc Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sun, 4 May 2025 20:48:57 +0200 Subject: [PATCH] docs: add release notes --- docs/config.md | 4 + docs/features.md | 10 ++ docs/window-and-client-rules.md | 259 ++++++++++++++++++++++++++++++++ release-notes.md | 4 + 4 files changed, 277 insertions(+) create mode 100644 docs/window-and-client-rules.md diff --git a/docs/config.md b/docs/config.md index 6e53c9c1..b01d8345 100644 --- a/docs/config.md +++ b/docs/config.md @@ -513,3 +513,7 @@ The default configuration will try to start [wl-tray-bridge] to give you access icons and menus. [wl-tray-bridge]: https://github.com/mahkoh/wl-tray-bridge + +### Window and Client Rules + +This is described in [window-and-client-rules.md](window-and-client-rules.md). diff --git a/docs/features.md b/docs/features.md index 918134ba..51924ba8 100644 --- a/docs/features.md +++ b/docs/features.md @@ -49,6 +49,10 @@ Commands: portal Run the desktop portal randr Inspect/modify graphics card and connector settings input Inspect/modify input settings + xwayland Inspect/modify xwayland settings + color-management Inspect/modify the color-management settings + clients Inspect/manipulate the connected clients + tree Inspect the surface tree help Print this message or the help of the given subcommand(s) Options: @@ -138,6 +142,12 @@ Jay uses frame scheduling to achieve input latency as low as 1.5 ms. Jay supports the color management protocol and HDR10. +## Window and Client Rules + +Jay supports powerful window and client rules. + +See [window-and-client-rules.md](window-and-client-rules.md) for more details. + ## Protocol Support Jay supports the following wayland protocols: diff --git a/docs/window-and-client-rules.md b/docs/window-and-client-rules.md new file mode 100644 index 00000000..48b7be77 --- /dev/null +++ b/docs/window-and-client-rules.md @@ -0,0 +1,259 @@ +# Window and Client Rules + +Jay supports powerful window and client rules similar to i3. + +## Example + +```toml +# Move spotify to workspace 3 and fullscreen it. +[[windows]] +match.client.sandbox-app-id = "com.spotify.Client" +action = [ + { type = "move-to-workspace", name = "3" }, + "enter-fullscreen", +] + +# Spawn the Chromium screen sharing window, the GIMP splash screen, and the +# JetBrains splash screen floating and without focus stealing. +[[windows]] +match.any = [ + { title-regex = 'is sharing (your screen|a window)\.$', client.comm = "chromium" }, + { title = "GIMP Startup", app-id = "gimp" }, + { title = "splash", x-class-regex = "^jetbrains-(clion|rustrover)$" } +] +initial-tile-state = "floating" +auto-focus = false + +# Spawn the JetBrains project selector floating. +[[windows]] +match.title-regex = "^Welcome to (RustRover|CLion)$" +match.x-class-regex = "^jetbrains-(clion|rustrover)$" +initial-tile-state = "floating" +``` + +## General Principles + +Each rule consists of three components: + +1. Criteria that determine which clients/windows the rule applies to. +2. An action to execute when a client/window starts matching the rule. +3. An action to execute when a client/window stops matching the rule. + +Each rule can be assigned a name which allows other rules to refer to it. + +Additionally, rules have ad-hoc properties for things that are not easily +expressed via actions, such as whether a window should be mapped floating or +tiled. + +```toml +[[windows]] +name = "..." # the rule name +match = { } # the rule criteria +action = "..." # the action to run on start +latch = "..." # the action to run on stop +``` + +Rules are re-evaluated whenever any of the referenced criteria changes. That is, +if you have the following rule + +```toml +[[windows]] +match.title = "VIM" +action = "enter-fullscreen" +``` + +then the window will enter fullscreen whenever title changes from something that +is not `VIM` to `VIM`. For window rules, if you only want to match windows that +have just been mapped, you can set the `just-mapped` criterion to `true`: + +```toml +[[windows]] +match.title = "VIM" +match.just-mapped = true +action = "enter-fullscreen" +``` + +This is similar to the `initial-title` criterion found in some other +compositors. + +Rules can trigger each other. For example: + +```toml +[[windows]] +match.fullscreen = false +action = "enter-fullscreen" + +[[windows]] +match.fullscreen = true +action = "exit-fullscreen" +``` + +This causes an infinite repetition of switching between windowed and fullscreen. +Jay prevents such loops from locking up the compositor by never performing more +than 1000 action callbacks before yielding to other work. However, they will +still cause the compositor to use 100% CPU and will likely cause affected +clients to be killed, since they won't be able to receive wayland messages fast +enough. + +## Combining Criteria + +Criteria can be combined with the following operations: + +- `any` - match if any of a number of criteria match +- `all` - match if all of a number of criteria match +- `not` - match if a criterion does not match +- `exactly` - match if an exact number of criteria match +- `name` - match if another window rule with that name matches + +```toml +# match windows that have the title `chromium` or `spotify` +match.any = [ + { title = "chromium" }, + { title = "spotify" }, +] + +# match windows whose title match both `chro` and `mium` +match.all = [ + { title-regex = "chro" }, + { title-regex = "mium" }, +] + +# match windows whose title is not `firefox` +match.not.title = "firefox" + +# match windows whose title is `VIM` or whose clients are sandboxed, but not +# both +match.exactly.num = 1 +match.exactly.list = [ + { title = "VIM" }, + { client.sandboxed = true }, +] + +# match if another rule called `another-rule-name` matches +match.name = "another-rule-name" +``` + +A criterion object has multiple fields, for example + +```toml +match.title = "abc" +match.app-id = "xyz" +``` + +These fields are implicitly combined with `all` operator. That is, this behaves +just like + +```toml +match.all = [ + { title = "abc" }, + { app-id = "xyz" }, +] +``` + +## Finding Criteria Values + +To determine which values to use in criteria, the `jay` executable provides the +subcommands `jay clients` and `jay tree` to inspect currently active clients and +open windows. For example + +```text +~$ jay tree query select-window +- xdg-toplevel: + id: 258ae697663a1b8abc7e4da9570ad36f + pos: 1920x36 + 1920x1044 + client: + id: 15 + uid: 1000 + pid: 2159136 + comm: chromium + exe: /usr/lib/chromium/chromium + title: YouTube - Chromium + app-id: chromium + workspace: 2 + visible +``` + +In this case, `select-window` allows you to interactively select a window and +then prints its properties. + +## Client Rules + +```toml +# start executable `b` whenever a client with executable `A` connects +[[clients]] +match.exe = "A" +action = { type = "exec", exec = "b" } +``` + +All properties that can be referred to in client criteria are currently +constant over the lifetime of the client. + +### Client Criteria + +The full specification of client criteria can be found in +[spec.generated.md](../toml-spec/spec/spec.generated.md). + +- `sandboxed` - Matches clients that are/aren't sandboxed. +- `sandbox-engine`, `sandbox-engine-regex` - Matches the sandbox engine that was + used to wrap this client. Usually `org.flatpak`. +- `sandbox-app-id`, `sandbox-app-id-regex` - Matches the app-id provided by the + sandbox engine +- `sandbox-instance-id-id`, `sandbox-instance-id-regex` - Matches the + instance-id provided by the sandbox engine +- `uid`, `pid` - Matches the UID/PID of the client. +- `is-xwayland` - Matches if the client is/isn't Xwayland. +- `comm`, `comm-regex` - Matches the `/proc/self/comm` of the client. +- `exe`, `exe-regex` - Matches the `/proc/self/exe` of the client. + +## Window Rules + +## Ad-hoc Window Rules + +Rule actions are evaluated asynchronously. For window rules, this means that +they are evaluated after the window has been mapped but before it is displayed +for the first time. This makes them ill-suited for things that need to be fixed +during the mapping process. Ad-hoc window rules can be used to bridge this gap: + +```toml +[[windows]] +match.title = "chromium" +initial-tile-state = "floating" +auto-focus = false +``` + +The `initial-tile-state` rule can be used to define whether the window is mapped +tiled or floating. If no such rule exists, this is determined via heuristics. +If multiple such rules exist and match a window, the compositor picks one at +random. + +The `auto-focus` rule determines if the window is automatically focused when it +is mapped. If no such rule exists, newly mapped windows always get the keyboard +focus except in some cases involving Xwayland. If multiple such rules exist and +match a window, then the window _does not_ get the focus if _any_ of them is set +to `false`. + +## Window Criteria + +The full specification of window criteria can be found in +[spec.generated.md](../toml-spec/spec/spec.generated.md). + +- `types` - Matches the type of a window. Currently there are four types: + containers, placeholders, xdg toplevels, and X windows. If the rule does not + contain such a criterion, the rule will only match windows created by clients, + that is, xdg toplevels and X windows. +- `client` - This is a client criterion. See above. +- `title`, `title-regex` - Matches the title of the window. +- `app-id`, `app-id-regex` - Matches the XDG app-id of the window. +- `floating` - Matches if the window is/isn't floating. +- `visible` - Matches if the window is/isn't visible. +- `urgent` - Matches if the window wants/doesn't want attentions. +- `focused` - Matches if the window is/isn't focused. +- `fullscreen` - Matches if the window is/isn't fullscreen. +- `just-mapped` - Matches if the window has/hasn't just been mapped. This is +- `just-mapped` - Matches if the window has/hasn't just been mapped. This is + true for a single frame after the window has been mapped. +- `tag`, `tag-regex` - Matches the XDG toplevel tag of the window. +- `x-class`, `x-class-regex` - Matches the X class of the window. +- `x-instance`, `x-instance-regex` - Matches the X instance of the window. +- `x-role`, `x-role-regex` - Matches the X role of the window. +- `workspace`, `workspace-regex` - Matches the workspace of the window. diff --git a/release-notes.md b/release-notes.md index 60dc13e8..86bccd30 100644 --- a/release-notes.md +++ b/release-notes.md @@ -27,6 +27,10 @@ [shortcuts] alt-x = "$switch-to-next" ``` +- Add client and window rules. This is described in detail in + [window-and-client-rules.md](./docs/window-and-client-rules.md). +- Add client and tree CLI subcommands to inspect clients and windows, primarily + to facilitate the writing of window and client rules. # 1.10.0 (2025-04-22)