{ 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 wlr-randr jq ]; services.kanshi = { enable = true; systemdTarget = "river-session.target"; }; wayland.windowManager.river = { enable = true; settings = { border-width = 2; declare-mode = [ "locked" "normal" "passthrough" ]; map-switch.normal.lid = { close = '' spawn 'monitors=$(wlr-randr --json | jq .[].name | count); [ "$monitors" = 1] && loginctl lock-session' ''; open = "spawn 'wlr-randr --output eDP-1 --on'"; }; map = { passthrough = { "Super F11" = "enter-mode normal"; }; normal = { "Super Q" = "close"; "Super Return" = "spawn '${config.my.terminal.package}'"; "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"''; "Control I" = ''spawn "loginctl lock-session"''; # XF86 keys "None XF86AudioLowerVolume" = "spawn 'pamixer -d 5'"; "None XF86AudioRaiseVolume" = "spawn 'pamixer -i 5'"; "None XF86AudioMute" = "spawn 'pamixer -t'"; "None XF86AudioNext" = "spawn 'playerctl -p spotifyd,firefox next'"; "None XF86AudioPlay" = "spawn 'playerctl -p spotifyd,firefox play-pause'"; "None XF86AudioPrev" = "spawn 'playerctl -p spotifyd,firefox previous'"; "Super F11" = "enter-mode passthrough"; } // # 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 = { }; users.users.moritz.packages = with pkgs; [ brightnessctl # control brightness grimblast # screenshot tool 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; }; }