RIVER-ULTITILE(1)
π¦ river-ultitile β river-ultitile(1) from the General Commands Manual π¦
Okay so bestie, welcome to the river-ultitile(1) page. river-ultitile is a layout generator for river, and hereβs the whole vibe. Features include:
- configurable layouts employing nested tiles (no juggling with coordinates, thank god),
- widescreen support by default,
- default layouts, switchable at run time with a command or key binding:
dwm-like main/stack layout,- main on the left on normal screens,
- main in the center and stacks on both sides on widescreens,
- a vertical stack,
- a horizontal stack, and
- a monocle layout,
- optional per-tag-per-output state.
π οΈ Building
Requirements, bestie:
- Zig
- Zig
0.14sincev1.3.0 - Zig
0.13up tov1.2.1 - Zig
0.12up tov1.1.3
- Zig
wayland-protocols
Download the sources with:
git clone https://git.sr.ht/~midgard/river-ultitile -b v1.3.0
Build with e.g.:
cd river-ultitile
zig build -Doptimize=ReleaseSafe --prefix ~/.local
And make sure ~/.local/bin is in your path. Periodt. β¨
π Quick start
Integrate the snippet into your river init file and look at the key bindings it defines. Thatβs the whole quick-start tea. π«Ά
π§ Usage and configuration
Configuration of layouts happens by modifying src/user_config.zig and recompiling (see Configuring layouts below). Layouts can use parameters that can be modified at runtime (see Modifying parameters below).
Any error messages will appear in the stderr of river, so if your configuration isnβt working as expected, look there.
If your setup is acting sus, check riverβs stderr β thatβs where the error messages show up. π
π Example river init file snippet
This snippet can be integrated in your river init file (usually $XDG_CONFIG_HOME/river/init). If youβre just getting started with river, note that you will want to add more than this. Look at riverβs documentation and default init file for that.
mod=Super
riverctl map normal $mod K focus-view previous
riverctl map normal $mod J focus-view next
riverctl map normal $mod Z zoom
# Rest of river configuration...
# Set the default layout generator to be river-ultitile and start it.
# River will send the process group of the init executable SIGTERM on exit.
riverctl default-layout river-ultitile
river-ultitile &
# These keybinds work with the default river-ultitile layouts
# Increase/decrease the main size
riverctl map normal $mod U send-layout-cmd river-ultitile "set integer main-size += 4"
riverctl map normal $mod I send-layout-cmd river-ultitile "set integer main-size -= 4"
# Decrease/increase the main size if it is in the center (on widescreens) and
# there are no views to the left or right
riverctl map normal $mod+Shift U send-layout-cmd river-ultitile "set integer main-size-if-only-centered-main += 4"
riverctl map normal $mod+Shift I send-layout-cmd river-ultitile "set integer main-size-if-only-centered-main -= 4"
# Decrease/increase the main count
riverctl map normal $mod N send-layout-cmd river-ultitile "set integer main-count += 1"
riverctl map normal $mod M send-layout-cmd river-ultitile "set integer main-count -= 1"
# Change layout
riverctl map normal $mod Up send-layout-cmd river-ultitile "set string layout = vstack"
riverctl map normal $mod Right send-layout-cmd river-ultitile "set string layout = hstack"
riverctl map normal $mod Down send-layout-cmd river-ultitile "set string layout = monocle"
riverctl map normal $mod Left send-layout-cmd river-ultitile "set string layout = main"
# Cycle through layouts on all tags/outputs
riverctl map normal $mod E spawn "riverctl send-layout-cmd river-ultitile 'unset-all-local layout'; riverctl send-layout-cmd river-ultitile 'set global string layout @ main hstack vstack'"
βΆοΈ Running river-ultitile
In your river init file, start river-ultitile as a background process. Yes, with the &. π
ποΈ Modifying parameters
To change the parameters that are used in the configuration, you send commands to river-ultitile using:
riverctl send-layout-cmd river-ultitile "<command>"
where <command> takes one of the following forms:
ποΈ set [global] <variable_type> <variable_name> <operator> <value...>
Set the value for a parameter called <variable_name>.
[global]: By default, a parameter assignment will be bound to the current dominant tag (the least-significant bit) of the currently focused Wayland output (monitor). Addingglobalto a definition will instead apply to all tags of all outputs.<variable_type>βinteger(32-bit signed integers) βstringβboolean(eithertrueorfalse)<operator>β=(set value, takes only one<value>) β@(cycle between an arbitrary amount of unique values) β For integers only:+=,-=(add and subtract from current value)
π§Ή unset-local <variable_name>
Unset local assignments for <variable_name> for the current tags of the currently focused Wayland output.
π§Ό unset-all-local <variable_name>
Unset local assignments for <variable_name> for all tags of all Wayland outputs.
π§© Configuring layouts
Modifying layouts is done by modifying src/user_config.zig and recompiling (see Building above).
In the src/user_config.zig file, the function layoutSpecification should return your layout expressed in terms of tiles which can be nested arbitrarily deep. Certain tiles should be designated to hold views by setting their max_views to null (for unlimited) or a non-zero number.
Tiles can have their contents arranged horizontally (typ=.hsplit), vertically (typ=.vsplit), or superimposed (typ=.overlay).
Views are assigned to tiles in an order determined by the order property of the tiles. The assignment of views starts with the lower orders, so order 0 gets the view on the top of the river view stack. To divide views evenly between tiles, give them the same order and use suborder to determine which tiles will be filled first. Having tiles with the same order and suborder and a non-zero max_views is not allowed.
+---left---+--center--+--right---+
|order=1 |order=0 |order=1 |
|suborder=1| |suborder=0|
| |maxviews=1| |
+----------+----------+----------+
In this example, views are assigned in this order: center, right, left, right, left ...
Tiles with the sameorderandsuborderplus a non-zeromax_views? Not allowed, bestie. π«
Tile properties are:
typ=<.hsplit|.vsplit|.overlay>(default.hsplit)padding=<number|null>(defaultnull;nullmeans inherit): space around the tileβs contents, in pixelsmargin=<number>(default0): space around the tile, in pixelsstretch=<number>(default100): a relativewidth*specifier. The stretches of a tileβs subtiles are summed, and the subtiles get awidth*proportional to their stretch divided by that sum. Views always have a stretch of100.order=<number>(default0): see abovesuborder=<number>(default0): see abovemax_views=<number|null>(default0;nullmeans unlimited): the maximum amount of views that will be assigned to this tile
*: or height for vsplit
Of course you can also use dynamic parameters in your custom layout. The variables object passed to the layoutSpecification function has methods getString, getInteger and getBoolean for that. Make sure to specify a default value in setDefaultVariables, or get... will return null.
If your layout is not behaving as expected, you can build river-ultitile in debug mode (with -Doptimize=Debug) which will cause river-ultitile to log each view itβs proposing. Debug mode ate, fr fr. π₯
π€ Contributing
See https://git.sr.ht/~midgard/river-ultitile/tree/main/item/CONTRIBUTING.md
π Thanks
Thanks to Isaac Freund and Leon Henrik Plickat for river obviously!
Thanks to Hugo Machet for rivercarro, from which river-ultitile is forked!
π License
river-ultitile is licensed under the GNU General Public License v3.0 or later.
Files in common/ and protocol/ directories are released under various licenses by various parties. You should refer to the copyright block of each file for the licensing information.
π URLs
Project homepage: https://sr.ht/~midgard/river-ultitile/
Thatβs a wrap on the RIVER-ULTITILE(1) page, bestie: version river-ultitile 1.3.0, dated 2026-10-25. Go slay your tiling. π
β¨
π¦ where this page comes from
- nixos 26.05: river-ultitile 1.3.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms