Update README.md, add docs/CONFIGURATION.md
I've finally added a somewhat usable README and also explained configuration in docs/CONFIGURATION.md
This commit is contained in:
parent
0970702263
commit
8e93395360
5 changed files with 348 additions and 9 deletions
76
README.md
76
README.md
|
|
@ -1,12 +1,78 @@
|
||||||
# beansprout wm
|
# beansprout
|
||||||
|
|
||||||
A tiling window manager for the [river](https://codeberg.org/river/river/) Wayland compositor.
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A tiling window manager for the [river](https://codeberg.org/river/river/) Wayland compositor written in Zig.
|
||||||
|
The window manager communicates using the [river-window-management-v1](protocol/river-window-management-v1.xml)
|
||||||
|
protocol, as well as some of River's additional Wayland protocols.
|
||||||
|
|
||||||
|
Beansprout uses a primary/stack tiling layout inspired by dwm with a customizable ratio and primary count.
|
||||||
|
Similarly, beansprout has a 32-bit tag system, rather than workspaces. Each output has its own tags and own
|
||||||
|
primary count/ratio.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Requires [Zig](https://ziglang.org/) 0.15.1 or later.
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
To compile beansprout, you'll need the dependencies found below. I've listed the package names for Gentoo and
|
||||||
|
Debian/Ubuntu, but they likely exist on all major distros.
|
||||||
|
|
||||||
|
Needed at both build-time and runtime:
|
||||||
|
|
||||||
|
| Dependency | Gentoo Name | Debian/Ubuntu Name |
|
||||||
|
|--------------------|-----------------------------|---------------------|
|
||||||
|
| wayland-client | `dev-libs/wayland` | `libwayland-dev` |
|
||||||
|
| pixman | `x11-libs/pixman` | `libpixman-1-dev` |
|
||||||
|
| xkbcommon | `x11-libs/libxkbcommon` | `libxkbcommon-dev` |
|
||||||
|
|
||||||
|
Only needed at build-time:
|
||||||
|
|
||||||
|
| Dependency | Gentoo Name | Debian/Ubuntu Name |
|
||||||
|
|--------------------|------------------------------|---------------------|
|
||||||
|
| wayland-protocols | `dev-libs/wayland-protocols` | `wayland-protocols` |
|
||||||
|
|
||||||
|
#### Note for Gentoo Users
|
||||||
|
|
||||||
|
Beansprout is available in my personal [ebuild repo](https://codeberg.org/bwbuhse/beansprout).
|
||||||
|
Right now, it's just a live ebuild, but I will add versioned ebuilds once v0.1.0 is released.
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
Build and install with:
|
||||||
|
|
||||||
|
```
|
||||||
|
zig build -Doptimize=ReleaseSafe --prefix ~/.local install
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `zig build -h` to see a list of all options.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
More to come.
|
You can either add `beansprout` to the river `init` file or directly run `river -c beansprout`.
|
||||||
|
|
||||||
## License
|
If you need to exit river, for example, if `beansprout` crashes, you can use river's hardcoded
|
||||||
|
`Ctrl+Alt+Delete` keybind.
|
||||||
|
|
||||||
GPL-3.0-only
|
## Configuration
|
||||||
|
|
||||||
|
Beansprout is configured with a [KDL](https://kdl.dev) file at
|
||||||
|
`$XDG_CONFIG_HOME/beansprout/config.kdl`. See [docs/CONFIGURATION.md](docs/CONFIGURATION.md)
|
||||||
|
for a full reference and [examples/config.kdl](examples/config.kdl) for an example config.
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
This project follows the [REUSE Specification](https://reuse.software/spec-3.3/),
|
||||||
|
all files have SPDX copyright and license information and/or are listed under
|
||||||
|
`REUSE.toml`.
|
||||||
|
|
||||||
|
In overview:
|
||||||
|
|
||||||
|
- beansprout's source code is released under the GPL-3.0-only license.
|
||||||
|
- beansprout's documentation is released under the CC-BY-4.0 license.
|
||||||
|
- beansprout's examples are released under the CC0-1.0 license.
|
||||||
|
|
||||||
|
All licenses can be found under `LICENSES`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
version = 1
|
version = 1
|
||||||
|
|
||||||
[[annotations]]
|
[[annotations]]
|
||||||
path = ["README.md", "docs/TODO.md"]
|
path = ["README.md", "docs/**"]
|
||||||
SPDX-FileCopyrightText = "2026 Ben Buhse <me@benbuhse.email>"
|
SPDX-FileCopyrightText = "2026 Ben Buhse <me@benbuhse.email>"
|
||||||
SPDX-License-Identifier = "CC-BY-4.0"
|
SPDX-License-Identifier = "CC-BY-4.0"
|
||||||
|
|
||||||
|
|
|
||||||
270
docs/CONFIGURATION.md
Normal file
270
docs/CONFIGURATION.md
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
# Configuration
|
||||||
|
|
||||||
|
Beansprout is configured with a [KDL](https://kdl.dev) file located at:
|
||||||
|
|
||||||
|
```
|
||||||
|
$XDG_CONFIG_HOME/beansprout/config.kdl
|
||||||
|
```
|
||||||
|
|
||||||
|
If `$XDG_CONFIG_HOME` is not set, this defaults to `~/.config/beansprout/config.kdl`.
|
||||||
|
|
||||||
|
An example config can be found at [examples/config.kdl](../examples/config.kdl).
|
||||||
|
|
||||||
|
If the config file is missing, beansprout falls back to its built-in defaults (which
|
||||||
|
is missing keybinds!). Similarly, if an individual node or block is invalid, it will
|
||||||
|
try to ignore the error and continue on.
|
||||||
|
|
||||||
|
All configuration is applied top down, so later options will overwrite earlier ones.
|
||||||
|
|
||||||
|
## General Settings
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
// Whether new windows should go to the top or bottom of the window stack
|
||||||
|
attach_mode "top"
|
||||||
|
|
||||||
|
// Whether mousing over a new window should move focus
|
||||||
|
focus_follows_pointer #true
|
||||||
|
|
||||||
|
// Whether the focus should warp to the center of newly-focused windows
|
||||||
|
pointer_warp_on_focus_change #true
|
||||||
|
|
||||||
|
// Path to image to use as wallpaper
|
||||||
|
// The same image is displayed on all outputs, but scaled separately
|
||||||
|
// If this config is missing, then the background is blank black screen
|
||||||
|
wallpaper_image_path "~/Pictures/wallpaper.png"
|
||||||
|
```
|
||||||
|
|
||||||
|
| Setting | Type | Default | Description |
|
||||||
|
|------------------------------|--------|---------|-----------------------------------------------------|
|
||||||
|
| `attach_mode` | enum | `top` | Where new windows go in the stack (`top` or `bottom`) |
|
||||||
|
| `focus_follows_pointer` | bool | `#true` | Focus follows the pointer between windows |
|
||||||
|
| `pointer_warp_on_focus_change` | bool | `#true` | Warp pointer to center of newly-focused windows |
|
||||||
|
| `wallpaper_image_path` | string | none | Path to wallpaper image |
|
||||||
|
|
||||||
|
Boolean values can be written as `#true`/`#false` or `true`/`false`.
|
||||||
|
|
||||||
|
## Borders
|
||||||
|
|
||||||
|
Border settings are placed inside a `borders` block:
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
borders {
|
||||||
|
width 2
|
||||||
|
color_focused "0x89b4fa"
|
||||||
|
color_unfocused "0x1e1e2e"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Setting | Type | Default | Description |
|
||||||
|
|-------------------|--------|--------------|------------------------------------|
|
||||||
|
| `width` | u8 | `2` | Border width in pixels |
|
||||||
|
| `color_focused` | color | `0x89b4fa` | Border color of the focused window |
|
||||||
|
| `color_unfocused` | color | `0x1e1e2e` | Border color of unfocused windows |
|
||||||
|
|
||||||
|
Colors are specified in `0xRRGGBB` or `0xRRGGBBAA` hex format.
|
||||||
|
|
||||||
|
## Keybinds
|
||||||
|
|
||||||
|
Keyboard bindings are placed inside a `keybinds` block. Each binding has the
|
||||||
|
form:
|
||||||
|
|
||||||
|
```
|
||||||
|
command modifiers keysym [arguments...]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modifiers
|
||||||
|
|
||||||
|
Modifiers are combined with `+`. They are case-insensitive.
|
||||||
|
|
||||||
|
| Modifier | Description |
|
||||||
|
|------------------|--------------------|
|
||||||
|
| `None` | No modifier, e.g. for media keys |
|
||||||
|
| `Mod4` or `Super` | Super/Windows key |
|
||||||
|
| `Shift` | Shift key |
|
||||||
|
| `Ctrl` | Control key |
|
||||||
|
| `Mod1` or `Alt` | Alt key |
|
||||||
|
| `Mod3` | Mod3 key |
|
||||||
|
| `Mod5` | Mod5 key |
|
||||||
|
|
||||||
|
Example: `Mod4+Shift`, `Ctrl+Alt`, `None`
|
||||||
|
|
||||||
|
### Keysyms
|
||||||
|
|
||||||
|
Keysym names follow the XKB naming convention (case-insensitive). Most keys
|
||||||
|
are simply the character that is typed, e.g. `T`, or `f`, while others have
|
||||||
|
names such as `Return` for the "enter" or "return" key, `Space`, or
|
||||||
|
`XF86AudioRaiseVolume`.
|
||||||
|
|
||||||
|
A full list of the key names can typically be found at
|
||||||
|
`/usr/include/xkbcommon/xkbcommon-keysyms.h`.
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
keybinds {
|
||||||
|
// Launch a program. The third argument is the command to run.
|
||||||
|
spawn Mod4 T "foot"
|
||||||
|
|
||||||
|
// Focus the next/previous window in the stack
|
||||||
|
focus_next_window Mod4 J
|
||||||
|
focus_prev_window Mod4 K
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Full command reference:
|
||||||
|
|
||||||
|
| Command | Arguments | Description |
|
||||||
|
|--------------------------|------------------|---------------------------------------------------|
|
||||||
|
| `spawn` | command (string) | Launch a program |
|
||||||
|
| `focus_next_window` | | Focus next window in stack |
|
||||||
|
| `focus_prev_window` | | Focus previous window in stack |
|
||||||
|
| `focus_next_output` | | Focus next output |
|
||||||
|
| `focus_prev_output` | | Focus previous output |
|
||||||
|
| `send_to_next_output` | | Send focused window to next output |
|
||||||
|
| `send_to_prev_output` | | Send focused window to previous output |
|
||||||
|
| `zoom` | | Swap focused window with the primary window |
|
||||||
|
| `swap_next` | | Swap focused window with the next in stack |
|
||||||
|
| `swap_prev` | | Swap focused window with the previous in stack |
|
||||||
|
| `toggle_float` | | Float/unfloat the focused window |
|
||||||
|
| `toggle_fullscreen` | | Toggle fullscreen on focused window |
|
||||||
|
| `close_window` | | Close the focused window |
|
||||||
|
| `change_ratio` | float | Adjust primary/stack ratio on current output |
|
||||||
|
| `increment_primary_count`| | Add a window to the primary side |
|
||||||
|
| `decrement_primary_count`| | Remove a window from the primary side |
|
||||||
|
| `move_up` | pixels | Move floating window up |
|
||||||
|
| `move_down` | pixels | Move floating window down |
|
||||||
|
| `move_left` | pixels | Move floating window left |
|
||||||
|
| `move_right` | pixels | Move floating window right |
|
||||||
|
| `resize_width` | pixels | Resize floating window width (negative to shrink) |
|
||||||
|
| `resize_height` | pixels | Resize floating window height (negative to shrink)|
|
||||||
|
| `set_output_tags` | tags (u32 bitmask) | Set the tags on the focused output |
|
||||||
|
| `set_window_tags` | tags (u32 bitmask) | Set the tags on the focused window |
|
||||||
|
| `toggle_output_tags` | tags (u32 bitmask) | Toggle a tag on the focused output |
|
||||||
|
| `toggle_window_tags` | tags (u32 bitmask) | Toggle a tag on the focused window |
|
||||||
|
| `reload_config` | | Reload the config file |
|
||||||
|
|
||||||
|
### Tag Binds
|
||||||
|
|
||||||
|
Tags use a 32-bit bitfield. Instead of binding each tag key individually,
|
||||||
|
you can also use the special `tag_bind` command to automatically generates
|
||||||
|
bindings for keys `1` through `9`, mapped to tags `1<<0` through `1<<8`:
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
keybinds {
|
||||||
|
// Mod4+1 switches to tag 1, Mod4+2 to tag 2, etc.
|
||||||
|
tag_bind Mod4 set_output_tags
|
||||||
|
// Mod4+Shift+1 moves the focused window to tag 1, etc.
|
||||||
|
tag_bind Mod4+Shift set_window_tags
|
||||||
|
// Mod4+Ctrl+1 toggles tag 1 visibility, etc.
|
||||||
|
tag_bind Mod4+Ctrl toggle_output_tags
|
||||||
|
// Mod4+Ctrl+Shift+1 toggles tag 1 on the focused window, etc.
|
||||||
|
tag_bind Mod4+Ctrl+Shift toggle_window_tags
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
As mentioned in the table above, you can also bind specific tag values directly
|
||||||
|
using the regular keybind syntax with the `set_output_tags`, `set_window_tags`,
|
||||||
|
`toggle_output_tags`, and `toggle_window_tags` commands. The argument is a
|
||||||
|
32-bit integer representing the tag bitfield, e.g. `0x0001` is tag `1`, `0x0003`
|
||||||
|
is tags 1 and 2. Any format supported by Zig's `parseInt()` is accepted. This
|
||||||
|
can be useful if you don't want to use keys 1-9 for your binds or if you want
|
||||||
|
more than 10 tags in use, for example, for a "scratchpad".
|
||||||
|
|
||||||
|
## Pointer Binds
|
||||||
|
|
||||||
|
Mouse button bindings are placed inside a `pointer_binds` block:
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
pointer_binds {
|
||||||
|
// Mod4 + left click to move floating windows
|
||||||
|
move_window Mod4 BTN_LEFT
|
||||||
|
// Mod4 + right click to resize floating windows
|
||||||
|
resize_window Mod4 BTN_RIGHT
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Action | Description |
|
||||||
|
|-----------------|----------------------------------|
|
||||||
|
| `move_window` | Drag to move the window |
|
||||||
|
| `resize_window` | Drag to resize the window |
|
||||||
|
|
||||||
|
Button names: `BTN_LEFT` / `button1`, `BTN_RIGHT` / `button3`,
|
||||||
|
`BTN_MIDDLE` / `button2`. Numeric button codes (decimal or hex) are also
|
||||||
|
accepted. Button names are case-insensitive.
|
||||||
|
|
||||||
|
To find button codes, you can usually look in `/usr/include/linux/input-event-codes.h`.
|
||||||
|
|
||||||
|
## Input Device Configuration
|
||||||
|
|
||||||
|
Input device settings are placed inside `input` blocks. A block without a
|
||||||
|
`name=` property applies to all devices. A block with `name=` applies only to
|
||||||
|
the matching device:
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
// Default settings for all devices
|
||||||
|
input {
|
||||||
|
accel_profile "flat"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings for a specific device (overrides the defaults)
|
||||||
|
input name="PIXA3854:00 093A:0274 Touchpad" {
|
||||||
|
accel_profile "adaptive"
|
||||||
|
click_method "clickfinger"
|
||||||
|
natural_scroll "enabled"
|
||||||
|
tap "disabled"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Input Settings
|
||||||
|
|
||||||
|
All libinput configuration options supported by river should also be supported by beansprout.
|
||||||
|
|
||||||
|
| Setting | Type | Values |
|
||||||
|
|------------------------|--------|------------------------------------------------------|
|
||||||
|
| `accel_profile` | enum | `none`, `flat`, `adaptive`, `custom` |
|
||||||
|
| `accel_speed` | float | |
|
||||||
|
| `click_method` | enum | `none`, `button_areas`, `clickfinger` |
|
||||||
|
| `clickfinger_button_map` | enum | `lrm`, `lmr` |
|
||||||
|
| `drag` | enum | `disabled`, `enabled` |
|
||||||
|
| `drag_lock` | enum | `disabled`, `enabled_timeout`, `enabled_sticky` |
|
||||||
|
| `dwt` | enum | `disabled`, `enabled` |
|
||||||
|
| `dwtp` | enum | `disabled`, `enabled` |
|
||||||
|
| `left_handed` | enum | `disabled`, `enabled` |
|
||||||
|
| `middle_emulation` | enum | `disabled`, `enabled` |
|
||||||
|
| `natural_scroll` | enum | `disabled`, `enabled` |
|
||||||
|
| `rotation` | u32 | Rotation angle in degrees |
|
||||||
|
| `scroll_button` | button | Button name or code (see Pointer Binds) |
|
||||||
|
| `scroll_button_lock` | enum | `disabled`, `enabled` |
|
||||||
|
| `scroll_method` | enum | `no_scroll`, `two_finger`, `edge`, `on_button_down` |
|
||||||
|
| `send_events` | enum | `enabled`, `disabled`, `disabled_on_external_mouse` |
|
||||||
|
| `tap` | enum | `disabled`, `enabled` |
|
||||||
|
| `tap_button_map` | enum | `lrm`, `lmr` |
|
||||||
|
| `three_finger_drag` | enum | `disabled`, `enabled_3fg`, `enabled_4fg` |
|
||||||
|
|
||||||
|
**dwt** = disable while typing. **dwtp** = disable while trackpointing.
|
||||||
|
|
||||||
|
## Per-Host Configuration
|
||||||
|
|
||||||
|
Any node can also have a `host=` property to restrict it to a specific
|
||||||
|
hostname. This is useful for sharing a config file across machines:
|
||||||
|
|
||||||
|
```kdl
|
||||||
|
// Per-host wallpaper
|
||||||
|
wallpaper_image_path "~/Pictures/desktop.png" host="desktop"
|
||||||
|
wallpaper_image_path "~/Pictures/laptop.png" host="laptop"
|
||||||
|
|
||||||
|
// Per-host border width inside a borders block
|
||||||
|
borders {
|
||||||
|
width 4 host="desktop"
|
||||||
|
width 2 host="laptop"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per-host keybind
|
||||||
|
keybinds {
|
||||||
|
spawn Mod4 T "foot" host="laptop"
|
||||||
|
spawn Mod4 T "alacritty" host="desktop"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nodes without a `host=` property apply to all hosts.
|
||||||
|
|
@ -2,10 +2,13 @@
|
||||||
|
|
||||||
These are in rough order of my priority, though no promises I do them in this order.
|
These are in rough order of my priority, though no promises I do them in this order.
|
||||||
|
|
||||||
- [ ] Implement an optional clock bar
|
- [ ] Implement primary count/ratio per tagmask
|
||||||
|
- [ ] Add primary_count and primary_ratio to Config
|
||||||
- [ ] Implement a river-tag-overlay clone
|
- [ ] Implement a river-tag-overlay clone
|
||||||
- [ ] Support overriding config location
|
- [ ] Implement an optional clock bar
|
||||||
- [ ] Support window rules (float/tags/SSD by app-id/title)
|
- [ ] Support window rules (float/tags/SSD by app-id/title)
|
||||||
|
- [ ] Support overriding config location
|
||||||
|
- [ ] Support configuring primary vs secondary stack side
|
||||||
- [ ] Support switch handling (e.g. lid close)
|
- [ ] Support switch handling (e.g. lid close)
|
||||||
- [ ] Support keybind modes (e.g. passthrough)
|
- [ ] Support keybind modes (e.g. passthrough)
|
||||||
- [ ] Support solid `background-color` fallback (no wallpaper)
|
- [ ] Support solid `background-color` fallback (no wallpaper)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ keybinds {
|
||||||
// Brightness keys (no modifier)
|
// Brightness keys (no modifier)
|
||||||
spawn None XF86MonBrightnessUp "~/.config/river/brightness-up.sh"
|
spawn None XF86MonBrightnessUp "~/.config/river/brightness-up.sh"
|
||||||
spawn None XF86MonBrightnessDown "~/.config/river/brightness-down.sh"
|
spawn None XF86MonBrightnessDown "~/.config/river/brightness-down.sh"
|
||||||
// Special command to generate keybinds for keys 1-9 and tags 1<<0 through 1<<9
|
// Special command to generate keybinds for keys 1-9 and tags 1<<0 through 1<<8
|
||||||
tag_bind Mod4 set_output_tags
|
tag_bind Mod4 set_output_tags
|
||||||
tag_bind Mod4+Shift set_window_tags
|
tag_bind Mod4+Shift set_window_tags
|
||||||
tag_bind Mod4+Ctrl toggle_output_tags
|
tag_bind Mod4+Ctrl toggle_output_tags
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue