River convinced me to switch from i3 in one day


A Long Time Coming

I’ve been using i3 and sway for around 4 years now. Once I found out about it, I never wanted to look back. I don’t care how my desktop looks, I just want my windows in a grid.

I have tried other window managers (qtile and awesomewm mainly) but none of them stuck with me. It all felt like it was adding too much to what should be a simple formula: Window Management! That’s all I want! No fancy features.

RiverWm

Introduction

It was inevitable I was going to end up on something minimal and wayland. I’ve been slimming down the tools I use as of late. I only use foot term now on wayland, for example. As I was looking into what the window manager scene looked like in 2024, I remembered one distinct name I’ve seen in some neofetch screenshots: River.

I searched for the repository, which can be found here. I was very attracted to their design goals, which I’ll summarize myself below:

  1. Using your window manager should be effortless. You shouldn’t have to think about where the next window opens - it should always be the next ideal spot.
  2. Window management based on views (?) and tags (what they call workspaces)
  3. Dynamic layouts are generated by binaries. What this means is how your windows tile is a program itself. For example, I’m using this bsp-layout to have a simple 4x4 grid tiling pattern.
  4. Scriptable configuration. Can be done in multiple languages, bash being the easiest

What It Looks Like

I’m sure you’re all dying to know what my super cool linux rice looks like. Get ready for this:

That’s right. You can’t see the background and it’s just a grid of windows… like I alread did in i3! The difference is the windows automatically tile in river. I don’t have to specify horizontal or vertical for the next one, river does it for me.

As for the bar, this is just waybar with a gruvbox theme I stole from this random github repo. As you can see, waybar does work with River’s tag system to show the different “tags”, aka “workspaces”.

How do you configure it?

I mentioned above that the configuration file for this window manager is actually an executable file. In my case, I stuck with a shell script since it’s the easiest to work woith. There are only a few fundamental commands you really need to know when configuring river WM.

exec

Just like in i3 and sway, if you need to execute commands to act as daemons, you can place them in your ~/.config/init like so

150 # Sets swayidle & swaylock to start
151 exec swayidle -w timeout 360 'bash $HOME/.config/sway/swaylock.sh' &
152
153 # Turns on the foot server
154 exec foot -s &

As you can see, I’m still using swaylock from my sway setup. All the sway tools will work with river. Anyways, when it comes to executing arbitrary commands, just use exec. Also make sure that if the command needs to run in the background, include the & at the end of the command. Yes it does matter!

riverctl

One of the first things you need to do when installing a new window manager is to set up your keyboard shortcuts. You do this specifically with the riverctl command. I’ll show you some examples then explain what’s going on.

136 # custom mapping
137 riverctl map normal Super D spawn 'wofi --show drun'
138 riverctl map normal Super+Shift F spawn '$HOME/.config/sway/screenshot.sh'
139 riverctl map normal Super+Shift D spawn 'pactl set-sink-volume @DEFAULT_SINK@ -10%    '
140 riverctl map normal Super+Shift U spawn 'pactl set-sink-volume @DEFAULT_SINK@ +10%    '
141 riverctl map normal Super B spawn 'brightnessctl set 10%+'
142 riverctl map normal Super+Shift B spawn 'brightnessctl set 10%-'

When assigning keyboard shortcuts, you just use riverctl then tell it what to do. The syntax is:

  1. riverctl map tells riverctl you will be mapping a keyboard combination
  2. normal means the keyboard combination will be applied to the “normal mode” of river, aka actual navigation of windows
  3. Super D / Super+Shift D This is where the keyboard combo is listed. You can refer to the windows key as Super, and any pressed combo is as straightforward as Super+Shift+Alt D
  4. spawn to fire off a command
  5. 'wofi --show drun' the actual command you want to run when pressing the keyboard combo

rivertile / River Tiling Applications

One of the most unique aspects with River is how you tile the windows. On i3/sway, it’s manual (unless you predefine where certain apps should open, of course). On awesomewm, the tiling is dynamic with a couple preinstalled ways to tile your windows.

On river, the job of tiling isn’t even managed by the window manager - beyond initializing the actual tiler. In river, the tile pattern is determined by binary programs. This might seem strange at first, but let’s take a look at the following default example:

# Set the default layout generator to be rivertile and start it.
# River will send the process group of the init executable SIGTERM on exit.
riverctl default-layout rivertile
rivertile -view-padding 6 -outer-padding 6 &

What’s going on here is crucial to understanding riverwm.

  1. riverctl tells the default-layout (the layout you always load in) to be managed by rivertile
  2. Immediately after this line, you enter the rivertile command, with some flags for gaps between windows.

To simplify this:

  1. RiverWM says what the default grid program should be.
  2. Rivertile is actually what controls your dynamic tiling layout

The default layout of rivertile kind of sucks in my opinion. I know plenty of people use tiling patters like rivertile does by default, but I hated it. I just wanted a simple 4x4 grid.

To get a simple 4x4 grid, I used the previously mentioned river-bsp-layout. How this is used is detailed in the readme, and expands on the default example given above.

riverctl default-layout bsp-layout
river-bsp-layout --inner-gap 10 --outer-gap 10 &

Instead of running rivertile we replace it with the new river-bsp-layout. Which lays out all the terminals in a grid like my screenshot showed above.

What Are Your First Impressions With River?

This is the fastest wm I’ve ever used. Everything feels faster on here, especially the terminal. It has me wondering what the hell was going on with sway, could I have improved it somehow to be faster?

River is also very light on resources - both hard disk and ram wise.

I like the fact it’s configured with a shell script - or other languages. Every time you start the WM, it just runs the init script and sets up your environment. It’s like qtile but WAY easier to configure in that regard.

I’m finishing this article a day after I wrote all this, and for the first time in my life I felt like i3 on my work desktop was too annoying. It might be time I finally get off Xorg and take the river pill on that machine as well.