mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-04 09:54:17 +02:00
Adds a top-level layout_defaults setting that defines default layout_options and layout_options_rules per layout. Workspaces without their own layout_options or layout_options_rules automatically inherit the global defaults. If a workspace defines either setting, all global defaults for that layout are fully replaced.
338 lines
10 KiB
Markdown
338 lines
10 KiB
Markdown
# Layout Ratios
|
|
|
|
With `komorebi` you can customize the split ratios for various layouts using
|
|
`column_ratios` and `row_ratios` in the `layout_options` configuration.
|
|
|
|
## Before and After
|
|
|
|
BSP layout example:
|
|
|
|
**Before** (default 50/50 splits):
|
|
|
|

|
|
|
|
**After** (with `column_ratios: [0.7]` and `row_ratios: [0.6]`):
|
|
|
|

|
|
|
|
## Configuration
|
|
|
|
```json
|
|
{
|
|
"monitors": [
|
|
{
|
|
"workspaces": [
|
|
{
|
|
"name": "main",
|
|
"layout_options": {
|
|
"column_ratios": [0.3, 0.4],
|
|
"row_ratios": [0.4, 0.3]
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
You can specify up to 5 ratio values (defined by `MAX_RATIOS` constant). Each value should be between 0.1 and 0.9
|
|
(defined by `MIN_RATIO` and `MAX_RATIO` constants). Values outside this range are automatically clamped.
|
|
Columns or rows without a specified ratio will share the remaining space equally.
|
|
|
|
## Usage by Layout
|
|
|
|
| Layout | `column_ratios` | `row_ratios` |
|
|
|--------|-----------------|--------------|
|
|
| **Columns** | Width of each column | - |
|
|
| **Rows** | - | Height of each row |
|
|
| **Grid** | Width of each column (rows are equal height) | - |
|
|
| **BSP** | `[0]` as horizontal split ratio | `[0]` as vertical split ratio |
|
|
| **VerticalStack** | `[0]` as primary column width | Stack row heights |
|
|
| **RightMainVerticalStack** | `[0]` as primary column width | Stack row heights |
|
|
| **HorizontalStack** | Stack column widths | `[0]` as primary row height |
|
|
| **UltrawideVerticalStack** | `[0]` center, `[1]` left column | Tertiary stack row heights |
|
|
|
|
## Examples
|
|
|
|
### Columns Layout with Custom Widths
|
|
|
|
Create 3 columns with 30%, 40%, and 30% widths:
|
|
|
|
```json
|
|
{
|
|
"layout_options": {
|
|
"column_ratios": [0.3, 0.4]
|
|
}
|
|
}
|
|
```
|
|
|
|
Note: The third column automatically gets the remaining 30%.
|
|
|
|
### Rows Layout with Custom Heights
|
|
|
|
Create 3 rows with 20%, 50%, and 30% heights:
|
|
|
|
```json
|
|
{
|
|
"layout_options": {
|
|
"row_ratios": [0.2, 0.5]
|
|
}
|
|
}
|
|
```
|
|
|
|
Note: The third row automatically gets the remaining 30%.
|
|
|
|
### Grid Layout with Custom Column Widths
|
|
|
|
Grid with custom column widths (rows within each column are always equal height):
|
|
|
|
```json
|
|
{
|
|
"layout_options": {
|
|
"column_ratios": [0.4, 0.6]
|
|
}
|
|
}
|
|
```
|
|
|
|
Note: The Grid layout only supports `column_ratios`. Rows within each column are always
|
|
divided equally because the number of rows per column varies dynamically based on window count.
|
|
|
|
### VerticalStack with Custom Ratios
|
|
|
|
Primary column takes 60% width, and the stack rows are split 30%/70%:
|
|
|
|
```json
|
|
{
|
|
"layout_options": {
|
|
"column_ratios": [0.6],
|
|
"row_ratios": [0.3]
|
|
}
|
|
}
|
|
```
|
|
|
|
Note: The second row automatically gets the remaining 70%.
|
|
|
|
### HorizontalStack with Custom Ratios
|
|
|
|
Primary row takes 70% height, and the stack columns are split 40%/60%:
|
|
|
|
```json
|
|
{
|
|
"layout_options": {
|
|
"row_ratios": [0.7],
|
|
"column_ratios": [0.4]
|
|
}
|
|
}
|
|
```
|
|
|
|
Note: The second column automatically gets the remaining 60%.
|
|
|
|
### UltrawideVerticalStack with Custom Ratios
|
|
|
|
Center column at 50%, left column at 25% (remaining 25% goes to tertiary stack),
|
|
with tertiary rows split 40%/60%:
|
|
|
|
```json
|
|
{
|
|
"layout_options": {
|
|
"column_ratios": [0.5, 0.25],
|
|
"row_ratios": [0.4]
|
|
}
|
|
}
|
|
```
|
|
|
|
Note: The second row automatically gets the remaining 60%.
|
|
|
|
### BSP Layout with Custom Split Ratios
|
|
|
|
Use separate ratios for horizontal (left/right) and vertical (top/bottom) splits:
|
|
|
|
```json
|
|
{
|
|
"layout_options": {
|
|
"column_ratios": [0.6],
|
|
"row_ratios": [0.3]
|
|
}
|
|
}
|
|
```
|
|
|
|
- `column_ratios[0]`: Controls all horizontal splits (left window gets 60%, right gets 40%)
|
|
- `row_ratios[0]`: Controls all vertical splits (top window gets 30%, bottom gets 70%)
|
|
|
|
Note: BSP only uses the first value (`[0]`) from each ratio array. This single ratio is applied
|
|
consistently to all splits of that type throughout the layout. Additional values in the arrays are ignored.
|
|
|
|
## Notes
|
|
|
|
- Ratios are clamped between 0.1 and 0.9 (prevents zero-sized windows and ensures space for other windows)
|
|
- Default ratio is 0.5 (50%) when not specified, except for UltrawideVerticalStack secondary column which defaults to 0.25 (25%)
|
|
- Ratios are applied **progressively** - a ratio is only used when there are more windows to place after the current one
|
|
- The **last window always takes the remaining space**, regardless of defined ratios
|
|
- **Ratios that would sum to 100% or more are automatically truncated** at config load time to ensure there's always space for additional windows
|
|
- Unspecified ratios default to sharing the remaining space equally
|
|
- You only need to specify the ratios you want to customize; trailing values can be omitted
|
|
|
|
## Layout Options Rules
|
|
|
|
You can dynamically change `layout_options` based on the number of containers on a workspace
|
|
using `layout_options_rules`. This uses the same threshold-based logic as `layout_rules`:
|
|
when the container count is greater than or equal to a threshold, the highest matching
|
|
threshold's options are used.
|
|
|
|
Rules **fully replace** the base `layout_options` when they match. If no rule matches, the
|
|
base `layout_options` is used.
|
|
|
|
### Configuration
|
|
|
|
```json
|
|
{
|
|
"monitors": [
|
|
{
|
|
"workspaces": [
|
|
{
|
|
"name": "main",
|
|
"layout": "VerticalStack",
|
|
"layout_options": {
|
|
"column_ratios": [0.6],
|
|
"row_ratios": [0.4]
|
|
},
|
|
"layout_options_rules": {
|
|
"3": { "column_ratios": [0.55] },
|
|
"5": { "column_ratios": [0.3, 0.3, 0.3], "row_ratios": [0.5] }
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
In the example above:
|
|
|
|
| Container Count | Effective `layout_options` |
|
|
|-----------------|---------------------------|
|
|
| 1-2 | Base: `column_ratios: [0.6]`, `row_ratios: [0.4]` |
|
|
| 3-4 | Rule "3": `column_ratios: [0.55]` (no row_ratios, no scrolling, no grid) |
|
|
| 5+ | Rule "5": `column_ratios: [0.3, 0.3, 0.3]`, `row_ratios: [0.5]` |
|
|
|
|
Rules can include any field that `layout_options` supports: `column_ratios`, `row_ratios`,
|
|
`scrolling`, and `grid`. When a rule matches, it completely replaces the base options. Fields
|
|
not specified in the matching rule default to their standard defaults (not the base
|
|
`layout_options` values).
|
|
|
|
### Example: Scrolling Layout with Dynamic Columns
|
|
|
|
```json
|
|
{
|
|
"layout": "Scrolling",
|
|
"layout_options": {
|
|
"scrolling": { "columns": 2 }
|
|
},
|
|
"layout_options_rules": {
|
|
"4": { "scrolling": { "columns": 3 } },
|
|
"7": { "scrolling": { "columns": 4 } }
|
|
}
|
|
}
|
|
```
|
|
|
|
This increases the visible scrolling columns as more windows are added.
|
|
|
|
## Layout Defaults
|
|
|
|
You can define global per-layout default `layout_options` and `layout_options_rules` using
|
|
the top-level `layout_defaults` setting. This avoids repeating the same configuration across
|
|
every workspace that uses the same layout.
|
|
|
|
### Configuration
|
|
|
|
```json
|
|
{
|
|
"layout_defaults": {
|
|
"VerticalStack": {
|
|
"layout_options": { "column_ratios": [0.7] },
|
|
"layout_options_rules": {
|
|
"2": { "column_ratios": [0.7] },
|
|
"3": { "column_ratios": [0.55] },
|
|
"5": { "column_ratios": [0.4] }
|
|
}
|
|
},
|
|
"Columns": {
|
|
"layout_options": { "column_ratios": [0.3, 0.4] },
|
|
"layout_options_rules": {
|
|
"4": { "column_ratios": [0.2, 0.3, 0.3] }
|
|
}
|
|
},
|
|
"HorizontalStack": {
|
|
"layout_options": { "row_ratios": [0.6] }
|
|
}
|
|
},
|
|
"monitors": [
|
|
{
|
|
"workspaces": [
|
|
{
|
|
"name": "main",
|
|
"layout": "VerticalStack"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
In this example, every workspace using `VerticalStack`, `Columns`, or `HorizontalStack`
|
|
automatically gets the global `layout_options` and `layout_options_rules` without needing
|
|
to specify them per-workspace. Note that `VerticalStack` only has 2 columns (main + stack),
|
|
so only a single `column_ratios` value is meaningful, while `Columns` distributes windows
|
|
across multiple columns where additional ratios control each column's width.
|
|
|
|
### Resolution Cascade
|
|
|
|
Global defaults act as a fallback. If a workspace defines **either** `layout_options` or
|
|
`layout_options_rules`, it **completely replaces** all global `layout_defaults` for that
|
|
layout. Global defaults are only used when the workspace has **neither** setting.
|
|
|
|
Within the effective source (workspace or global):
|
|
1. Try threshold match from the rules (highest matching threshold wins)
|
|
2. If a rule matches → use it (full replacement of base options)
|
|
3. Otherwise → use the base `layout_options`
|
|
|
|
### Override Examples
|
|
|
|
| Workspace Config | Global Config | Effective Behavior |
|
|
|------------------|---------------|--------------------|
|
|
| No `layout_options`, no rules | `layout_defaults` has both | Uses global base + global rules |
|
|
| Has `layout_options` only | `layout_defaults` has both | Workspace base only (all globals ignored) |
|
|
| Has `layout_options_rules` only | `layout_defaults` has both | Workspace rules only (all globals ignored) |
|
|
| Has both | `layout_defaults` has both | All workspace (all globals ignored) |
|
|
|
|
This "complete replacement" semantic means you never get a mix of workspace and global
|
|
settings for the same layout. If you override anything at the workspace level, you take
|
|
full control of that layout's options for that workspace.
|
|
|
|
## Progressive Ratio Behavior
|
|
|
|
Ratios are applied progressively as windows are added. For example, with `row_ratios: [0.3, 0.5]` in a VerticalStack:
|
|
|
|
| Windows in Stack | Row Heights |
|
|
|------------------|-------------|
|
|
| 1 | 100% |
|
|
| 2 | 30%, 70% (remainder) |
|
|
| 3 | 30%, 50%, 20% (remainder) |
|
|
| 4 | 30%, 50%, 10%, 10% (remainder split equally) |
|
|
| 5 | 30%, 50%, 6.67%, 6.67%, 6.67% |
|
|
|
|
## Automatic Ratio Truncation
|
|
|
|
When ratios sum to 100% (or more), they are automatically truncated at config load time.
|
|
|
|
For example, if you configure `column_ratios: [0.4, 0.3, 0.3]` (sums to 100%), the last ratio (0.3) is automatically removed, resulting in effectively `[0.4, 0.3]`. This ensures there's always remaining space for the last window.
|
|
|
|
| Configured Ratios | Effective Ratios | Reason |
|
|
|-------------------|------------------|--------|
|
|
| `[0.3, 0.4]` | `[0.3, 0.4]` | Sum is 0.7, below 1.0 |
|
|
| `[0.4, 0.3, 0.3]` | `[0.4, 0.3]` | Sum would be 1.0, last ratio truncated |
|
|
| `[0.5, 0.5]` | `[0.5]` | Sum would be 1.0, last ratio truncated |
|
|
| `[0.6, 0.5]` | `[0.6]` | Sum would exceed 1.0, last ratio truncated |
|
|
|
|
This ensures the layout always fills 100% of the available space and new windows are never placed outside the visible area.
|