docs: add release notes
This commit is contained in:
parent
38d7a60d00
commit
8ab0c8958d
4 changed files with 277 additions and 0 deletions
259
docs/window-and-client-rules.md
Normal file
259
docs/window-and-client-rules.md
Normal file
|
|
@ -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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue