From 3f736a9ac3f59004c74a6a2b77749edcb8572cd7 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Apr 2026 14:57:14 +0000 Subject: [PATCH] niri: add full desktop stack (bar, launcher, notifications, configs) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves programs.niri into a dedicated niri.nix module and installs the usual Wayland userland — alacritty, fuzzel, waybar, mako, swaybg, grim/slurp/wl-clipboard, swaylock/swayidle/wlogout, xwayland-satellite, plus nm-applet/pavucontrol/playerctl/brightnessctl. Ships starter configs for niri (keybinds mirroring sway/KDE habits, screenshots to ~/Pictures/Screenshots, media keys, workspace switching, auto-lock via swayidle), waybar with a Catppuccin-ish style, mako, and fuzzel — all wired up through home-manager's xdg.configFile. https://claude.ai/code/session_01NrGdGEBRbDbWvHUb3Lho44 --- configuration.nix | 1 + desktop.nix | 2 - home.nix | 26 +++++ niri.nix | 43 +++++++++ niri/config.kdl | 201 +++++++++++++++++++++++++++++++++++++++ niri/fuzzel/fuzzel.ini | 23 +++++ niri/mako/config | 20 ++++ niri/waybar/config.jsonc | 77 +++++++++++++++ niri/waybar/style.css | 62 ++++++++++++ 9 files changed, 453 insertions(+), 2 deletions(-) create mode 100644 niri.nix create mode 100644 niri/config.kdl create mode 100644 niri/fuzzel/fuzzel.ini create mode 100644 niri/mako/config create mode 100644 niri/waybar/config.jsonc create mode 100644 niri/waybar/style.css diff --git a/configuration.nix b/configuration.nix index a8bc09e..6cb4a03 100644 --- a/configuration.nix +++ b/configuration.nix @@ -5,6 +5,7 @@ ./hardware-configuration.nix ./packages.nix ./desktop.nix + ./niri.nix ./nvidia.nix ./shell.nix ./yami-dev-stack.nix diff --git a/desktop.nix b/desktop.nix index 7181c16..4449b32 100644 --- a/desktop.nix +++ b/desktop.nix @@ -26,8 +26,6 @@ }; }; - programs.niri.enable = true; - security.rtkit.enable = true; qt = { diff --git a/home.nix b/home.nix index 182493b..1bb1d1d 100644 --- a/home.nix +++ b/home.nix @@ -17,5 +17,31 @@ enableFishIntegration = true; }; + programs.alacritty = { + enable = true; + settings = { + window = { + padding = { x = 10; y = 10; }; + opacity = 0.95; + decorations = "None"; + }; + font = { + normal = { family = "JetBrainsMono Nerd Font"; style = "Regular"; }; + size = 11; + }; + colors = { + primary = { background = "#1e1e2e"; foreground = "#cdd6f4"; }; + }; + }; + }; + + xdg.configFile = { + "niri/config.kdl".source = ./niri/config.kdl; + "waybar/config.jsonc".source = ./niri/waybar/config.jsonc; + "waybar/style.css".source = ./niri/waybar/style.css; + "mako/config".source = ./niri/mako/config; + "fuzzel/fuzzel.ini".source = ./niri/fuzzel/fuzzel.ini; + }; + programs.home-manager.enable = true; } diff --git a/niri.nix b/niri.nix new file mode 100644 index 0000000..731c1b0 --- /dev/null +++ b/niri.nix @@ -0,0 +1,43 @@ +{ pkgs, ... }: + +{ + programs.niri.enable = true; + + environment.systemPackages = with pkgs; [ + # terminal + launcher + alacritty + fuzzel + + # bar, notifications, wallpaper + waybar + mako + swaybg + + # screenshots + clipboard + grim + slurp + swappy + wl-clipboard + + # lock + idle + swaylock-effects + swayidle + wlogout + + # XWayland shim for niri + xwayland-satellite + + # tray + system utilities + networkmanagerapplet + pavucontrol + playerctl + brightnessctl + libnotify + xdg-utils + ]; + + environment.sessionVariables = { + XDG_CURRENT_DESKTOP = "niri"; + XDG_SESSION_DESKTOP = "niri"; + }; +} diff --git a/niri/config.kdl b/niri/config.kdl new file mode 100644 index 0000000..55dd2ea --- /dev/null +++ b/niri/config.kdl @@ -0,0 +1,201 @@ +// niri configuration +// docs: https://github.com/YaLTeR/niri/wiki/Configuration:-Overview + +input { + keyboard { + xkb { + layout "us" + } + repeat-delay 300 + repeat-rate 40 + } + + touchpad { + tap + dwt + natural-scroll + accel-speed 0.2 + } + + mouse { + accel-speed 0.0 + } + + warp-mouse-to-focus +} + +output "*" { + // let niri autodetect; override here per-monitor if needed +} + +layout { + gaps 12 + center-focused-column "never" + + preset-column-widths { + proportion 0.33333 + proportion 0.5 + proportion 0.66667 + } + + default-column-width { proportion 0.5; } + + focus-ring { + width 2 + active-color "#7fc8ff" + inactive-color "#3a3a3a" + } + + border { + off + } + + struts { + left 8 + right 8 + top 4 + bottom 4 + } +} + +cursor { + xcursor-theme "Adwaita" + xcursor-size 24 +} + +prefer-no-csd + +screenshot-path "~/Pictures/Screenshots/Screenshot-%Y-%m-%d-%H%M%S.png" + +hotkey-overlay { + skip-at-startup +} + +environment { + DISPLAY ":0" + QT_QPA_PLATFORM "wayland;xcb" + GDK_BACKEND "wayland,x11" + MOZ_ENABLE_WAYLAND "1" + _JAVA_AWT_WM_NONREPARENTING "1" +} + +spawn-at-startup "xwayland-satellite" +spawn-at-startup "waybar" +spawn-at-startup "mako" +spawn-at-startup "swaybg" "-c" "#1e1e2e" +spawn-at-startup "nm-applet" "--indicator" +spawn-at-startup "swayidle" "-w" \ + "timeout" "600" "swaylock -f" \ + "timeout" "900" "niri msg action power-off-monitors" \ + "before-sleep" "swaylock -f" + +window-rule { + geometry-corner-radius 8 + clip-to-geometry true +} + +window-rule { + match app-id="^org\\.keepassxc\\.KeePassXC$" + match app-id="^1Password$" + block-out-from "screen-capture" +} + +binds { + Mod+Shift+Slash { show-hotkey-overlay; } + + // launchers + Mod+Return { spawn "alacritty"; } + Mod+D { spawn "fuzzel"; } + Mod+E { spawn "dolphin"; } + Mod+B { spawn "firefox"; } + Mod+Ctrl+L { spawn "swaylock" "-f"; } + Mod+Shift+Escape { spawn "wlogout"; } + + // media keys + XF86AudioRaiseVolume allow-when-locked=true { spawn "wpctl" "set-volume" "-l" "1.0" "@DEFAULT_AUDIO_SINK@" "5%+"; } + XF86AudioLowerVolume allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%-"; } + XF86AudioMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; } + XF86AudioMicMute allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; } + XF86AudioPlay { spawn "playerctl" "play-pause"; } + XF86AudioPause { spawn "playerctl" "play-pause"; } + XF86AudioNext { spawn "playerctl" "next"; } + XF86AudioPrev { spawn "playerctl" "previous"; } + XF86MonBrightnessUp { spawn "brightnessctl" "set" "5%+"; } + XF86MonBrightnessDown { spawn "brightnessctl" "set" "5%-"; } + + // window management + Mod+Q { close-window; } + + Mod+Left { focus-column-left; } + Mod+Right { focus-column-right; } + Mod+Up { focus-window-up; } + Mod+Down { focus-window-down; } + Mod+H { focus-column-left; } + Mod+L { focus-column-right; } + Mod+K { focus-window-up; } + Mod+J { focus-window-down; } + + Mod+Ctrl+Left { move-column-left; } + Mod+Ctrl+Right { move-column-right; } + Mod+Ctrl+Up { move-window-up; } + Mod+Ctrl+Down { move-window-down; } + Mod+Ctrl+H { move-column-left; } + Mod+Ctrl+L { move-column-right; } + Mod+Ctrl+K { move-window-up; } + Mod+Ctrl+J { move-window-down; } + + Mod+Home { focus-column-first; } + Mod+End { focus-column-last; } + + Mod+Page_Down { focus-workspace-down; } + Mod+Page_Up { focus-workspace-up; } + Mod+U { focus-workspace-down; } + Mod+I { focus-workspace-up; } + + Mod+Shift+Page_Down { move-column-to-workspace-down; } + Mod+Shift+Page_Up { move-column-to-workspace-up; } + Mod+Shift+U { move-column-to-workspace-down; } + Mod+Shift+I { move-column-to-workspace-up; } + + Mod+1 { focus-workspace 1; } + Mod+2 { focus-workspace 2; } + Mod+3 { focus-workspace 3; } + Mod+4 { focus-workspace 4; } + Mod+5 { focus-workspace 5; } + Mod+6 { focus-workspace 6; } + Mod+7 { focus-workspace 7; } + Mod+8 { focus-workspace 8; } + Mod+9 { focus-workspace 9; } + + Mod+Shift+1 { move-column-to-workspace 1; } + Mod+Shift+2 { move-column-to-workspace 2; } + Mod+Shift+3 { move-column-to-workspace 3; } + Mod+Shift+4 { move-column-to-workspace 4; } + Mod+Shift+5 { move-column-to-workspace 5; } + Mod+Shift+6 { move-column-to-workspace 6; } + Mod+Shift+7 { move-column-to-workspace 7; } + Mod+Shift+8 { move-column-to-workspace 8; } + Mod+Shift+9 { move-column-to-workspace 9; } + + Mod+Comma { consume-window-into-column; } + Mod+Period { expel-window-from-column; } + + Mod+R { switch-preset-column-width; } + Mod+F { maximize-column; } + Mod+Shift+F { fullscreen-window; } + Mod+C { center-column; } + + Mod+Minus { set-column-width "-10%"; } + Mod+Equal { set-column-width "+10%"; } + Mod+Shift+Minus { set-window-height "-10%"; } + Mod+Shift+Equal { set-window-height "+10%"; } + + // screenshots + Print { screenshot; } + Ctrl+Print { screenshot-screen; } + Alt+Print { screenshot-window; } + + // session + Mod+Shift+E { quit; } + Mod+Shift+P { power-off-monitors; } +} diff --git a/niri/fuzzel/fuzzel.ini b/niri/fuzzel/fuzzel.ini new file mode 100644 index 0000000..dc6ccad --- /dev/null +++ b/niri/fuzzel/fuzzel.ini @@ -0,0 +1,23 @@ +font=JetBrainsMono Nerd Font:size=12 +dpi-aware=yes +terminal=alacritty +prompt=" " +icon-theme=Adwaita +width=40 +lines=12 +horizontal-pad=20 +vertical-pad=14 +inner-pad=10 + +[colors] +background=1e1e2eee +text=cdd6f4ff +match=f9e2afff +selection=89b4faff +selection-text=1e1e2eff +selection-match=1e1e2eff +border=89b4faff + +[border] +width=2 +radius=10 diff --git a/niri/mako/config b/niri/mako/config new file mode 100644 index 0000000..3882a53 --- /dev/null +++ b/niri/mako/config @@ -0,0 +1,20 @@ +font=JetBrainsMono Nerd Font 10 +background-color=#1e1e2eee +text-color=#cdd6f4 +border-color=#89b4fa +border-size=2 +border-radius=8 +padding=12 +margin=8 +default-timeout=5000 +ignore-timeout=1 +max-visible=5 +layer=overlay +anchor=top-right + +[urgency=low] +border-color=#6c7086 + +[urgency=high] +border-color=#f38ba8 +default-timeout=0 diff --git a/niri/waybar/config.jsonc b/niri/waybar/config.jsonc new file mode 100644 index 0000000..bbd7d9f --- /dev/null +++ b/niri/waybar/config.jsonc @@ -0,0 +1,77 @@ +{ + "layer": "top", + "position": "top", + "height": 30, + "spacing": 6, + "margin-top": 4, + "margin-left": 8, + "margin-right": 8, + + "modules-left": ["niri/workspaces", "niri/window"], + "modules-center": ["clock"], + "modules-right": [ + "tray", + "network", + "pulseaudio", + "cpu", + "memory", + "custom/power" + ], + + "niri/workspaces": { + "format": "{icon}", + "format-icons": { + "default": "", + "active": "", + "urgent": "" + } + }, + + "niri/window": { + "format": "{title}", + "max-length": 80, + "separate-outputs": true + }, + + "clock": { + "format": "{:%a %d %b %H:%M}", + "tooltip-format": "{calendar}" + }, + + "cpu": { + "format": " {usage}%", + "interval": 2 + }, + + "memory": { + "format": " {used:0.1f}G", + "interval": 5 + }, + + "network": { + "format-wifi": " {essid}", + "format-ethernet": " {ifname}", + "format-disconnected": "⚠ offline", + "tooltip-format": "{ifname} · {ipaddr}" + }, + + "pulseaudio": { + "format": "{icon} {volume}%", + "format-muted": " muted", + "format-icons": { + "default": ["", "", ""] + }, + "on-click": "pavucontrol" + }, + + "tray": { + "icon-size": 16, + "spacing": 8 + }, + + "custom/power": { + "format": "⏻", + "tooltip": false, + "on-click": "wlogout" + } +} diff --git a/niri/waybar/style.css b/niri/waybar/style.css new file mode 100644 index 0000000..e7745a7 --- /dev/null +++ b/niri/waybar/style.css @@ -0,0 +1,62 @@ +* { + font-family: "JetBrainsMono Nerd Font", "Geist", sans-serif; + font-size: 13px; + border: none; + border-radius: 0; + min-height: 0; +} + +window#waybar { + background: rgba(30, 30, 46, 0.85); + color: #cdd6f4; + border-radius: 10px; +} + +#workspaces button { + padding: 0 8px; + color: #9399b2; + background: transparent; + border-radius: 6px; +} + +#workspaces button.active { + color: #1e1e2e; + background: #89b4fa; +} + +#workspaces button.urgent { + background: #f38ba8; + color: #1e1e2e; +} + +#window, +#clock, +#cpu, +#memory, +#network, +#pulseaudio, +#tray, +#custom-power { + padding: 0 10px; + margin: 4px 2px; + border-radius: 6px; + background: rgba(49, 50, 68, 0.6); +} + +#clock { + color: #f9e2af; + font-weight: 600; +} + +#custom-power { + color: #f38ba8; + padding: 0 12px; +} + +#network.disconnected { + color: #f38ba8; +} + +#pulseaudio.muted { + color: #6c7086; +}