From 3cfdb9f59203c0249b3fe704c0c220a99832cfa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20B=C3=B6hme?= Date: Tue, 10 Dec 2024 15:12:39 +0100 Subject: [PATCH] feat: add niri module --- flake.lock | 110 ++++++++++++++- flake.nix | 5 + modules/programs/niri.nix | 278 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 392 insertions(+), 1 deletion(-) create mode 100644 modules/programs/niri.nix diff --git a/flake.lock b/flake.lock index 4901c19..9c2186d 100644 --- a/flake.lock +++ b/flake.lock @@ -991,6 +991,64 @@ "type": "github" } }, + "niri": { + "inputs": { + "niri-stable": "niri-stable", + "niri-unstable": "niri-unstable", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_3", + "xwayland-satellite-stable": "xwayland-satellite-stable", + "xwayland-satellite-unstable": "xwayland-satellite-unstable" + }, + "locked": { + "lastModified": 1734526071, + "narHash": "sha256-0GjNrhkmJv961FqmkxPUWSj0Vdy2ZOzaw6dL1lBGhco=", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "328e55103afad95949f7fc60bb2ecabdd790611e", + "type": "github" + }, + "original": { + "owner": "sodiboo", + "repo": "niri-flake", + "type": "github" + } + }, + "niri-stable": { + "flake": false, + "locked": { + "lastModified": 1731483594, + "narHash": "sha256-Qjf7alRbPPERfiZsM9EMKX+HwjESky1tieh5PJIkLwE=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "75c79116a7e40cbc0e110ce0cdd500e896458679", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "ref": "v0.1.10.1", + "repo": "niri", + "type": "github" + } + }, + "niri-unstable": { + "flake": false, + "locked": { + "lastModified": 1734270275, + "narHash": "sha256-FfpxEVDPQ1qSDoLOqnSK2laM6oPklgZhd2YWzxOB8Ns=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "d35ad73e3572b0ac704b0c08928f53d0cfd1951f", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "repo": "niri", + "type": "github" + } + }, "nix-darwin": { "inputs": { "nixpkgs": [ @@ -1128,6 +1186,22 @@ } }, "nixpkgs-stable_3": { + "locked": { + "lastModified": 1734202038, + "narHash": "sha256-LwcGIkORU8zfQ/8jAgptgPY8Zf9lGKB0vtNdQyEkaN8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "bcba2fbf6963bf6bed3a749f9f4cf5bff4adb96d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_4": { "locked": { "lastModified": 1730741070, "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=", @@ -1423,7 +1497,7 @@ "flake-compat": "flake-compat_5", "gitignore": "gitignore_4", "nixpkgs": "nixpkgs_9", - "nixpkgs-stable": "nixpkgs-stable_3" + "nixpkgs-stable": "nixpkgs-stable_4" }, "locked": { "lastModified": 1734190932, @@ -1473,6 +1547,7 @@ "impermanence": "impermanence", "master": "master", "neovim-nightly-overlay": "neovim-nightly-overlay", + "niri": "niri", "nix-index-database": "nix-index-database", "nix-monitored": "nix-monitored", "nixos-facter-modules": "nixos-facter-modules", @@ -1769,6 +1844,39 @@ "type": "github" } }, + "xwayland-satellite-stable": { + "flake": false, + "locked": { + "lastModified": 1730166465, + "narHash": "sha256-nq7bouXQXaaPPo/E+Jbq+wNHnatD4dY8OxSrRqzvy6s=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "a713cf46cb7db84a0d1b57c3a397c610cad3cf98", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "ref": "v0.5", + "repo": "xwayland-satellite", + "type": "github" + } + }, + "xwayland-satellite-unstable": { + "flake": false, + "locked": { + "lastModified": 1734112800, + "narHash": "sha256-9qSb6AJpmzV3oYRfsyEt0e9eju6UeXDSD1poeSwadKo=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "c45c2ed990912c26e6aed0f47bfddb03993d7999", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "type": "github" + } + }, "zig": { "inputs": { "flake-compat": [ diff --git a/flake.nix b/flake.nix index 2b1d3bc..29cbbed 100644 --- a/flake.nix +++ b/flake.nix @@ -57,6 +57,10 @@ submodules = true; }; + # Niri + niri.url = "github:sodiboo/niri-flake"; + niri.inputs.nixpkgs.follows = "nixpkgs"; + # Laptop asus-touchpad-numpad-driver.url = "github:MoritzBoehme/asus-touchpad-numpad-driver/german-layout"; asus-touchpad-numpad-driver.flake = false; @@ -170,6 +174,7 @@ inputs.impermanence.nixosModules.impermanence inputs.nix-index-database.nixosModules.nix-index inputs.nixos-facter-modules.nixosModules.facter + inputs.niri.nixosModules.niri path ]; }) diff --git a/modules/programs/niri.nix b/modules/programs/niri.nix new file mode 100644 index 0000000..1c179c2 --- /dev/null +++ b/modules/programs/niri.nix @@ -0,0 +1,278 @@ +{ 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; + kitty.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; + }; +}