mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-11-14 21:04:04 +01:00
komorebi-for-kde/docs/ -> docs/linux/ komorebi-for-mac/docs/ -> docs/macos/ The Windows docs stay where they are (docs/). Renames only, so links and include paths that named the old directories are broken at this revision; they are fixed in the revision that fixes the paths of the whole layout move.
268 lines
8.5 KiB
Markdown
268 lines
8.5 KiB
Markdown
# Initial window placement rules
|
|
|
|
By default, when a new window opens, komorebi puts it **after the focused container**. The
|
|
`initial_window_placement_rules` setting of a workspace, in its entry in
|
|
[`komorebi.json`](usage/configuration.md#monitors-and-workspaces), controls where new tiled windows
|
|
go in the list of containers.
|
|
|
|
The setting only applies when the workspace's `window_container_behaviour` is `Create`, which is
|
|
the default. With `Append` (see [Stacking windows](usage/stacking-windows.md)), a new window goes
|
|
into the focused container whatever the rules say.
|
|
|
|
## The two forms
|
|
|
|
`initial_window_placement_rules` takes a place for every window, or a map from places to the
|
|
windows that go there.
|
|
|
|
### A place for every window
|
|
|
|
A placement strategy (a string) or a container index (a number, counting from 1):
|
|
|
|
```json
|
|
{
|
|
"monitors": [
|
|
{
|
|
"workspaces": [
|
|
{
|
|
"name": "main",
|
|
"initial_window_placement_rules": "Primary"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
With a number, every new window goes to that place:
|
|
|
|
```json
|
|
{
|
|
"monitors": [
|
|
{
|
|
"workspaces": [
|
|
{
|
|
"name": "main",
|
|
"initial_window_placement_rules": 3
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
This puts every new window third. If there is no such place, the window goes where it would
|
|
have gone without a rule, after the focused container. The place after the last container is
|
|
there: `4` is the end of a list of three.
|
|
|
|
The strategies:
|
|
|
|
| Strategy | Where the window goes |
|
|
|----------|-----------------------|
|
|
| `Primary` | The primary (largest) tile: index 0 in every built-in layout |
|
|
| `Secondary` | The secondary tile: index 1 in every built-in layout, and none when there is only one container |
|
|
| `BeforeFocused` | Before the focused container |
|
|
| `AfterFocused` | After the focused container (the default) |
|
|
| `Last` | At the end of the list |
|
|
|
|
### A place for the windows that match
|
|
|
|
A map from a strategy or a number to the rule that says which windows go there. The key is a
|
|
strategy or a place counted from 1, as text:
|
|
|
|
```json
|
|
{
|
|
"monitors": [
|
|
{
|
|
"workspaces": [
|
|
{
|
|
"name": "main",
|
|
"initial_window_placement_rules": {
|
|
"Primary": {
|
|
"kind": "Exe",
|
|
"id": "firefox",
|
|
"matching_strategy": "Equals"
|
|
},
|
|
"Last": {
|
|
"kind": "Title",
|
|
"id": "Chat",
|
|
"matching_strategy": "Contains"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
Here the windows of Firefox take the primary tile, a window with "Chat" in its title goes to the end
|
|
of the list, and every other window goes after the focused container.
|
|
|
|
## What a rule matches
|
|
|
|
A rule is the same condition the [ignore and manage rules](usage/rules.md) are made of: a `kind`
|
|
(`Exe`, `Class`, `Title` or `Path`), an `id`, and a `matching_strategy`.
|
|
|
|
### One condition
|
|
|
|
```json
|
|
{
|
|
"kind": "Exe",
|
|
"id": "firefox",
|
|
"matching_strategy": "Equals"
|
|
}
|
|
```
|
|
|
|
### Several windows for one place (OR)
|
|
|
|
An array is a list of conditions, and a window goes to the place when **any** of them matches it:
|
|
|
|
```json
|
|
{
|
|
"initial_window_placement_rules": {
|
|
"Primary": [
|
|
{ "kind": "Exe", "id": "firefox", "matching_strategy": "Equals" },
|
|
{ "kind": "Exe", "id": "chromium", "matching_strategy": "Equals" }
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
This puts Firefox and Chromium in the primary tile.
|
|
|
|
### A window that matches all of them (AND)
|
|
|
|
An array inside the array is a condition that needs **all** of its parts:
|
|
|
|
```json
|
|
{
|
|
"initial_window_placement_rules": {
|
|
"Primary": [
|
|
[
|
|
{ "kind": "Exe", "id": "code", "matching_strategy": "Equals" },
|
|
{ "kind": "Title", "id": "workspace", "matching_strategy": "Contains" }
|
|
]
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
This only matches windows of `code` with "workspace" in their title.
|
|
|
|
### Both
|
|
|
|
The two can be mixed in one list:
|
|
|
|
```json
|
|
{
|
|
"initial_window_placement_rules": {
|
|
"Primary": [
|
|
{ "kind": "Exe", "id": "firefox", "matching_strategy": "Equals" },
|
|
[
|
|
{ "kind": "Exe", "id": "code", "matching_strategy": "Equals" },
|
|
{ "kind": "Title", "id": "workspace", "matching_strategy": "Contains" }
|
|
]
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
This puts every window of Firefox in the primary tile, and so every window of `code` that has
|
|
"workspace" in its title.
|
|
|
|
## The primary and secondary tiles
|
|
|
|
In every built-in layout the primary container is the one at index 0, the largest tile, and the
|
|
secondary is the one at index 1. Flipping a layout moves the tiles on the screen and not the
|
|
indexes of the containers.
|
|
|
|
| Layout | Primary (index 0) | Secondary (index 1) |
|
|
|--------|-------------------|---------------------|
|
|
| **BSP** | The largest split | The second split |
|
|
| **VerticalStack** | The left column | The first row of the right stack |
|
|
| **RightMainVerticalStack** | The right column | The first row of the left stack |
|
|
| **HorizontalStack** | The top row | The first column of the bottom stack |
|
|
| **UltrawideVerticalStack** | The center column | The left column |
|
|
| **Columns** | The first column | The second column |
|
|
| **Rows** | The first row | The second row |
|
|
| **Grid** | The first cell | The second cell |
|
|
| **Scrolling** | The first column | The second column |
|
|
|
|
Custom layouts are not supported on KDE yet.
|
|
|
|
## The order rules are tried in
|
|
|
|
The rules of the map form are tried in the order of their keys, and the first that matches
|
|
decides. A key is compared as text: a number sorts before a name, `10` before `2`, and the names
|
|
alphabetically.
|
|
|
|
```json
|
|
{
|
|
"initial_window_placement_rules": {
|
|
"1": { "kind": "Exe", "id": "firefox", "matching_strategy": "Equals" },
|
|
"Primary": { "kind": "Exe", "id": "chromium", "matching_strategy": "Equals" },
|
|
"Secondary": { "kind": "Title", "id": "Chat", "matching_strategy": "Contains" }
|
|
}
|
|
}
|
|
```
|
|
|
|
The keys are tried in this order: `"1"`, `"Primary"`, `"Secondary"`. A new window goes:
|
|
|
|
- of `firefox`: to place 1, the first;
|
|
- of `chromium`: to the primary tile, which is also the first place, but is found from the layout;
|
|
- with "Chat" in its title: to the secondary tile;
|
|
- any other: after the focused container.
|
|
|
|
A mix of numbers and names sorts like this:
|
|
|
|
| Key | Position |
|
|
|-----|----------|
|
|
| `"1"` | 1st |
|
|
| `"10"` | 2nd |
|
|
| `"2"` | 3rd |
|
|
| `"AfterFocused"` | 4th |
|
|
| `"Last"` | 5th |
|
|
| `"Primary"` | 6th |
|
|
| `"Secondary"` | 7th |
|
|
|
|
Most configurations have a few keys, and the order does not matter. When a window matches two
|
|
keys, the first of these decides.
|
|
|
|
If a rule matches and its place does not exist (a rule for place 5 on a workspace of three
|
|
containers), that match is ignored and the window goes after the focused container.
|
|
|
|
## Other things that decide
|
|
|
|
- A place that was reserved with [`preselect-direction`](cli/preselect-direction.md) wins over the
|
|
rules, and the rules are back for the next window.
|
|
- `window_container_behaviour`: while a workspace has `Append`, because its entry says so, because
|
|
of its `window_container_behaviour_rules`, or because
|
|
[`toggle-workspace-window-container-behaviour`](cli/toggle-workspace-window-container-behaviour.md)
|
|
switched it, the rules are not used.
|
|
- The rules decide for every window that gets a container of its own, not only for one that opens:
|
|
one that comes back from being minimized, one that
|
|
[`manage`](cli/manage.md) puts back in the layout, one that
|
|
[`unstack`](cli/unstack.md) takes out of a stack, and one that a
|
|
[workspace rule](usage/workspace-rules.md) or KWin moves to the workspace.
|
|
- A locked container keeps its index: a window that a rule puts at the index of a locked container
|
|
goes just after it.
|
|
- The container a window opens in takes the focus, as it does without a rule.
|
|
|
|
## On KDE
|
|
|
|
This is the same setting as in komorebi for Windows, and it reads the same configuration. What
|
|
differs is how a window is named:
|
|
|
|
- `Exe` is the name of the program (`firefox`, `foot`, `code`). A `.exe` in the `id` is ignored, so
|
|
a `komorebi.json` with `"chrome.exe"` in it works on every platform.
|
|
- `Class` is the Wayland `app_id` of the window (the X11 `WM_CLASS` of a window on XWayland), such
|
|
as `org.kde.konsole`.
|
|
- `Title` is the title of the window, and `Path` the full path of its executable.
|
|
|
|
[`komorebic state`](cli/state.md) shows all four for every window. The matching strategies are
|
|
those of the [ignore and manage rules](usage/rules.md).
|
|
|
|
A number is accepted as the whole value of the setting (`"initial_window_placement_rules": 3`),
|
|
as this page shows. komorebi for Windows shows the same in its documentation, and as of its commit
|
|
83c4e11d its deserializer only reads a number that is quoted: `"3"`.
|