Skip to content

Latest commit

 

History

History
260 lines (209 loc) · 8.14 KB

File metadata and controls

260 lines (209 loc) · 8.14 KB

Window and Client Rules

Jay supports powerful window and client rules similar to i3.

Example

# 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.

[[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

[[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:

[[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:

[[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
# 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

match.title = "abc"
match.app-id = "xyz"

These fields are implicitly combined with all operator. That is, this behaves just like

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

~$ 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

# 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.

  • 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:

[[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.

  • 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 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.
  • content-types - Matches the content type of a window. Currently there are three types: photos, videos, and games.