1
0
Fork 0
forked from wry/wry

config: add window-rule infrastructure

This commit is contained in:
Julian Orth 2025-05-01 17:49:21 +02:00
parent a6257910bb
commit 59f8acdfde
26 changed files with 1829 additions and 38 deletions

View file

@ -858,6 +858,14 @@
"description": "",
"$ref": "#/$defs/ClientRule"
}
},
"windows": {
"type": "array",
"description": "An array of window rules.\n\nThese rules can be used to give names to windows and to manipulate them.\n\n- Example:\n\n ```toml\n [[windows]]\n name = \"spotify\"\n match.title-regex = \"Spotify\"\n action = { type = \"move-to-workspace\", name = \"music\" }\n ```\n",
"items": {
"description": "",
"$ref": "#/$defs/WindowRule"
}
}
},
"required": []
@ -1487,7 +1495,7 @@
},
"SimpleActionName": {
"type": "string",
"description": "The name of a `simple` Action.\n\n- Example:\n\n ```toml\n [shortcuts]\n alt-q = \"quit\"\n ```\n",
"description": "The name of a `simple` Action.\n\nWhen used inside a window rule, the following actions apply to the matched window\ninstead fo the focused window:\n\n- `move-left`\n- `move-down`\n- `move-up`\n- `move-right`\n- `split-horizontal`\n- `split-vertical`\n- `toggle-split`\n- `tile-horizontal`\n- `tile-vertical`\n- `toggle-split`\n- `show-single`\n- `show-all`\n- `toggle-fullscreen`\n- `enter-fullscreen`\n- `exit-fullscreen`\n- `close`\n- `toggle-floating`\n- `float`\n- `tile`\n- `toggle-float-pinned`\n- `pin-float`\n- `unpin-float`\n\n\n- Example:\n\n ```toml\n [shortcuts]\n alt-q = \"quit\"\n ```\n",
"enum": [
"focus-left",
"focus-down",
@ -1732,6 +1740,115 @@
"variant3"
]
},
"WindowMatch": {
"description": "Criteria for matching windows.\n\nIf no fields are set, all windows are matched. If multiple fields are set, all fields\nmust match the window.\n",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Matches if the window rule with this name matches.\n\n- Example:\n\n ```toml\n [[windows]]\n name = \"spotify\"\n match.title-regex = \"Spotify\"\n\n # Matches the same windows as the previous rule.\n [[windows]]\n match.name = \"spotify\"\n ```\n"
},
"not": {
"description": "Matches if the contained criteria don't match.\n\n- Example:\n\n ```toml\n [[windows]]\n name = \"not-spotify\"\n match.not.title-regex = \"Spotify\"\n ```\n",
"$ref": "#/$defs/WindowMatch"
},
"all": {
"type": "array",
"description": "Matches if all of the contained criteria match.\n\n- Example:\n\n ```toml\n [[windows]]\n match.all = [\n { title-regex = \"Spotify\" },\n { title-regex = \"Premium\" },\n ]\n ```\n",
"items": {
"description": "",
"$ref": "#/$defs/WindowMatch"
}
},
"any": {
"type": "array",
"description": "Matches if any of the contained criteria match.\n\n- Example:\n\n ```toml\n [[windows]]\n match.any = [\n { title-regex = \"Spotify\" },\n { title-regex = \"Alacritty\" },\n ]\n ```\n",
"items": {
"description": "",
"$ref": "#/$defs/WindowMatch"
}
},
"exactly": {
"description": "Matches if a specific number of contained criteria match.\n\n- Example:\n\n ```toml\n # Matches any window that is either Alacritty or on workspace 3 but not both.\n [[windows]]\n match.exactly.num = 1\n match.exactly.list = [\n { workspace = \"3\" },\n { title-regex = \"Alacritty\" },\n ]\n ```\n",
"$ref": "#/$defs/WindowMatchExactly"
},
"types": {
"description": "Matches windows whose type is contained in the mask.",
"$ref": "#/$defs/WindowTypeMask"
}
},
"required": []
},
"WindowMatchExactly": {
"description": "Criterion for matching a specific number of window criteria.\n",
"type": "object",
"properties": {
"num": {
"type": "number",
"description": "The number of criteria that must match."
},
"list": {
"type": "array",
"description": "The list of criteria.",
"items": {
"description": "",
"$ref": "#/$defs/WindowMatch"
}
}
},
"required": [
"num",
"list"
]
},
"WindowRule": {
"description": "A window rule.\n",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The name of this rule.\n\nThis name can be referenced in other rules.\n\n- Example\n\n ```toml\n [[windows]]\n name = \"spotify\"\n match.title-regex = \"Spotify\"\n\n [[windows]]\n match.name = \"spotify\"\n action = \"enter-fullscreen\"\n ```\n"
},
"match": {
"description": "The criteria that select the window that this rule applies to.",
"$ref": "#/$defs/WindowMatch"
},
"action": {
"description": "An action to execute when a window matches the criteria.",
"$ref": "#/$defs/Action"
},
"latch": {
"description": "An action to execute when a window no longer matches the criteria.",
"$ref": "#/$defs/Action"
}
},
"required": []
},
"WindowTypeMask": {
"description": "A mask of window types.\n",
"anyOf": [
{
"type": "string",
"description": "A named mask.",
"enum": [
"none",
"any",
"container",
"xdg-toplevel",
"x-window",
"client-window"
]
},
{
"type": "array",
"description": "An array of masks that are OR'd.",
"items": {
"description": "",
"$ref": "#/$defs/WindowTypeMask"
}
}
]
},
"XScalingMode": {
"type": "string",
"description": "The scaling mode of X windows.\n\n- Example:\n\n ```toml\n xwayland = { scaling-mode = \"downscaled\" }\n ```\n",

View file

@ -1721,6 +1721,23 @@ The table has the following fields:
The value of this field should be an array of [ClientRules](#types-ClientRule).
- `windows` (optional):
An array of window rules.
These rules can be used to give names to windows and to manipulate them.
- Example:
```toml
[[windows]]
name = "spotify"
match.title-regex = "Spotify"
action = { type = "move-to-workspace", name = "music" }
```
The value of this field should be an array of [WindowRules](#types-WindowRule).
<a name="types-Connector"></a>
### `Connector`
@ -3235,6 +3252,33 @@ The table has the following fields:
The name of a `simple` Action.
When used inside a window rule, the following actions apply to the matched window
instead fo the focused window:
- `move-left`
- `move-down`
- `move-up`
- `move-right`
- `split-horizontal`
- `split-vertical`
- `toggle-split`
- `tile-horizontal`
- `tile-vertical`
- `toggle-split`
- `show-single`
- `show-all`
- `toggle-fullscreen`
- `enter-fullscreen`
- `exit-fullscreen`
- `close`
- `toggle-floating`
- `float`
- `tile`
- `toggle-float-pinned`
- `pin-float`
- `unpin-float`
- Example:
```toml
@ -3437,7 +3481,8 @@ The string should have one of the following values:
Kills a client.
This action has no effect outside of client rules.
Within a window rule, it applies to the client of the window. Within a client rule
it applies to the matched client. Has no effect otherwise.
@ -3859,6 +3904,222 @@ The string should have one of the following values:
<a name="types-WindowMatch"></a>
### `WindowMatch`
Criteria for matching windows.
If no fields are set, all windows are matched. If multiple fields are set, all fields
must match the window.
Values of this type should be tables.
The table has the following fields:
- `name` (optional):
Matches if the window rule with this name matches.
- Example:
```toml
[[windows]]
name = "spotify"
match.title-regex = "Spotify"
# Matches the same windows as the previous rule.
[[windows]]
match.name = "spotify"
```
The value of this field should be a string.
- `not` (optional):
Matches if the contained criteria don't match.
- Example:
```toml
[[windows]]
name = "not-spotify"
match.not.title-regex = "Spotify"
```
The value of this field should be a [WindowMatch](#types-WindowMatch).
- `all` (optional):
Matches if all of the contained criteria match.
- Example:
```toml
[[windows]]
match.all = [
{ title-regex = "Spotify" },
{ title-regex = "Premium" },
]
```
The value of this field should be an array of [WindowMatchs](#types-WindowMatch).
- `any` (optional):
Matches if any of the contained criteria match.
- Example:
```toml
[[windows]]
match.any = [
{ title-regex = "Spotify" },
{ title-regex = "Alacritty" },
]
```
The value of this field should be an array of [WindowMatchs](#types-WindowMatch).
- `exactly` (optional):
Matches if a specific number of contained criteria match.
- Example:
```toml
# Matches any window that is either Alacritty or on workspace 3 but not both.
[[windows]]
match.exactly.num = 1
match.exactly.list = [
{ workspace = "3" },
{ title-regex = "Alacritty" },
]
```
The value of this field should be a [WindowMatchExactly](#types-WindowMatchExactly).
- `types` (optional):
Matches windows whose type is contained in the mask.
The value of this field should be a [WindowTypeMask](#types-WindowTypeMask).
<a name="types-WindowMatchExactly"></a>
### `WindowMatchExactly`
Criterion for matching a specific number of window criteria.
Values of this type should be tables.
The table has the following fields:
- `num` (required):
The number of criteria that must match.
The value of this field should be a number.
- `list` (required):
The list of criteria.
The value of this field should be an array of [WindowMatchs](#types-WindowMatch).
<a name="types-WindowRule"></a>
### `WindowRule`
A window rule.
Values of this type should be tables.
The table has the following fields:
- `name` (optional):
The name of this rule.
This name can be referenced in other rules.
- Example
```toml
[[windows]]
name = "spotify"
match.title-regex = "Spotify"
[[windows]]
match.name = "spotify"
action = "enter-fullscreen"
```
The value of this field should be a string.
- `match` (optional):
The criteria that select the window that this rule applies to.
The value of this field should be a [WindowMatch](#types-WindowMatch).
- `action` (optional):
An action to execute when a window matches the criteria.
The value of this field should be a [Action](#types-Action).
- `latch` (optional):
An action to execute when a window no longer matches the criteria.
The value of this field should be a [Action](#types-Action).
<a name="types-WindowTypeMask"></a>
### `WindowTypeMask`
A mask of window types.
Values of this type should have one of the following forms:
#### A string
A named mask.
The string should have one of the following values:
- `none`:
The empty mask.
- `any`:
The mask containing every possible type.
- `container`:
The mask matching a container.
- `xdg-toplevel`:
The mask matching an XDG toplevel.
- `x-window`:
The mask matching an X window.
- `client-window`:
The mask matching any type of client window.
#### An array
An array of masks that are OR'd.
Each element of this array should be a [WindowTypeMask](#types-WindowTypeMask).
<a name="types-XScalingMode"></a>
### `XScalingMode`

View file

@ -691,6 +691,33 @@ Exec:
SimpleActionName:
description: |
The name of a `simple` Action.
When used inside a window rule, the following actions apply to the matched window
instead fo the focused window:
- `move-left`
- `move-down`
- `move-up`
- `move-right`
- `split-horizontal`
- `split-vertical`
- `toggle-split`
- `tile-horizontal`
- `tile-vertical`
- `toggle-split`
- `show-single`
- `show-all`
- `toggle-fullscreen`
- `enter-fullscreen`
- `exit-fullscreen`
- `close`
- `toggle-floating`
- `float`
- `tile`
- `toggle-float-pinned`
- `pin-float`
- `unpin-float`
- Example:
@ -825,7 +852,8 @@ SimpleActionName:
description: |
Kills a client.
This action has no effect outside of client rules.
Within a window rule, it applies to the client of the window. Within a client rule
it applies to the matched client. Has no effect otherwise.
Color:
@ -2509,6 +2537,24 @@ Config:
name = "spotify"
match.sandbox-app-id = "com.spotify.Client"
```
windows:
kind: array
items:
ref: WindowRule
required: false
description: |
An array of window rules.
These rules can be used to give names to windows and to manipulate them.
- Example:
```toml
[[windows]]
name = "spotify"
match.title-regex = "Spotify"
action = { type = "move-to-workspace", name = "music" }
```
Idle:
@ -3284,3 +3330,179 @@ ClientMatchExactly:
ref: ClientMatch
required: true
description: The list of criteria.
WindowRule:
kind: table
description: |
A window rule.
fields:
name:
kind: string
required: false
description: |
The name of this rule.
This name can be referenced in other rules.
- Example
```toml
[[windows]]
name = "spotify"
match.title-regex = "Spotify"
[[windows]]
match.name = "spotify"
action = "enter-fullscreen"
```
match:
ref: WindowMatch
required: false
description: The criteria that select the window that this rule applies to.
action:
ref: Action
required: false
description: An action to execute when a window matches the criteria.
latch:
ref: Action
required: false
description: An action to execute when a window no longer matches the criteria.
WindowMatch:
kind: table
description: |
Criteria for matching windows.
If no fields are set, all windows are matched. If multiple fields are set, all fields
must match the window.
fields:
name:
kind: string
required: false
description: |
Matches if the window rule with this name matches.
- Example:
```toml
[[windows]]
name = "spotify"
match.title-regex = "Spotify"
# Matches the same windows as the previous rule.
[[windows]]
match.name = "spotify"
```
not:
ref: WindowMatch
required: false
description: |
Matches if the contained criteria don't match.
- Example:
```toml
[[windows]]
name = "not-spotify"
match.not.title-regex = "Spotify"
```
all:
kind: array
items:
ref: WindowMatch
required: false
description: |
Matches if all of the contained criteria match.
- Example:
```toml
[[windows]]
match.all = [
{ title-regex = "Spotify" },
{ title-regex = "Premium" },
]
```
any:
kind: array
items:
ref: WindowMatch
required: false
description: |
Matches if any of the contained criteria match.
- Example:
```toml
[[windows]]
match.any = [
{ title-regex = "Spotify" },
{ title-regex = "Alacritty" },
]
```
exactly:
ref: WindowMatchExactly
required: false
description: |
Matches if a specific number of contained criteria match.
- Example:
```toml
# Matches any window that is either Alacritty or on workspace 3 but not both.
[[windows]]
match.exactly.num = 1
match.exactly.list = [
{ workspace = "3" },
{ title-regex = "Alacritty" },
]
```
types:
ref: WindowTypeMask
required: false
description: Matches windows whose type is contained in the mask.
WindowMatchExactly:
kind: table
description: |
Criterion for matching a specific number of window criteria.
fields:
num:
kind: number
required: true
description: The number of criteria that must match.
list:
kind: array
items:
ref: WindowMatch
required: true
description: The list of criteria.
WindowTypeMask:
description: |
A mask of window types.
kind: variable
variants:
- kind: string
description: A named mask.
values:
- value: none
description: The empty mask.
- value: any
description: The mask containing every possible type.
- value: container
description: The mask matching a container.
- value: xdg-toplevel
description: The mask matching an XDG toplevel.
- value: x-window
description: The mask matching an X window.
- value: client-window
description: The mask matching any type of client window.
- kind: array
description: An array of masks that are OR'd.
items:
ref: WindowTypeMask