Skip to content
Abdullah Khabir edited this page Aug 16, 2022 · 1 revision

river session River is a dynamic wayland compositor.

Configuration

river is a new wayland compositor and not fully documented. I'll use home-manager and systemd to configure it.

Create custom target

Not only river, I need other apps/tools to use with it. Thanks to systemd which provides a graphical-session-target which is a user unit which is active whenever an X or wayland session starts.

I'm going to use home-manager to create one for me. First I'll source my river configuration file from ~/nix/dots/river/river-configuration to river config directory ~/.config/river/init. (I keep my home-manager directory at ~/nix.)

So I'm writing a new file river.nix.

{ config, pkgs, lib, ... }:

{
  # move river configuration file to its directory...
  home.file.".config/river/init".source =
    config.lib.file.mkOutOfStoreSymlink ./river/river-configuration;

}

Now init is symlinked to my ~/nix/dots/river/river-configuration. Lets create a river-target.

{ config, pkgs, lib, ... }:

{
  # move river configuration file to its directory...
  home.file.".config/river/init".source =
    config.lib.file.mkOutOfStoreSymlink ./river/river-configuration;

    systemd.user.targets.river-session = {
      Unit = {
        Description = "River Compositor Session";
        Documentation = [ "man:systemd.special(7)" ];
        BindsTo = [ "graphical-session.target" ];
        Wants = [ "graphical-session-pre.target" ];
        After = [ "graphical-session-pre.target" ];
      };
    };
}

Binding other tools to river-session.target

So now whenever river-session is started, all systemd stuff you bound to it, automatically starts, and also stops whenever you exit of this target. I'm going to bind waybar to it.

Waybar start

Here is my modified waybar.nix.

{ pkgs, ... }:

{
  programs.waybar = {
    enable = true;
    systemd.enable = true;
    systemd.target = "river-session.target";
    style =
    ''
...
...

Background/wallpaper

Lets create a wallpaper service for setting wallpaper for our river session.

{ config, pkgs, lib, ... }:

{
  # move river configuration file to its directory...
  home.file.".config/river/init".source =
    config.lib.file.mkOutOfStoreSymlink ./river/river-configuration;

  # lets create a target session for river
    systemd.user.targets.river-session = {
      Unit = {
        Description = "River Compositor Session";
        Documentation = [ "man:systemd.special(7)" ];
        BindsTo = [ "graphical-session.target" ];
        Wants = [ "graphical-session-pre.target" ];
        After = [ "graphical-session-pre.target" ];
      };
    };

  # lets create wallpaper service/timer
  systemd.user.timers.wallpaper = {
    Install = {
      WantedBy = [ "river-session.target" ];
    };
    Timer = {
      OnUnitActiveSec = [ "1s" ];
      OnCalendar = [ "*:0/1" ];
      Unit = [ "wallpaper.service" ];
    };
    Unit = {
      Description = "Wallpaper Service for River";
    };
  };

  systemd.user.services.wallpaper = {
    Service = {
      ExecStart = [ "%h/.local/bin/river-wallpaper" ];
      Type = [ "oneshot" ];
    };
    Unit = {
      Description = "Wallpaper Service for River";
    };
  };
}

This will change wallpaper as we log into our river-session. And then after every minute, it will change wallpaper. It's a bit hacky as systemd waits for the change wallpaper command to finish first to re-invoke it again. So my hack here is just kill the process swaybg after one minute. If you're using X, and using feh, you don't need to kill the process as feh just sets the wallpaper and exits with 0. Here is my river-wallpaper script.

#!/usr/bin/env dash

# A simple script to change wallpaper in river-session
systemctl --user import-environment WAYLAND_DISPLAY
walls_directory="$HOME/pix/wall/blurry"
random_wall=$(find $walls_directory -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' | shuf -n 1)

swaybg -m fill -i $random_wall
sleep 60
pkill swaybg

Locker/Idle-inhibitor

Next we will create a locker for our session. I'm using swayidle and swaylock. And light for turning the screen off. After 1 minute of inactivity, it will lock the screen, and then after more 15 seconds, it will turn the screen off.

{ config, pkgs, lib, ... }:

{
  # move river configuration file to its directory...
  home.file.".config/river/init".source =
    config.lib.file.mkOutOfStoreSymlink ./river/river-configuration;

  # lets create a target session for river
    systemd.user.targets.river-session = {
      Unit = {
        Description = "River Compositor Session";
        Documentation = [ "man:systemd.special(7)" ];
        BindsTo = [ "graphical-session.target" ];
        Wants = [ "graphical-session-pre.target" ];
        After = [ "graphical-session-pre.target" ];
      };
    };

  # lets create wallpaper service/timer
  systemd.user.timers.wallpaper = {
    Install = {
      WantedBy = [ "river-session.target" ];
    };
    Timer = {
      OnUnitActiveSec = [ "1s" ];
      OnCalendar = [ "*:0/1" ];
      Unit = [ "wallpaper.service" ];
    };
    Unit = {
      Description = "Wallpaper Service for River";
    };
  };

  systemd.user.services.wallpaper = {
    Service = {
      ExecStart = [ "%h/.local/bin/river-wallpaper" ];
      Type = [ "oneshot" ];
    };
    Unit = {
      Description = "Wallpaper Service for River";
    };
  };

  # lets create a locker for river-session
  systemd.user.services.locker = {
    Unit = {
      Description = [ "Automatic Locker for river-session" ];
    };
    Install = {
      WantedBy = [ "river-session.target" ];
    };
    Service = {
      ExecStart = [ "${pkgs.swayidle}/bin/swayidle -w timeout 60 '${pkgs.swaylock}/bin/swaylock -f -i ~/nix/dots/river/locker.jpeg' before-sleep '${pkgs.swaylock}/bin/swaylock -f -i ~/nix/dots/river/locker.jpeg' timeout 75 '${pkgs.light}/bin/light -O; ${pkgs.light}/bin/light -S 0' resume '${pkgs.light}/bin/light -I' lock '${pkgs.swaylock}/bin/swaylock -f -i ~/nix/dots/river/locker.jpeg'" ];
    };
  };
}

Applying changes

Just enable the settings we have created now.

systemctl --user start river-session.target
systemctl --user enable --now wallpaper.timer
systemctl --user enable --now locker.service

Enough for now...