dotfiles/modules/programs/river/default.nix

286 lines
7.9 KiB
Nix

{ config
, lib
, pkgs
, ...
}:
let
inherit (lib) mkEnableOption mkIf mkOption types;
cfg = config.my.programs.river;
in
{
options.my.programs.river = {
enable = mkEnableOption "river";
keyboardLayouts = mkOption {
type = types.listOf types.str;
description = "list of keyboard layouts";
default = [ "us" "de" ];
};
nvidiaSupport = mkEnableOption "nvidiaSupport";
};
config = mkIf cfg.enable {
programs.river.enable = true;
my = {
programs = {
wallpaper.enable = true;
kitty.enable = true;
tofi.enable = true;
};
wallpapers.enable = true;
services = {
dunst.enable = true;
wallpaper = {
enable = true;
target = "river-session.target";
};
spotify-player.target = "river-session.target";
};
};
home-manager.users.moritz = {
home.packages = with pkgs; [
rivercarro
];
services.kanshi = {
enable = true;
systemdTarget = "river-session.target";
};
wayland.windowManager.river = {
enable = true;
settings = {
border-width = 2;
declare-mode = [
"locked"
"normal"
"passthrough"
];
map = {
normal = {
"Super Q" = "close";
"Super Return" = "spawn kitty";
"Super R" = ''spawn 'exec $(tofi-run --fuzzy-match=true)' '';
"Super W" = ''spawn "pkill -USR1 waybar"'';
"Super+Shift R" = "spawn ~/.config/river/init";
# Focus view
"Super J" = "focus-view next";
"Super K" = "focus-view previous";
# swap the focused view
"Super+Shift J" = "swap next";
"Super+Shift K" = "swap previous";
# focus output
"Super Period" = "focus-output next";
"Super Comma" = "focus-output previous";
# send to output
"Super+Shift Period" = "send-to-output next";
"Super+Shift Comma" = "send-to-output previous";
# bump in layout stack
"Super Z" = "zoom";
# lock screen
"Super+Alt L" = ''spawn "loginctl lock-session"'';
} //
# tags
(
let
numbers = lib.range 1 9;
toTag = num: "$((1 << (${toString num} - 1)))";
mkMappings = num:
let
numStr = toString num;
tag = toTag num;
in
[
# Super+Control+[1-9] to toggle focus of tag [0-8]
{ name = "Super ${numStr}"; value = "set-focused-tags ${tag}"; }
# Super+Shift+Control+[1-9] to toggle tag [0-8] of focused view
{ name = "Super+Shift ${numStr}"; value = "toggle-view-tags ${tag}"; }
];
mappings = lib.flatten (map mkMappings numbers);
in
lib.listToAttrs mappings
);
};
map-pointer = {
normal = {
"Super BTN_LEFT" = "move-view";
"Super BTN_RIGHT" = "resize-view";
"Super BTN_MIDDLE" = "toggle-float";
};
};
attach-mode = "bottom";
default-layout = "rivercarro";
focus-follows-cursor = "normal";
hide-cursor = {
timeout = "1500";
when-typing = "enabled";
};
set-cursor-warp = "on-focus-change";
keyboard-layout = "-options grp:win_space_toggle,caps:escape ${lib.concatStringsSep "," cfg.keyboardLayouts}";
};
extraConfig = /* bash */ ''
rivercarro_pid="$(pidof rivercarro)"
if [[ -z $rivercarro_pid ]]; then
rivercarro -inner-gaps 4 -outer-gaps 4 &
fi
'';
};
# add waybar as a status bar
programs.waybar = {
enable = true;
# start using systemd service
systemd = {
enable = true;
target = "river-session.target";
};
settings = {
mainBar = {
start_hidden = true;
layer = "top";
position = "top";
height = 20;
modules-left = [ "river/tags" ];
modules-center = [ "river/window" ];
modules-right = [ "network" "memory" "cpu" "battery" "clock" ];
};
};
style = lib.readFile ./style.css;
};
# lock screen after timeout
programs.swaylock = {
enable = true;
settings = {
color = "000000";
};
};
services.swayidle = {
enable = true;
events = [
{
event = "before-sleep";
command = "${lib.getExe pkgs.swaylock} -fF";
}
{
event = "lock";
command = "${lib.getExe pkgs.swaylock} -fF";
}
];
timeouts =
let
lockTimeout = 10;
in
[
{
timeout = lockTimeout * 60 - 10;
command = "${pkgs.libnotify}/bin/notify-send 'Locking screen!'";
}
{
timeout = lockTimeout * 60 + 10;
command = "${pkgs.systemd}/bin/loginctl lock-session";
}
];
systemdTarget = "river-session.target";
};
};
# adds pam module for swaylock
security.pam.services.swaylock = { };
# add user packages for wayland and hyprland in particular
users.users.moritz.packages = with pkgs; [
brightnessctl # control brightness
grimblast # screenshot tool for hyprland
pamixer # pulse audio cli
playerctl # control media playback
slurp # region select for wayland (for screensharing)
wdisplays # manage monitors
wl-clipboard # clipboard tool for wayland
];
# additional environment variables
environment.sessionVariables =
{
XDG_CURRENT_DESKTOP = "river";
XDG_SESSION_TYPE = "wayland";
XDG_SESSION_DESKTOP = "river";
QT_AUTO_SCREEN_SCALE_FACTOR = "1";
QT_QPA_PLATFORM = "wayland;xcb";
QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
QT_QPA_PLATFORMTHEME = "qt5ct";
_JAVA_AWT_WM_NONEREPARENTING = "1";
} // (lib.optionalAttrs cfg.nvidiaSupport
{
GBM_BACKEND = "nvidia-drm";
GDK_BACKEND = "wayland";
LIBVA_DRIVER_NAME = "nvidia";
MOZ_ENABLE_WAYLAND = "1";
WLR_DRM_DEVICES = "/dev/dri/card0";
WLR_DRM_NO_ATOMIC = "1";
WLR_NO_HARDWARE_CURSORS = "1";
XDG_CURRENT_DESKTOP = "river";
_GL_GSYNC_ALLOWED = "0";
__GLX_VENDOR_LIBRARY_NAME = "nvidia";
__GL_VRR_ALLOWED = "0";
});
services = {
dbus.enable = true;
# use pipewire (needed for screensharing)
pipewire = {
enable = true;
alsa.enable = true;
alsa.support32Bit = true;
pulse.enable = true;
};
displayManager = {
autoLogin = {
enable = true;
user = "moritz";
};
defaultSession = "river";
};
xserver = {
enable = true;
displayManager.lightdm.enable = true;
};
};
security.rtkit.enable = true;
home-manager.users.moritz.systemd.user.services =
let
units = [ "waybar" ];
mkAfter = _: {
Unit = {
After = [ "river-session.target" ];
Wants = [ "river-session.target" ];
};
};
in
lib.genAttrs units mkAfter;
systemd.user.services =
let
units = [ "pipewire" "xdg-desktop-portal" "wireplumber" ];
mkAfter = _: {
after = [ "river-session.target" ];
wants = [ "river-session.target" ];
};
in
lib.genAttrs units mkAfter;
};
}