{ config , lib , pkgs , ... }: with lib; let cfg = config.my.programs.niri; inherit (config.home-manager.users.moritz.lib.niri) actions; in { options.my.programs.niri.enable = mkEnableOption "niri"; config = mkIf cfg.enable { 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 ]; # adds pam module for swaylock security.pam.services.swaylock = { }; programs.niri.enable = true; my = { programs = { wallpaper.enable = true; ghostty.enable = true; tofi.enable = true; }; wallpapers.enable = true; services = { dunst.enable = true; wallpaper = { enable = true; target = "niri.service"; }; spotify-player.target = "niri.service"; }; }; home-manager.users.moritz = { programs.waybar = { enable = true; # start using systemd service systemd = { enable = true; target = "niri.service"; }; settings = { mainBar = { start_hidden = true; layer = "top"; position = "top"; height = 20; modules-left = [ "niri/workspaces" ]; modules-center = [ "niri/window" ]; modules-right = [ "network" "memory" "cpu" "battery" "clock" ]; }; }; }; # 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 = "niri.service"; }; home.packages = with pkgs; [ wlr-randr jq ]; services.kanshi = { enable = true; systemdTarget = "niri.service"; }; programs.niri = { settings = { environment = { "NIXOS_OZONE_WL" = "1"; "QT_QPA_PLATFORM" = "wayland"; }; binds = { # spawn different programs "Mod+Return".action.spawn = config.my.terminal.package; "Mod+Shift+escape".action.spawn = [ "loginctl" "lock-session" ]; "Mod+R".action.spawn = "${lib.getExe pkgs.fuzzel}"; # keyboard layout "Mod+Space".action = actions.switch-layout "next"; "Mod+I".action = actions.show-hotkey-overlay; "Mod+Q".action = actions.close-window; "Mod+Shift+Q".action = actions.quit; "Mod+Shift+C".action = actions.screenshot; # resizing / swapping / switching "Mod+F".action = actions.fullscreen-window; "Mod+Shift+H".action.set-column-width = "-5%"; "Mod+Shift+L".action.set-column-width = "+5%"; "Mod+J".action = actions.focus-window-down-or-column-right; "Mod+K".action = actions.focus-window-up-or-column-left; "Mod+H".action = actions.move-column-left-or-to-monitor-left; "Mod+L".action = actions.move-column-right-or-to-monitor-right; "Mod+W".action.spawn = [ "pkill" "-USR1" "waybar" ]; "Mod+C".action = actions.consume-window-into-column; "Mod+E".action = actions.expel-window-from-column; "Mod+comma".action = actions.focus-monitor-up; "Mod+period".action = actions.focus-monitor-down; "Mod+Shift+comma".action = actions.move-workspace-to-monitor-up; "Mod+Shift+period".action = actions.move-workspace-to-monitor-down; "Mod+T".action = actions.switch-preset-column-width; "Mod+Shift+1".action.move-window-to-workspace = 1; "Mod+Shift+2".action.move-window-to-workspace = 2; "Mod+Shift+3".action.move-window-to-workspace = 3; "Mod+Shift+4".action.move-window-to-workspace = 4; "Mod+Shift+5".action.move-window-to-workspace = 5; "Mod+Shift+6".action.move-window-to-workspace = 6; "Mod+Shift+7".action.move-window-to-workspace = 7; "Mod+Shift+8".action.move-window-to-workspace = 8; "Mod+Shift+9".action.move-window-to-workspace = 9; "Mod+Shift+0".action.move-window-to-workspace = 10; "Mod+1".action.focus-workspace = 1; "Mod+2".action.focus-workspace = 2; "Mod+3".action.focus-workspace = 3; "Mod+4".action.focus-workspace = 4; "Mod+5".action.focus-workspace = 5; "Mod+6".action.focus-workspace = 6; "Mod+7".action.focus-workspace = 7; "Mod+8".action.focus-workspace = 8; "Mod+9".action.focus-workspace = 9; "Mod+0".action.focus-workspace = 10; # audio "XF86_AudioMute".action.spawn = [ "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle" ]; "XF86AudioRaiseVolume".action.spawn = [ "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%+" "-l" "1.0" ]; "XF86AudioLowerVolume".action.spawn = [ "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%-" ]; # TODO(mangoiv): mic mute toggle }; environment = { DISPLAY = ":0"; }; layout = { border.enable = false; focus-ring.enable = false; default-column-width.proportion = 2.0 / 3.0; preset-column-widths = [ { proportion = 1.0 / 3.0; } { proportion = 2.0 / 3.0; } { proportion = 1.0 / 1.0; } ]; gaps = 3; }; animations = { enable = true; slowdown = 0.5; }; prefer-no-csd = true; hotkey-overlay.skip-at-startup = true; window-rules = [ { matches = [ { title = "^.*1Password.*$"; } { title = "^.*Bitwarden.*$"; } { title = "^.*KeePassXC.*$"; } ]; block-out-from = "screen-capture"; } { clip-to-geometry = true; geometry-corner-radius = { bottom-left = 5.0; bottom-right = 5.0; top-left = 5.0; top-right = 5.0; }; } ]; switch-events = { lid-close.action.spawn = [ "loginctl" "lock-session" ]; }; input = { touchpad.natural-scroll = false; focus-follows-mouse.enable = true; warp-mouse-to-focus = true; keyboard = { xkb.layout = "us, de"; }; }; }; }; }; systemd.user.services.xwayland-satellite = { description = "Xwayland outside your Wayland"; after = [ "graphical-session.target" ]; wantedBy = [ "graphical-session.target" ]; partOf = [ "graphical-session.target" ]; bindsTo = [ "graphical-session.target" ]; requisite = [ "graphical-session.target" ]; serviceConfig = { Type = "notify"; Restart = "always"; RestartSec = "1s"; ExecStart = "${getExe pkgs.xwayland-satellite}"; StandardOutput = "journal"; NotifyAccess = "all"; }; }; services = { dbus.enable = true; # use pipewire (needed for screensharing) pipewire = { enable = true; alsa.enable = true; pulse.enable = true; }; displayManager = { autoLogin = { enable = true; user = "moritz"; }; defaultSession = "niri"; }; xserver = { enable = true; displayManager.lightdm.enable = true; }; }; security.rtkit.enable = true; }; }