docs: add alpha warning, contributing section and docs/config.md reference
- commit
- 95250ed440e19cc60c3d4a4be54fa471b8ab5c5b
- author
- brice · · 2026-09-26 16:05 UTC
- parent
- 0b8594d
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +138 -33
M README.md +10 -33
| @@ -11,6 +11,9 @@ | |||
| 11 | 11 | ||
| 12 | 12 | <p align="center">A minimal Wayland compositor in Go, built for performance: scrollable columns, multi-monitor workspaces and a zero-copy path for games.</p> | |
| 13 | 13 | ||
| 14 | + | > [!WARNING] | |
| 15 | + | > **Early alpha.** NeferWL is developed and tested mostly on AMD CPUs and GPUs. NVIDIA support is incomplete and untested; expect bugs and breaking config changes. | |
| 16 | + | ||
| 14 | 17 | --- | |
| 15 | 18 | ||
| 16 | 19 | ## Why NeferWL | |
| @@ -104,39 +107,7 @@ bind.ctrl+cmd+space = spawn fuzzel | |||
| 104 | 107 | startup = wl-paste --watch cliphist store | |
| 105 | 108 | ``` | |
| 106 | 109 | ||
| 107 | - | ### Keys | |
| 108 | - | ||
| 109 | - | | Key | Default | Meaning | | |
| 110 | - | |---|---|---| | |
| 111 | - | | `keyboard.layout`, `.variant`, `.options` | empty | xkb names, e.g. `fr`, `caps:escape` | | |
| 112 | - | | `keyboard.repeat-rate` / `repeat-delay` | `25` / `600` | Key repeat per second / delay in ms | | |
| 113 | - | | `keyboard.cmd` | `super` | Modifier that `cmd` means in binds: `super`, `alt` or `ctrl` | | |
| 114 | - | | `terminal` | `foot` | Opened at startup and by `spawn-terminal` | | |
| 115 | - | | `startup` | none | Command run once at session start; repeat the key for more | | |
| 116 | - | | `xwayland` | `xwayland-satellite` | X11 support; `off` disables it | | |
| 117 | - | | `background` | `#111111` | Solid background color | | |
| 118 | - | | `border.width` | `2` | Separator lines between tiles, in logical pixels; `0` hides them | | |
| 119 | - | | `border.active` / `border.inactive` | `#808080` / `#111111` | Separator colors around the focused / other windows | | |
| 120 | - | | `layout.gaps` | `0` | Space between windows | | |
| 121 | - | | `layout.max-columns` | `2` | Columns that share the screen before scrolling | | |
| 122 | - | | `layout.overflow` | `scroll` | Past the max: `scroll` right, or `fixed` spiral split | | |
| 123 | - | | `layout.presets` | `1/3, 1/2, 2/3, 1` | Widths for `cycle-column-width` | | |
| 124 | - | | `focus.follow-move` | `off` | Follow a column moved to another workspace | | |
| 125 | - | | `workspace.<name>.hidden` | `off` | Reachable only through its bind, which toggles it | | |
| 126 | - | | `workspace.<name>.monitor` | focused | Home monitor: connector (`DP-2`) or monitor key | | |
| 127 | - | | `workspace.<name>.max-columns`, `.overflow` | layout values | Per-workspace layout | | |
| 128 | - | | `workspace.<name>.column.<N>` | none | Slot: `<width>, <command>` | | |
| 129 | - | | `output.<name>` | preferred | `WxH`, `WxH@Hz`, `preferred` or `off` | | |
| 130 | - | | `output.<name>.scale` | `1` | 1 to 4, e.g. `1.5` or `4/3` | | |
| 131 | - | | `output.<name>.primary` | `off` | Gets focus and pointer at startup | | |
| 132 | - | | `render.direct-scanout` | `on` | Fullscreen buffers straight to the display | | |
| 133 | - | | `render.tearing` / `render.vrr` | `on` / `on` | For games in direct scanout | | |
| 134 | - | | `log.level` / `log.debug` | `info` / empty | Log level / debug components or `all` | | |
| 135 | - | | `bind.<keys>` | see below | Action for a key combo; `none` removes a default | | |
| 136 | - | ||
| 137 | - | Bind actions: `spawn <command>`, `spawn-terminal`, `close-window`, `toggle-fullscreen`, `cycle-column-width`, `focus-column-left/right`, `focus-window-up/down`, `move-column-left/right`, `consume-or-expel-window-left/right`, `focus-workspace <N>`, `focus-workspace-up/down`, `workspace <name>`, `move-column-to-workspace <N|up|down>`, `move-window-to-workspace <N|up|down>`, `focus-monitor-left/right`, `move-workspace-to-monitor-left/right`, `scale-up`, `scale-down`, `quit`. | |
| 138 | - | ||
| 139 | - | See `examples/config` for every default bind, with comments. A missing file means defaults. An invalid line logs a warning and keeps that key's default; the rest of the file still applies. Every key applies live when the file changes, including the keyboard layout; each reload logs the keys that changed. | |
| 110 | + | Every key, value and default bind is listed in [docs/config.md](docs/config.md); `examples/config` is a commented copy of the defaults. A missing file means defaults. An invalid line logs a warning and keeps that key's default; the rest of the file still applies. Every key applies live when the file changes, including the keyboard layout; each reload logs the keys that changed. | |
| 140 | 111 | ||
| 141 | 112 | ## Running commands | |
| 142 | 113 | ||
| @@ -231,6 +202,12 @@ As a software engineer, my passion is bringing more tools to the Go ecosystem. N | |||
| 231 | 202 | ||
| 232 | 203 | What Go does not give us is Rust's borrow checker: memory and concurrency mistakes are not caught at compile time. NeferWL makes up for it with strict ownership (one goroutine owns each piece of state), the race detector on every test run, and protocol tests against real Wayland clients. | |
| 233 | 204 | ||
| 205 | + | ## Contributing | |
| 206 | + | ||
| 207 | + | Contributions are welcome. Open an issue first, for a bug fix or a feature, and wait until it is accepted before sending a pull request. Pull requests without an accepted issue will be closed. | |
| 208 | + | ||
| 209 | + | Before a pull request, `make check`, `make race`, `make mocks-check` and `staticcheck ./...` must pass. Repository rules are in [AGENTS.md](AGENTS.md). | |
| 210 | + | ||
| 234 | 211 | ## License | |
| 235 | 212 | ||
| 236 | 213 | NeferWL is licensed under the [GNU General Public License v3.0](LICENSE). | |
| @@ -11,6 +11,9 @@ | |||||
| 11 | 11 | ||||
| 12 | <p align="center">A minimal Wayland compositor in Go, built for performance: scrollable columns, multi-monitor workspaces and a zero-copy path for games.</p> | 12 | <p align="center">A minimal Wayland compositor in Go, built for performance: scrollable columns, multi-monitor workspaces and a zero-copy path for games.</p> | ||
| 13 | 13 | ||||
| 14 | + | > [!WARNING] | |||
| 15 | + | > **Early alpha.** NeferWL is developed and tested mostly on AMD CPUs and GPUs. NVIDIA support is incomplete and untested; expect bugs and breaking config changes. | |||
| 16 | + | ||||
| 14 | --- | 17 | --- | ||
| 15 | 18 | ||||
| 16 | ## Why NeferWL | 19 | ## Why NeferWL | ||
| @@ -104,39 +107,7 @@ bind.ctrl+cmd+space = spawn fuzzel | |||||
| 104 | startup = wl-paste --watch cliphist store | 107 | startup = wl-paste --watch cliphist store | ||
| 105 | ``` | 108 | ``` | ||
| 106 | 109 | ||||
| 107 | - | ### Keys | 110 | + | Every key, value and default bind is listed in [docs/config.md](docs/config.md); `examples/config` is a commented copy of the defaults. A missing file means defaults. An invalid line logs a warning and keeps that key's default; the rest of the file still applies. Every key applies live when the file changes, including the keyboard layout; each reload logs the keys that changed. |
| 108 | - | ||||
| 109 | - | | Key | Default | Meaning | | |||
| 110 | - | |---|---|---| | |||
| 111 | - | | `keyboard.layout`, `.variant`, `.options` | empty | xkb names, e.g. `fr`, `caps:escape` | | |||
| 112 | - | | `keyboard.repeat-rate` / `repeat-delay` | `25` / `600` | Key repeat per second / delay in ms | | |||
| 113 | - | | `keyboard.cmd` | `super` | Modifier that `cmd` means in binds: `super`, `alt` or `ctrl` | | |||
| 114 | - | | `terminal` | `foot` | Opened at startup and by `spawn-terminal` | | |||
| 115 | - | | `startup` | none | Command run once at session start; repeat the key for more | | |||
| 116 | - | | `xwayland` | `xwayland-satellite` | X11 support; `off` disables it | | |||
| 117 | - | | `background` | `#111111` | Solid background color | | |||
| 118 | - | | `border.width` | `2` | Separator lines between tiles, in logical pixels; `0` hides them | | |||
| 119 | - | | `border.active` / `border.inactive` | `#808080` / `#111111` | Separator colors around the focused / other windows | | |||
| 120 | - | | `layout.gaps` | `0` | Space between windows | | |||
| 121 | - | | `layout.max-columns` | `2` | Columns that share the screen before scrolling | | |||
| 122 | - | | `layout.overflow` | `scroll` | Past the max: `scroll` right, or `fixed` spiral split | | |||
| 123 | - | | `layout.presets` | `1/3, 1/2, 2/3, 1` | Widths for `cycle-column-width` | | |||
| 124 | - | | `focus.follow-move` | `off` | Follow a column moved to another workspace | | |||
| 125 | - | | `workspace.<name>.hidden` | `off` | Reachable only through its bind, which toggles it | | |||
| 126 | - | | `workspace.<name>.monitor` | focused | Home monitor: connector (`DP-2`) or monitor key | | |||
| 127 | - | | `workspace.<name>.max-columns`, `.overflow` | layout values | Per-workspace layout | | |||
| 128 | - | | `workspace.<name>.column.<N>` | none | Slot: `<width>, <command>` | | |||
| 129 | - | | `output.<name>` | preferred | `WxH`, `WxH@Hz`, `preferred` or `off` | | |||
| 130 | - | | `output.<name>.scale` | `1` | 1 to 4, e.g. `1.5` or `4/3` | | |||
| 131 | - | | `output.<name>.primary` | `off` | Gets focus and pointer at startup | | |||
| 132 | - | | `render.direct-scanout` | `on` | Fullscreen buffers straight to the display | | |||
| 133 | - | | `render.tearing` / `render.vrr` | `on` / `on` | For games in direct scanout | | |||
| 134 | - | | `log.level` / `log.debug` | `info` / empty | Log level / debug components or `all` | | |||
| 135 | - | | `bind.<keys>` | see below | Action for a key combo; `none` removes a default | | |||
| 136 | - | ||||
| 137 | - | Bind actions: `spawn <command>`, `spawn-terminal`, `close-window`, `toggle-fullscreen`, `cycle-column-width`, `focus-column-left/right`, `focus-window-up/down`, `move-column-left/right`, `consume-or-expel-window-left/right`, `focus-workspace <N>`, `focus-workspace-up/down`, `workspace <name>`, `move-column-to-workspace <N|up|down>`, `move-window-to-workspace <N|up|down>`, `focus-monitor-left/right`, `move-workspace-to-monitor-left/right`, `scale-up`, `scale-down`, `quit`. | |||
| 138 | - | ||||
| 139 | - | See `examples/config` for every default bind, with comments. A missing file means defaults. An invalid line logs a warning and keeps that key's default; the rest of the file still applies. Every key applies live when the file changes, including the keyboard layout; each reload logs the keys that changed. | |||
| 140 | 111 | ||||
| 141 | ## Running commands | 112 | ## Running commands | ||
| 142 | 113 | ||||
| @@ -231,6 +202,12 @@ As a software engineer, my passion is bringing more tools to the Go ecosystem. N | |||||
| 231 | 202 | ||||
| 232 | What Go does not give us is Rust's borrow checker: memory and concurrency mistakes are not caught at compile time. NeferWL makes up for it with strict ownership (one goroutine owns each piece of state), the race detector on every test run, and protocol tests against real Wayland clients. | 203 | What Go does not give us is Rust's borrow checker: memory and concurrency mistakes are not caught at compile time. NeferWL makes up for it with strict ownership (one goroutine owns each piece of state), the race detector on every test run, and protocol tests against real Wayland clients. | ||
| 233 | 204 | ||||
| 205 | + | ## Contributing | |||
| 206 | + | ||||
| 207 | + | Contributions are welcome. Open an issue first, for a bug fix or a feature, and wait until it is accepted before sending a pull request. Pull requests without an accepted issue will be closed. | |||
| 208 | + | ||||
| 209 | + | Before a pull request, `make check`, `make race`, `make mocks-check` and `staticcheck ./...` must pass. Repository rules are in [AGENTS.md](AGENTS.md). | |||
| 210 | + | ||||
| 234 | ## License | 211 | ## License | ||
| 235 | 212 | ||||
| 236 | NeferWL is licensed under the [GNU General Public License v3.0](LICENSE). | 213 | NeferWL is licensed under the [GNU General Public License v3.0](LICENSE). | ||
A docs/config.md +128 -0
| @@ -0,0 +1,128 @@ | |||
| 1 | + | # Configuration | |
| 2 | + | ||
| 3 | + | NeferWL reads `$XDG_CONFIG_HOME/neferwl/config` (or `~/.config/neferwl/config`). `neferwl --config <path>` selects another file; `neferwl validate-config [path]` checks one without starting the compositor. | |
| 4 | + | ||
| 5 | + | ## Format | |
| 6 | + | ||
| 7 | + | - One `key = value` per line; `#` starts a comment. | |
| 8 | + | - Lists are comma-separated; booleans are `on` / `off`. | |
| 9 | + | - A missing file or key means the default. An invalid line logs a warning and keeps that key's default; the rest of the file still applies. A duplicate key warns and the last one wins. | |
| 10 | + | - Every key applies live when the file is saved; windows stay open. `startup` and `xwayland` take effect at the next start. | |
| 11 | + | ||
| 12 | + | ## Keys | |
| 13 | + | ||
| 14 | + | | Key | Default | Meaning | | |
| 15 | + | |---|---|---| | |
| 16 | + | | `keyboard.layout`, `.variant`, `.options` | empty | xkb names, e.g. `fr`, `caps:escape` | | |
| 17 | + | | `keyboard.repeat-rate` / `repeat-delay` | `25` / `600` | Key repeat per second / delay in ms | | |
| 18 | + | | `keyboard.cmd` | `super` | Modifier that `cmd` means in binds: `super`, `alt` or `ctrl` | | |
| 19 | + | | `terminal` | `foot` | Opened at startup and by `spawn-terminal` | | |
| 20 | + | | `startup` | none | Command run once at session start; repeat the key for more | | |
| 21 | + | | `xwayland` | `xwayland-satellite` | X11 support; `off` disables it | | |
| 22 | + | | `background` | `#111111` | Solid background color | | |
| 23 | + | | `border.width` | `2` | Separator lines between tiles, in logical pixels; `0` hides them | | |
| 24 | + | | `border.active` / `border.inactive` | `#808080` / `#111111` | Separator colors around the focused / other windows | | |
| 25 | + | | `layout.gaps` | `0` | Space between windows | | |
| 26 | + | | `layout.max-columns` | `2` | Columns that share the screen before scrolling | | |
| 27 | + | | `layout.overflow` | `scroll` | Past the max: `scroll` right, or `fixed` spiral split | | |
| 28 | + | | `layout.presets` | `1/3, 1/2, 2/3, 1` | Widths for `cycle-column-width` | | |
| 29 | + | | `focus.follow-move` | `off` | Follow a column moved to another workspace | | |
| 30 | + | | `workspace.<name>.hidden` | `off` | Reachable only through its bind, which toggles it | | |
| 31 | + | | `workspace.<name>.monitor` | focused | Home monitor: connector (`DP-2`) or monitor key | | |
| 32 | + | | `workspace.<name>.max-columns`, `.overflow` | layout values | Per-workspace layout | | |
| 33 | + | | `workspace.<name>.column.<N>` | none | Slot: `<width>, <command>` | | |
| 34 | + | | `output.<name>` | preferred | `WxH`, `WxH@Hz`, `preferred` or `off` | | |
| 35 | + | | `output.<name>.scale` | `1` | 1 to 4, e.g. `1.5` or `4/3` | | |
| 36 | + | | `output.<name>.primary` | `off` | Gets focus and pointer at startup | | |
| 37 | + | | `render.direct-scanout` | `on` | Fullscreen buffers straight to the display | | |
| 38 | + | | `render.tearing` / `render.vrr` | `on` / `on` | For games in direct scanout | | |
| 39 | + | | `log.level` / `log.debug` | `info` / empty | Log level / debug components or `all` | | |
| 40 | + | | `bind.<keys>` | see below | Action for a key combo; `none` removes a default | | |
| 41 | + | ||
| 42 | + | ## Binds | |
| 43 | + | ||
| 44 | + | `bind.<keys> = <action>`. Modifiers: `cmd` (see `keyboard.cmd`), `shift`, `ctrl`, `alt`, `super`. | |
| 45 | + | ||
| 46 | + | - Keys are what the active layout prints: `cmd+é` on AZERTY. Write `=`, `#` and space by name: `cmd+equal`, `cmd+numbersign`, `cmd+space`. | |
| 47 | + | - `code:N` is a physical key (evdev code), the same on every layout: `code:2` to `code:10` are the digit row 1 to 9. | |
| 48 | + | - `none` removes a default bind. | |
| 49 | + | - `spawn <command>` runs a program without a shell; see [Running commands](../README.md#running-commands). | |
| 50 | + | ||
| 51 | + | ### Actions | |
| 52 | + | ||
| 53 | + | | Action | Effect | | |
| 54 | + | |---|---| | |
| 55 | + | | `spawn <command>` | Run a program | | |
| 56 | + | | `spawn-terminal` | Run `terminal` | | |
| 57 | + | | `close-window` | Close the focused window | | |
| 58 | + | | `toggle-fullscreen` | Fullscreen the focused window | | |
| 59 | + | | `cycle-column-width` | Step through `layout.presets` | | |
| 60 | + | | `focus-column-left/right` | Focus the neighbor column; at the edge, the neighbor monitor | | |
| 61 | + | | `focus-window-up/down` | Focus in the column; past the edge, the next workspace | | |
| 62 | + | | `move-column-left/right` | Move the focused column | | |
| 63 | + | | `consume-or-expel-window-left/right` | A lone window joins the neighbor column; a stacked one leaves for a new column | | |
| 64 | + | | `focus-workspace <N>` / `focus-workspace-up/down` | Show a numbered or neighbor workspace | | |
| 65 | + | | `workspace <name>` | Toggle a named workspace | | |
| 66 | + | | `move-column-to-workspace <N>` / `-up/-down` | Move the focused column | | |
| 67 | + | | `move-window-to-workspace <N>` / `-up/-down` | Move only the focused window | | |
| 68 | + | | `focus-monitor-left/right` | Focus the neighbor monitor | | |
| 69 | + | | `move-workspace-to-monitor-left/right` | Move the workspace; it gets a new home | | |
| 70 | + | | `scale-up` / `scale-down` | Zoom the whole display | | |
| 71 | + | | `quit` | Exit NeferWL | | |
| 72 | + | ||
| 73 | + | ### Default binds | |
| 74 | + | ||
| 75 | + | | Keys | Action | | |
| 76 | + | |---|---| | |
| 77 | + | | `cmd+return` | `spawn-terminal` | | |
| 78 | + | | `cmd+left` | `focus-column-left` | | |
| 79 | + | | `cmd+right` | `focus-column-right` | | |
| 80 | + | | `cmd+up` | `focus-window-up` | | |
| 81 | + | | `cmd+down` | `focus-window-down` | | |
| 82 | + | | `cmd+shift+left` | `move-column-left` | | |
| 83 | + | | `cmd+shift+right` | `move-column-right` | | |
| 84 | + | | `cmd+h` | `focus-column-left` | | |
| 85 | + | | `cmd+l` | `focus-column-right` | | |
| 86 | + | | `cmd+k` | `focus-window-up` | | |
| 87 | + | | `cmd+j` | `focus-window-down` | | |
| 88 | + | | `cmd+shift+h` | `move-column-left` | | |
| 89 | + | | `cmd+shift+l` | `move-column-right` | | |
| 90 | + | | `cmd+bracketleft` | `consume-or-expel-window-left` | | |
| 91 | + | | `cmd+bracketright` | `consume-or-expel-window-right` | | |
| 92 | + | | `cmd+r` | `cycle-column-width` | | |
| 93 | + | | `cmd+shift+f` | `toggle-fullscreen` | | |
| 94 | + | | `cmd+q` | `close-window` | | |
| 95 | + | | `ctrl+alt+backspace` | `quit` | | |
| 96 | + | | `ctrl+cmd+space` | `spawn fuzzel` | | |
| 97 | + | | `cmd+pageup` | `focus-workspace-up` | | |
| 98 | + | | `cmd+pagedown` | `focus-workspace-down` | | |
| 99 | + | | `cmd+shift+pageup` | `move-column-to-workspace-up` | | |
| 100 | + | | `cmd+shift+pagedown` | `move-column-to-workspace-down` | | |
| 101 | + | | `cmd+code:2` | `focus-workspace 1` | | |
| 102 | + | | `cmd+code:3` | `focus-workspace 2` | | |
| 103 | + | | `cmd+code:4` | `focus-workspace 3` | | |
| 104 | + | | `cmd+code:5` | `focus-workspace 4` | | |
| 105 | + | | `cmd+code:6` | `focus-workspace 5` | | |
| 106 | + | | `cmd+code:7` | `focus-workspace 6` | | |
| 107 | + | | `cmd+code:8` | `focus-workspace 7` | | |
| 108 | + | | `cmd+code:9` | `focus-workspace 8` | | |
| 109 | + | | `cmd+code:10` | `focus-workspace 9` | | |
| 110 | + | | `cmd+shift+code:2` | `move-column-to-workspace 1` | | |
| 111 | + | | `cmd+shift+code:3` | `move-column-to-workspace 2` | | |
| 112 | + | | `cmd+shift+code:4` | `move-column-to-workspace 3` | | |
| 113 | + | | `cmd+shift+code:5` | `move-column-to-workspace 4` | | |
| 114 | + | | `cmd+shift+code:6` | `move-column-to-workspace 5` | | |
| 115 | + | | `cmd+shift+code:7` | `move-column-to-workspace 6` | | |
| 116 | + | | `cmd+shift+code:8` | `move-column-to-workspace 7` | | |
| 117 | + | | `cmd+shift+code:9` | `move-column-to-workspace 8` | | |
| 118 | + | | `cmd+shift+code:10` | `move-column-to-workspace 9` | | |
| 119 | + | | `cmd+ctrl+left` | `focus-monitor-left` | | |
| 120 | + | | `cmd+ctrl+right` | `focus-monitor-right` | | |
| 121 | + | | `cmd+ctrl+h` | `focus-monitor-left` | | |
| 122 | + | | `cmd+ctrl+l` | `focus-monitor-right` | | |
| 123 | + | | `cmd+ctrl+shift+left` | `move-workspace-to-monitor-left` | | |
| 124 | + | | `cmd+ctrl+shift+right` | `move-workspace-to-monitor-right` | | |
| 125 | + | | `cmd+ctrl+shift+h` | `move-workspace-to-monitor-left` | | |
| 126 | + | | `cmd+ctrl+shift+l` | `move-workspace-to-monitor-right` | | |
| 127 | + | | `cmd+code:13` | `scale-up` | | |
| 128 | + | | `cmd+code:12` | `scale-down` | | |
| @@ -0,0 +1,128 @@ | |||||
| 1 | + | # Configuration | |||
| 2 | + | ||||
| 3 | + | NeferWL reads `$XDG_CONFIG_HOME/neferwl/config` (or `~/.config/neferwl/config`). `neferwl --config <path>` selects another file; `neferwl validate-config [path]` checks one without starting the compositor. | |||
| 4 | + | ||||
| 5 | + | ## Format | |||
| 6 | + | ||||
| 7 | + | - One `key = value` per line; `#` starts a comment. | |||
| 8 | + | - Lists are comma-separated; booleans are `on` / `off`. | |||
| 9 | + | - A missing file or key means the default. An invalid line logs a warning and keeps that key's default; the rest of the file still applies. A duplicate key warns and the last one wins. | |||
| 10 | + | - Every key applies live when the file is saved; windows stay open. `startup` and `xwayland` take effect at the next start. | |||
| 11 | + | ||||
| 12 | + | ## Keys | |||
| 13 | + | ||||
| 14 | + | | Key | Default | Meaning | | |||
| 15 | + | |---|---|---| | |||
| 16 | + | | `keyboard.layout`, `.variant`, `.options` | empty | xkb names, e.g. `fr`, `caps:escape` | | |||
| 17 | + | | `keyboard.repeat-rate` / `repeat-delay` | `25` / `600` | Key repeat per second / delay in ms | | |||
| 18 | + | | `keyboard.cmd` | `super` | Modifier that `cmd` means in binds: `super`, `alt` or `ctrl` | | |||
| 19 | + | | `terminal` | `foot` | Opened at startup and by `spawn-terminal` | | |||
| 20 | + | | `startup` | none | Command run once at session start; repeat the key for more | | |||
| 21 | + | | `xwayland` | `xwayland-satellite` | X11 support; `off` disables it | | |||
| 22 | + | | `background` | `#111111` | Solid background color | | |||
| 23 | + | | `border.width` | `2` | Separator lines between tiles, in logical pixels; `0` hides them | | |||
| 24 | + | | `border.active` / `border.inactive` | `#808080` / `#111111` | Separator colors around the focused / other windows | | |||
| 25 | + | | `layout.gaps` | `0` | Space between windows | | |||
| 26 | + | | `layout.max-columns` | `2` | Columns that share the screen before scrolling | | |||
| 27 | + | | `layout.overflow` | `scroll` | Past the max: `scroll` right, or `fixed` spiral split | | |||
| 28 | + | | `layout.presets` | `1/3, 1/2, 2/3, 1` | Widths for `cycle-column-width` | | |||
| 29 | + | | `focus.follow-move` | `off` | Follow a column moved to another workspace | | |||
| 30 | + | | `workspace.<name>.hidden` | `off` | Reachable only through its bind, which toggles it | | |||
| 31 | + | | `workspace.<name>.monitor` | focused | Home monitor: connector (`DP-2`) or monitor key | | |||
| 32 | + | | `workspace.<name>.max-columns`, `.overflow` | layout values | Per-workspace layout | | |||
| 33 | + | | `workspace.<name>.column.<N>` | none | Slot: `<width>, <command>` | | |||
| 34 | + | | `output.<name>` | preferred | `WxH`, `WxH@Hz`, `preferred` or `off` | | |||
| 35 | + | | `output.<name>.scale` | `1` | 1 to 4, e.g. `1.5` or `4/3` | | |||
| 36 | + | | `output.<name>.primary` | `off` | Gets focus and pointer at startup | | |||
| 37 | + | | `render.direct-scanout` | `on` | Fullscreen buffers straight to the display | | |||
| 38 | + | | `render.tearing` / `render.vrr` | `on` / `on` | For games in direct scanout | | |||
| 39 | + | | `log.level` / `log.debug` | `info` / empty | Log level / debug components or `all` | | |||
| 40 | + | | `bind.<keys>` | see below | Action for a key combo; `none` removes a default | | |||
| 41 | + | ||||
| 42 | + | ## Binds | |||
| 43 | + | ||||
| 44 | + | `bind.<keys> = <action>`. Modifiers: `cmd` (see `keyboard.cmd`), `shift`, `ctrl`, `alt`, `super`. | |||
| 45 | + | ||||
| 46 | + | - Keys are what the active layout prints: `cmd+é` on AZERTY. Write `=`, `#` and space by name: `cmd+equal`, `cmd+numbersign`, `cmd+space`. | |||
| 47 | + | - `code:N` is a physical key (evdev code), the same on every layout: `code:2` to `code:10` are the digit row 1 to 9. | |||
| 48 | + | - `none` removes a default bind. | |||
| 49 | + | - `spawn <command>` runs a program without a shell; see [Running commands](../README.md#running-commands). | |||
| 50 | + | ||||
| 51 | + | ### Actions | |||
| 52 | + | ||||
| 53 | + | | Action | Effect | | |||
| 54 | + | |---|---| | |||
| 55 | + | | `spawn <command>` | Run a program | | |||
| 56 | + | | `spawn-terminal` | Run `terminal` | | |||
| 57 | + | | `close-window` | Close the focused window | | |||
| 58 | + | | `toggle-fullscreen` | Fullscreen the focused window | | |||
| 59 | + | | `cycle-column-width` | Step through `layout.presets` | | |||
| 60 | + | | `focus-column-left/right` | Focus the neighbor column; at the edge, the neighbor monitor | | |||
| 61 | + | | `focus-window-up/down` | Focus in the column; past the edge, the next workspace | | |||
| 62 | + | | `move-column-left/right` | Move the focused column | | |||
| 63 | + | | `consume-or-expel-window-left/right` | A lone window joins the neighbor column; a stacked one leaves for a new column | | |||
| 64 | + | | `focus-workspace <N>` / `focus-workspace-up/down` | Show a numbered or neighbor workspace | | |||
| 65 | + | | `workspace <name>` | Toggle a named workspace | | |||
| 66 | + | | `move-column-to-workspace <N>` / `-up/-down` | Move the focused column | | |||
| 67 | + | | `move-window-to-workspace <N>` / `-up/-down` | Move only the focused window | | |||
| 68 | + | | `focus-monitor-left/right` | Focus the neighbor monitor | | |||
| 69 | + | | `move-workspace-to-monitor-left/right` | Move the workspace; it gets a new home | | |||
| 70 | + | | `scale-up` / `scale-down` | Zoom the whole display | | |||
| 71 | + | | `quit` | Exit NeferWL | | |||
| 72 | + | ||||
| 73 | + | ### Default binds | |||
| 74 | + | ||||
| 75 | + | | Keys | Action | | |||
| 76 | + | |---|---| | |||
| 77 | + | | `cmd+return` | `spawn-terminal` | | |||
| 78 | + | | `cmd+left` | `focus-column-left` | | |||
| 79 | + | | `cmd+right` | `focus-column-right` | | |||
| 80 | + | | `cmd+up` | `focus-window-up` | | |||
| 81 | + | | `cmd+down` | `focus-window-down` | | |||
| 82 | + | | `cmd+shift+left` | `move-column-left` | | |||
| 83 | + | | `cmd+shift+right` | `move-column-right` | | |||
| 84 | + | | `cmd+h` | `focus-column-left` | | |||
| 85 | + | | `cmd+l` | `focus-column-right` | | |||
| 86 | + | | `cmd+k` | `focus-window-up` | | |||
| 87 | + | | `cmd+j` | `focus-window-down` | | |||
| 88 | + | | `cmd+shift+h` | `move-column-left` | | |||
| 89 | + | | `cmd+shift+l` | `move-column-right` | | |||
| 90 | + | | `cmd+bracketleft` | `consume-or-expel-window-left` | | |||
| 91 | + | | `cmd+bracketright` | `consume-or-expel-window-right` | | |||
| 92 | + | | `cmd+r` | `cycle-column-width` | | |||
| 93 | + | | `cmd+shift+f` | `toggle-fullscreen` | | |||
| 94 | + | | `cmd+q` | `close-window` | | |||
| 95 | + | | `ctrl+alt+backspace` | `quit` | | |||
| 96 | + | | `ctrl+cmd+space` | `spawn fuzzel` | | |||
| 97 | + | | `cmd+pageup` | `focus-workspace-up` | | |||
| 98 | + | | `cmd+pagedown` | `focus-workspace-down` | | |||
| 99 | + | | `cmd+shift+pageup` | `move-column-to-workspace-up` | | |||
| 100 | + | | `cmd+shift+pagedown` | `move-column-to-workspace-down` | | |||
| 101 | + | | `cmd+code:2` | `focus-workspace 1` | | |||
| 102 | + | | `cmd+code:3` | `focus-workspace 2` | | |||
| 103 | + | | `cmd+code:4` | `focus-workspace 3` | | |||
| 104 | + | | `cmd+code:5` | `focus-workspace 4` | | |||
| 105 | + | | `cmd+code:6` | `focus-workspace 5` | | |||
| 106 | + | | `cmd+code:7` | `focus-workspace 6` | | |||
| 107 | + | | `cmd+code:8` | `focus-workspace 7` | | |||
| 108 | + | | `cmd+code:9` | `focus-workspace 8` | | |||
| 109 | + | | `cmd+code:10` | `focus-workspace 9` | | |||
| 110 | + | | `cmd+shift+code:2` | `move-column-to-workspace 1` | | |||
| 111 | + | | `cmd+shift+code:3` | `move-column-to-workspace 2` | | |||
| 112 | + | | `cmd+shift+code:4` | `move-column-to-workspace 3` | | |||
| 113 | + | | `cmd+shift+code:5` | `move-column-to-workspace 4` | | |||
| 114 | + | | `cmd+shift+code:6` | `move-column-to-workspace 5` | | |||
| 115 | + | | `cmd+shift+code:7` | `move-column-to-workspace 6` | | |||
| 116 | + | | `cmd+shift+code:8` | `move-column-to-workspace 7` | | |||
| 117 | + | | `cmd+shift+code:9` | `move-column-to-workspace 8` | | |||
| 118 | + | | `cmd+shift+code:10` | `move-column-to-workspace 9` | | |||
| 119 | + | | `cmd+ctrl+left` | `focus-monitor-left` | | |||
| 120 | + | | `cmd+ctrl+right` | `focus-monitor-right` | | |||
| 121 | + | | `cmd+ctrl+h` | `focus-monitor-left` | | |||
| 122 | + | | `cmd+ctrl+l` | `focus-monitor-right` | | |||
| 123 | + | | `cmd+ctrl+shift+left` | `move-workspace-to-monitor-left` | | |||
| 124 | + | | `cmd+ctrl+shift+right` | `move-workspace-to-monitor-right` | | |||
| 125 | + | | `cmd+ctrl+shift+h` | `move-workspace-to-monitor-left` | | |||
| 126 | + | | `cmd+ctrl+shift+l` | `move-workspace-to-monitor-right` | | |||
| 127 | + | | `cmd+code:13` | `scale-up` | | |||
| 128 | + | | `cmd+code:12` | `scale-down` | | |||