nilFM

ryudo as a daily driver

Off and on, I've been using ryudo as a daily driver for the better part of the past year. Now that it's reached version 1.1 1.2, I think it may be about time for a rundown of the setup and workflow.

Ryudo desktop with 2 terminals, one showing uname output and disk usage, the other editing some uxntal code in micro; xosview and xclock are in the corners

philosophy

Since my first flirtations with plan9 and rio, I loved it. The perfect balance between minimalism and functionality was intoxicating. I used rio from plan9port as my main window manager for a long time, and once my programming chops got up to snuff, I forked it and ryudo was born.

My goals with ryudo were to provide plan9port rio with keybindings, but I ended up with a more stable and better-behaved window manager as a result. Since starting with ryudo, I've also used KDE Plasma, and while I love the customizability and outward polish of that environment, it has a number of things that leave a foul taste in my mouth: the clutter it hides in your ~/.config directory, the number of processes it spawns, the reliance on a systemd-compatible seat-management service, the use of Javascript as an extension language, and a few things having to do with tactless release cycles. Ultimatley, I prefer a simpler and more elegant computing environment where I can actually track what every process in pstree is doing.

An alacritty window showing clean pstree output of an almost-empty ryudo session

I switched back and forth between Plasma and ryudo alternatively, a few months on each, for a while. Workflow-wise, Plasma with Bismuth offers most everything I need. But philosophically I'm at odds with it, for all the reasons given above. I recently switched back to ryudo, and I think this time I'm going to leave Plasma behind me for good (on both of my machines! I have migrated to Fluxbox on yggdrasil, which is comparable in UX to Plasma but without the cruft).

flow

I keep it simple, logging into tty1 and launching startx. ryudo 1.1 features an xsession .desktop file and a session wrapper script modelled after Fluxbox and Openbox. Session processes can be put in ~/.ryudorc and ryudo options can be put in ~/.ryudo.conf; so my .xinitrc is just exec startryudo.

startryudo in turn calls ryudo with the arguments you supply in ~/.ryudo.conf as well as running whatever you put in ~/.ryudorc. My .ryudo.conf looks like this:

-virtuals 6 -term alacritty

I use Alacritty, Nitrogen, and xbindkeys to provide the rest of the main desktop environment; Other programs that I use to complete my session include dmenu, dunst, xosview, and xclock; my .ryudorc looks like this:

#!/bin/sh

# misc low level stuff

xset -b
sudo powertop --auto-tune &
redshift -x; redshift -O 6000K &
xbacklight -set 50 &

# mbsync wrapper

if ! pgrep sirius.sh; then
  ~/src/zenUtils/sirius.sh &
fi

# pipewire is great. no more pulseaudio taking 100% cpu on relogin

if ! pgrep pipewire; then
  pipewire & sleep 0.3
  pipewire-pulse &
fi

# serve local copy of my website for testing

darkhttpd /home/nilix/src/nilfm/www/ --port 9001 --daemon

# handle monitor biz

case $(~/src/zenUtils/extdisplay.sh status) in
  "connected")
    ~/src/zenUtils/extdisplay.sh solo;;
  *)
    :;;
esac

# real session stuff

plumber &
nitrogen --restore &
xcompmgr & # sleep 0.3
~/src/zenUtils/batAlarm.sh &
xosview -geometry +0+0 &
xclock -strftime "%Y-%m-%d %H:%M" -geometry -0-0 &
export GTK_THEME=steppenwolf-dark
export WINIT_X11_SCALE_FACTOR=1
xbindkeys -f ~/.xbindkeysrc

The transsetter.sh script included in the ryudo source tree is used to provide selective transparency with the help of a compositor. As of version 1.2, ryudo has support for setting window transparency by class in the config.h file -- it just needs a compositor running for the transparency to take effect. I use xcompmgr as the compositor because, despite being unmaintained and lacking a bunch of features, it's the lightest on resources of all the standalone X compositors and does what I need it to do.

My .xbindkeysrc looks like this:

"sudo /home/nilix/src/zenUtils/logout.sh -p"
  Control + Alt + BackSpace

"/home/nilix/bin/9/dmenu_exe"
  Alt + space

"slock"
  Mod4 + Escape

"/home/nilix/bin/zenbar/nmtuiWin.sh"
  Mod4 + F1

"notify-send -c power battery [$(cat /sys/class/power_supply/BAT0/capacity)%]"
  Mod4 + F2

"datetime=$(date +%H:%M); notify-send -c time time [$datetime]"
  Mod4 + F3

"amixer set Master 5%+; notify-send -u low -c volume volume $(amixer get Master | grep % | head -n 1 | awk '{print $5}')"
  XF86AudioRaiseVolume

"amixer set Master 5%-; notify-send -u low -c volume volume $(amixer get Master | grep % | head -n 1 | awk '{print $5}')"
  XF86AudioLowerVolume

"xbacklight -inc 5; notify-send -u low -c brightness brightness [$(xbacklight -get)%]"
  XF86MonBrightnessUp

"xbacklight -dec 5; notify-send -u low -c brightness brightness [$(xbacklight -get)%]"
  XF86MonBrightnessDown

"amixer set Master toggle"
  XF86AudioMute

"amixer set Capture toggle"
  XF86AudioMicMute

"redshift -x; redshift -O 4500K; notify-send -u low -c brightness color [4500K]"
  Mod4 + XF86MonBrightnessDown

"redshift -x; redshift -O 6000K; notify-send -u low -c brightness color [6000K]"
  Mod4 + XF86MonBrightnessUp

I also use this little shell function to manage switching between ksatrya's builtin display and my external monitor; it wraps one of my zenUtils scripts, extDisplay.sh, which itself wraps xrandr, and in addition to switching the displays it also resets my wallpaper and repositions xclock:

mode(){
  hasPanel=0
  if [ ! -z "$1" ]; then
    if pgrep tint2; then
      hasPanel=1
      killall tint2
    fi
    case $1 in
      desktop)
        ~/src/zenUtils/extdisplay.sh solo
         ;;
      laptop)
        ~/src/zenUtils/extdisplay.sh off
        xrandr --dpi 96
        ;;
      dualleft)
        ~/src/zenUtils/extdisplay.sh left-of
        ;;
      dualright)
        ~/src/zenUtils/extdisplay.sh right-of
    esac
    nitrogen --restore
    if pgrep ryudo; then
      killall xclock; xclock -strftime "%Y-%m-%d %H:%M" -geometry -0-0 &
    fi
    if [ ${hasPanel} -eq 1 ]; then
      tint2 &
    fi
  fi
}

thoughts

Between the psuedo-tiling, mouse control, the possibility for autostick windows, and the improved positioning and focus behavior over plan9port rio, a ryudo session provides a spartan but complete and comfortable experience. It does this in a way that keeps the process tree and filesystem free of clutter and the user's mind on the task at hand.

My ryudo session, and perhaps the fact that I use ryudo at all, is an expression of my unique relationship with technology. I don't expect anyone else in the world to use it, but I provide the opportunity in case any like minded folks want to give it a shot.

As I mention in the ryudo project page, there are a few bugs to work out, and I hope to hunt them down. Mostly it's just the obvious improvements that could be made to the focus model (currently, the click used to focus a window is not passed through), and the strange bug that happens if you rapidly switch back and forth between two virtual desktops with visible windows (if you loop/scroll in one direction it doesn't trigger the bug).

It's good to be home.