diff --git a/flake.lock b/flake.lock index d5d64b5..cf9938e 100644 --- a/flake.lock +++ b/flake.lock @@ -471,6 +471,64 @@ "type": "github" } }, + "niri": { + "inputs": { + "niri-stable": "niri-stable", + "niri-unstable": "niri-unstable", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable", + "xwayland-satellite-stable": "xwayland-satellite-stable", + "xwayland-satellite-unstable": "xwayland-satellite-unstable" + }, + "locked": { + "lastModified": 1745668007, + "narHash": "sha256-xYf6xz8WOW9ztBi356dHdqLsTCoxVS8Iapfpwosrn7Q=", + "owner": "sodiboo", + "repo": "niri-flake", + "rev": "8fdaf610c455d0b5b70374a21392a717be513b0f", + "type": "github" + }, + "original": { + "owner": "sodiboo", + "repo": "niri-flake", + "type": "github" + } + }, + "niri-stable": { + "flake": false, + "locked": { + "lastModified": 1740117926, + "narHash": "sha256-mTTHA0RAaQcdYe+9A3Jx77cmmyLFHmRoZdd8RpWa+m8=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "b94a5db8790339cf9134873d8b490be69e02ac71", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "ref": "v25.02", + "repo": "niri", + "type": "github" + } + }, + "niri-unstable": { + "flake": false, + "locked": { + "lastModified": 1745663376, + "narHash": "sha256-mGQyB+Epl87ZCZZCcBkjUrdR1aJt8Ybiqr4h0yUkgQI=", + "owner": "YaLTeR", + "repo": "niri", + "rev": "78e3daf5f82b5870e998faf0e1efeaa048730976", + "type": "github" + }, + "original": { + "owner": "YaLTeR", + "repo": "niri", + "type": "github" + } + }, "nix-index-database": { "inputs": { "nixpkgs": [ @@ -604,6 +662,22 @@ "type": "github" } }, + "nixpkgs-stable": { + "locked": { + "lastModified": 1745487689, + "narHash": "sha256-FQoi3R0NjQeBAsEOo49b5tbDPcJSMWc3QhhaIi9eddw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5630cf13cceac06cefe9fc607e8dfa8fb342dde3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-unstable": { "locked": { "lastModified": 1745391562, @@ -747,6 +821,7 @@ "fireproof-shell": "fireproof-shell", "flake-parts": "flake-parts_3", "home-manager": "home-manager_2", + "niri": "niri", "nix-index-database": "nix-index-database", "nix-vscode-extensions": "nix-vscode-extensions", "nixos-facter-modules": "nixos-facter-modules", @@ -932,6 +1007,39 @@ "repo": "treefmt-nix", "type": "github" } + }, + "xwayland-satellite-stable": { + "flake": false, + "locked": { + "lastModified": 1739246919, + "narHash": "sha256-/hBM43/Gd0/tW+egrhlWgOIISeJxEs2uAOIYVpfDKeU=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "44590a416d4a3e8220e19e29e0b6efe64a80315d", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "ref": "v0.5.1", + "repo": "xwayland-satellite", + "type": "github" + } + }, + "xwayland-satellite-unstable": { + "flake": false, + "locked": { + "lastModified": 1745372360, + "narHash": "sha256-5DX9lYmEbkdANCzME2v3coV0EnWOhS7NsTlGBQuqmjM=", + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "rev": "c31679aa41966ee9272bb240703755cb1e7c72e3", + "type": "github" + }, + "original": { + "owner": "Supreeeme", + "repo": "xwayland-satellite", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index ed144c7..14e3750 100644 --- a/flake.nix +++ b/flake.nix @@ -75,5 +75,8 @@ claude-desktop.url = "github:k3d3/claude-desktop-linux-flake"; claude-desktop.inputs.nixpkgs.follows = "nixpkgs"; + + niri.url = "github:sodiboo/niri-flake"; + niri.inputs.nixpkgs.follows = "nixpkgs"; }; } diff --git a/hosts/default.nix b/hosts/default.nix index 14d6070..71ab1a8 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -45,6 +45,7 @@ with lib; let inputs.nixos-facter-modules.nixosModules.facter inputs.fireproof-shell.nixosModules.default inputs.nvf.nixosModules.default + inputs.niri.nixosModules.niri ../modules/base/user.nix (mkSystemImports hostname) ] diff --git a/hosts/desktop/niri.nix b/hosts/desktop/niri.nix new file mode 100644 index 0000000..123ea24 --- /dev/null +++ b/hosts/desktop/niri.nix @@ -0,0 +1,35 @@ +_: { + fireproof.home-manager.programs.niri.settings.outputs = { + "DP-3" = { + position = { + x = 0; + y = 1080; + }; + mode = { + refresh = 164.998; + width = 2560; + height = 1440; + }; + }; + "DP-1" = { + position = { + x = 2560; + y = 1080; + }; + mode = { + refresh = 165.000; + width = 2560; + height = 1440; + }; + }; + "DP-2" = { + position = { + x = (2560 - 1920) / 2; + y = 0; + }; + }; + "HDMI-A-1" = { + enable = false; + }; + }; +} diff --git a/hosts/homelab/sso.nix b/hosts/homelab/sso.nix index b34aa91..621a8fb 100644 --- a/hosts/homelab/sso.nix +++ b/hosts/homelab/sso.nix @@ -1,4 +1,8 @@ -{config, pkgsUnstable, ...}: let +{ + config, + pkgsUnstable, + ... +}: let port = 9190; rootDomain = "nickolaj.com"; zitadelDomain = "sso.${rootDomain}"; diff --git a/modules/desktop/fuzzel.nix b/modules/desktop/fuzzel.nix new file mode 100644 index 0000000..0c61f80 --- /dev/null +++ b/modules/desktop/fuzzel.nix @@ -0,0 +1,5 @@ +{pkgs, ...}: { + environment.systemPackages = [ + pkgs.fuzzel + ]; +} diff --git a/modules/desktop/mako.nix b/modules/desktop/mako.nix new file mode 100644 index 0000000..5267781 --- /dev/null +++ b/modules/desktop/mako.nix @@ -0,0 +1,17 @@ +{pkgs, ...}: { + fireproof.home-manager.services.mako.enable = true; + systemd.user.services."mako" = { + description = "Mako notification daemon"; + documentation = ["man:mako(1)"]; + partOf = ["graphical-session.target"]; + after = ["graphical-session.target"]; + serviceConfig = { + Type = "dbus"; + BusName = "org.freedesktop.Notifications"; + ExecCondition = "/bin/sh -c '[ -n \"$WAYLAND_DISPLAY\" ]'"; + ExecReload = "${pkgs.mako}/bin/mako reload"; + ExecStart = "${pkgs.mako}/bin/mako"; + }; + wantedBy = ["graphical-session.target"]; + }; +} diff --git a/modules/desktop/niri.nix b/modules/desktop/niri.nix new file mode 100644 index 0000000..37efbc2 --- /dev/null +++ b/modules/desktop/niri.nix @@ -0,0 +1,258 @@ +{pkgsUnstable, ...}: { + # TODO: Move these to a separate module + fireproof.home-manager.programs.waybar = { + enable = true; + systemd.enable = true; + systemd.target = "niri.target"; + settings = { + bar = { + layer = "top"; + position = "top"; + modules-left = ["clock" "niri/workspaces"]; + modules-center = ["niri/window"]; + modules-right = ["backlight" "battery" "pulseaudio" "tray"]; + + pulseaudio = { + format = "{volume}% {icon}"; + format-muted = "󰝟 "; + format-icons = { + default = ["󰕿 " "󰖀 " "󰕾 "]; + headphone = "󰋋 "; + }; + on-click = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"; + }; + }; + }; + style = '' + * { + font-family: Hack Nerd Font Mono; + font-size: 14px; + } + window#waybar, #clock, #pulseaudio, #battery, #backlight, #tray { + background: #1C1B1A; + color: #DAD8CE; + border-bottom: 2px solid #CF6A4C; + } + + #workspaces button.focused { + background: #CF6A4C; + color: #1C1B1A; + box-shadow: 0 0 0 #CF6A4C; + } + + /* Default */ + button { + /* Use box-shadow instead of border so the text isn't offset */ + box-shadow: inset 0 -3px transparent; + /* Avoid rounded borders under each button name */ + border: none; + border-radius: 0; + } + + /* https://github.com/Alexays/Waybar/wiki/FAQ#the-workspace-buttons-have-a-strange-hover-effect */ + button:hover { + background: inherit; + box-shadow: inset 0 -3px #ffffff; + } + + /* you can set a style on hover for any module like this */ + #pulseaudio:hover { + background-color: #a37800; + } + + #workspaces button { + padding: 0 5px; + background-color: transparent; + color: #ffffff; + } + + #workspaces button:hover { + background: rgba(0, 0, 0, 0.2); + } + + #workspaces button.urgent { + background-color: #eb4d4b; + } + + #window, + #workspaces { + margin: 0 4px; + } + + + #tray > .passive { + -gtk-icon-effect: dim; + } + + #tray > .needs-attention { + -gtk-icon-effect: highlight; + background-color: #eb4d4b; + } + #tray > .active { + -gtk-icon-effect: highlight; + background-color: #eb4d4b; + }''; + }; + + programs.niri = { + enable = true; + package = pkgsUnstable.niri; + }; + fireproof.home-manager.programs.niri.settings = { + prefer-no-csd = true; + spawn-at-startup = [ + {command = ["systemctl" "--user" "start" "hypridle"];} + {command = ["systemctl" "--user" "start" "hyprpaper"];} + {command = ["systemctl" "--user" "start" "mako"];} + {command = ["systemctl" "--user" "start" "waybar"];} + ]; + layout = { + gaps = 10; + focus-ring.enable = false; + insert-hint.display.color = "#CF6A4C"; + border = { + enable = true; + width = 2; + active.color = "#CF6A4C"; + inactive.color = "#343331"; + }; + tab-indicator = { + hide-when-single-tab = true; + place-within-column = true; + gap = 2; + position = "top"; + corner-radius = 8; + }; + }; + input = { + focus-follows-mouse.enable = true; + mouse.accel-profile = "flat"; + }; + window-rules = [ + { + clip-to-geometry = true; + geometry-corner-radius = { + top-left = 8.0; + top-right = 8.0; + bottom-left = 8.0; + bottom-right = 8.0; + }; + } + ]; + binds = { + "XF86AudioRaiseVolume" = { + allow-when-locked = true; + action.spawn = [ + "wpctl" + "set-volume" + "@DEFAULT_AUDIO_SINK@" + "0.1+" + ]; + }; + "XF86AudioLowerVolume" = { + allow-when-locked = true; + action.spawn = [ + "wpctl" + "set-volume" + "@DEFAULT_AUDIO_SINK@" + "0.1-" + ]; + }; + "XF86AudioMute" = { + allow-when-locked = true; + action.spawn = [ + "wpctl" + "set-mute" + "@DEFAULT_AUDIO_SINK@" + "toggle" + ]; + }; + "XF86AudioMicMute" = { + allow-when-locked = true; + action.spawn = [ + "wpctl" + "set-mute" + "@DEFAULT_AUDIO_SOURCE@" + "toggle" + ]; + }; + + "Mod+Left".action.focus-column-or-monitor-left = {}; + "Mod+Down".action.focus-window-or-monitor-down = {}; + "Mod+Up".action.focus-window-or-monitor-up = {}; + "Mod+Right".action.focus-column-or-monitor-right = {}; + "Mod+H".action.focus-column-or-monitor-left = {}; + "Mod+J".action.focus-window-or-monitor-down = {}; + "Mod+K".action.focus-window-or-monitor-up = {}; + "Mod+L".action.focus-column-or-monitor-right = {}; + + "Mod+Shift+Left".action.move-column-left-or-to-monitor-left = {}; + "Mod+Shift+Down".action.move-window-down = {}; + "Mod+Shift+Up".action.move-window-up = {}; + "Mod+Shift+Right".action.move-column-right-or-to-monitor-right = {}; + "Mod+Shift+H".action.move-column-left-or-to-monitor-left = {}; + "Mod+Shift+J".action.move-window-down = {}; + "Mod+Shift+K".action.move-window-up = {}; + "Mod+Shift+L".action.move-column-right-or-to-monitor-right = {}; + + "Mod+Home".action.focus-column-first = {}; + "Mod+End".action.focus-column-last = {}; + "Mod+Shift+Home".action.move-column-to-first = {}; + "Mod+Shift+End".action.move-column-to-last = {}; + + "Mod+Ctrl+Left".action.focus-monitor-left = {}; + "Mod+Ctrl+Down".action.focus-monitor-down = {}; + "Mod+Ctrl+Up".action.focus-monitor-up = {}; + "Mod+Ctrl+Right".action.focus-monitor-right = {}; + "Mod+Ctrl+H".action.focus-monitor-left = {}; + "Mod+Ctrl+J".action.focus-monitor-down = {}; + "Mod+Ctrl+K".action.focus-monitor-up = {}; + "Mod+Ctrl+L".action.focus-monitor-right = {}; + + "Mod+F".action.maximize-column = {}; + "Mod+Shift+F".action.fullscreen-window = {}; + "Mod+A".action.toggle-column-tabbed-display = {}; + "Mod+C".action.center-column = {}; + "Mod+S".action.toggle-window-floating = {}; + + "Mod+Z".action.set-column-width = "-5%"; + "Mod+X".action.set-column-width = "+5%"; + "Mod+Shift+Z".action.set-window-height = "-5%"; + "Mod+Shift+X".action.set-window-height = "+5%"; + + "Mod+Shift+WheelScrollDown".action.focus-workspace-down = {}; + "Mod+Shift+WheelScrollUp".action.focus-workspace-up = {}; + "Mod+WheelScrollDown".action.focus-column-right = {}; + "Mod+WheelScrollUp".action.focus-column-left = {}; + + "Mod+WheelScrollRight".action.focus-column-right = {}; + "Mod+WheelScrollLeft".action.focus-column-left = {}; + "Mod+Shift+WheelScrollRight".action.move-column-right = {}; + "Mod+Shift+WheelScrollLeft".action.move-column-left = {}; + + "Mod+q".action.focus-workspace = 1; + "Mod+w".action.focus-workspace = 2; + "Mod+e".action.focus-workspace = 3; + "Mod+r".action.focus-workspace = 4; + "Mod+t".action.focus-workspace = 5; + "Mod+Shift+q".action.move-column-to-workspace = 1; + "Mod+Shift+w".action.move-column-to-workspace = 2; + "Mod+Shift+e".action.move-column-to-workspace = 3; + "Mod+Shift+r".action.move-column-to-workspace = 4; + "Mod+Shift+t".action.move-column-to-workspace = 5; + + "Mod+Comma".action.consume-or-expel-window-left = {}; + "Mod+Period".action.consume-or-expel-window-right = {}; + + "Print".action.screenshot = {}; + "Ctrl+Print".action.screenshot-screen = {}; + "Alt+Print".action.screenshot-window = {}; + + "Mod+Slash".action.show-hotkey-overlay = {}; + + "Mod+Return".action.spawn = ["ghostty"]; + "Mod+Space".action.spawn = ["fuzzel"]; + "Mod+Backspace".action.close-window = {}; + }; + }; +} diff --git a/modules/graphical.nix b/modules/graphical.nix index a7ae127..958c796 100644 --- a/modules/graphical.nix +++ b/modules/graphical.nix @@ -5,6 +5,9 @@ ./desktop/fonts.nix ./desktop/fireproof-shell.nix ./desktop/greetd.nix + ./desktop/niri.nix + ./desktop/fuzzel.nix + ./desktop/mako.nix ./desktop/hyprland/default.nix ./desktop/gtk/default.nix ./desktop/qt.nix