{ lib, pkgs, ... }: with lib; let power-menu = pkgs.writeScript "power-menu" '' SELECTION="$(printf "󰌾 Lock\n󰶐 Power off monitors\n󰗽 Log out\n󰤄 Suspend\n Reboot\n󰐥 Shutdown" | fuzzel --dmenu -l 6 -p "⚡ ")" case $SELECTION in *"Lock") loginctl lock-session;; *"Power off monitors") niri msg action power-off-monitors;; *"Log out") niri msg action quit -s;; *"Suspend") systemctl suspend;; *"Reboot") systemctl reboot;; *"Shutdown") systemctl poweroff;; esac ''; in { imports = [../home.nix]; # Consistent theming. qt.enable = true; gtk.enable = true; stylix.icons = rec { enable = true; package = pkgs.adwaita-icon-theme; dark = "Adwaita"; light = dark; }; # XDG portals. xdg.portal = { enable = true; config.common.default = "*"; extraPortals = [ pkgs.xdg-desktop-portal-gnome pkgs.xdg-desktop-portal-gtk ]; }; # Create home directories. xdg.userDirs.createDirectories = true; # Niri WM. programs.niri = { settings = { # Wayland environment variables. environment = { CLUTTER_BACKEND = "wayland"; GDK_BACKEND = "wayland,x11"; MOZ_ENABLE_WAYLAND = "1"; NIXOS_OZONE_WL = "1"; QT_QPA_PLATFORM = "wayland;xcb"; QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; SDL_VIDEODRIVER = "wayland"; GTK_CSD = "0"; }; # X11 support. xwayland-satellite = { enable = true; path = getExe pkgs.xwayland-satellite-unstable; }; # Don't show client-side window decorations. prefer-no-csd = true; # Don't show hotkeys at startup. hotkey-overlay.skip-at-startup = true; # Disable hot corner. gestures.hot-corners.enable = false; # Keyboard, mouse, trackpad, trackpoint. input = { touchpad.natural-scroll = false; keyboard.repeat-rate = 60; }; binds = { # Spawn programs. "Mod+Return".action.spawn = "ghostty"; "Mod+Space".action.spawn = "fuzzel"; "Mod+E".action.spawn = "bemoji"; "Mod+Alt+L".action.spawn = "hyprlock"; # Show overview "Mod+Escape".action.toggle-overview = {}; # Media & brightness control. "XF86AudioRaiseVolume" = { allow-when-locked = true; action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%+"]; }; "XF86AudioLowerVolume" = { allow-when-locked = true; action.spawn = ["wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "5%-"]; }; "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"]; }; "XF86AudioPlay" = { allow-when-locked = true; action.spawn = ["playerctl" "play-pause"]; }; "XF86AudioStop" = { allow-when-locked = true; action.spawn = ["playerctl" "pause"]; }; "XF86AudioPrev" = { allow-when-locked = true; action.spawn = ["playerctl" "previous"]; }; "XF86AudioNext" = { allow-when-locked = true; action.spawn = ["playerctl" "next"]; }; "XF86MonBrightnessUp" = { allow-when-locked = true; action.spawn = ["brillo" "-A" "5"]; }; "XF86MonBrightnessDown" = { allow-when-locked = true; action.spawn = ["brillo" "-U" "5"]; }; # Close windows. "Mod+Q".action.close-window = {}; # Power menu. "Mod+Shift+E".action.spawn = "${power-menu}"; # Take a screenshot. "Mod+P".action.screenshot = {}; "Mod+Shift+P".action.screenshot-screen = {}; "Mod+Shift+Ctrl+P".action.screenshot-window = {}; # Focus and move columns. "Mod+H".action.focus-column-left = {}; "Mod+J".action.focus-window-down = {}; "Mod+K".action.focus-window-up = {}; "Mod+L".action.focus-column-right = {}; "Mod+Shift+H".action.move-column-left = {}; "Mod+Shift+J".action.move-window-down = {}; "Mod+Shift+K".action.move-window-up = {}; "Mod+Shift+L".action.move-column-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 = {}; # Focus monitors. "Mod+bracketleft".action.focus-monitor-left = {}; "Mod+bracketright".action.focus-monitor-right = {}; # Move columns between monitors. "Mod+Shift+bracketleft".action.move-column-to-monitor-left = {}; "Mod+Shift+bracketright".action.move-column-to-monitor-right = {}; # Focus workspaces. "Mod+U".action.focus-workspace-down = {}; "Mod+I".action.focus-workspace-up = {}; "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; # Move columns to workspaces. "Mod+Shift+U".action.move-column-to-workspace-down = {}; "Mod+Shift+I".action.move-column-to-workspace-up = {}; "Mod+Shift+1".action.move-column-to-workspace = 1; "Mod+Shift+2".action.move-column-to-workspace = 2; "Mod+Shift+3".action.move-column-to-workspace = 3; "Mod+Shift+4".action.move-column-to-workspace = 4; "Mod+Shift+5".action.move-column-to-workspace = 5; "Mod+Shift+6".action.move-column-to-workspace = 6; "Mod+Shift+7".action.move-column-to-workspace = 7; "Mod+Shift+8".action.move-column-to-workspace = 8; "Mod+Shift+9".action.move-column-to-workspace = 9; # Expel & consume windows into columns. "Mod+Comma".action.consume-window-into-column = {}; "Mod+Period".action.expel-window-from-column = {}; # Resize columns. "Mod+R".action.switch-preset-column-width = {}; "Mod+Shift+R".action.reset-window-height = {}; "Mod+F".action.maximize-column = {}; "Mod+Shift+F".action.fullscreen-window = {}; "Mod+C".action.center-column = {}; "Mod+Minus".action.set-column-width = "-10%"; "Mod+Equal".action.set-column-width = "+10%"; "Mod+Shift+Minus".action.set-window-height = "-10%"; "Mod+Shift+Equal".action.set-window-height = "+10%"; }; layout = { gaps = 4; border.width = 1; preset-column-widths = [ {proportion = 1.0 / 3.0;} {proportion = 1.0 / 2.0;} {proportion = 2.0 / 6.0;} ]; default-column-width = { proportion = 1.0 / 2.0; }; }; }; }; # Lock screen. programs.hyprlock = { enable = true; settings = { input-field = { fade_on_empty = false; rounding = 0; outline_thickness = 1; valign = "center"; halign = "center"; position = "0%, -10%"; size = "20%, 5%"; }; label = { valign = "center"; halign = "center"; position = "0%, 10%"; text = "$TIME"; font_size = 128; font_family = "Adwaita Sans Bold"; }; }; }; stylix.targets.hyprlock.useWallpaper = false; # Auto-lock. services.hypridle = { enable = true; settings = { general = { lock_cmd = "pidof hyprlock || hyprlock"; before_sleep_cmd = "loginctl lock-session"; after_sleep_cmd = "niri msg action power-on-monitors"; }; listener = [ { timeout = 300; on-timeout = "brillo -O; brillo -u 500000 -S 10"; on-resume = "brillo -I -u 250000"; } { timeout = 600; on-timeout = "loginctl lock-session"; } { timeout = 900; on-timeout = "niri msg action power-off-monitors"; } ]; }; }; # Launcher. programs.fuzzel = { enable = true; settings = { main = { terminal = "ghostty"; horizontal-pad = 8; vertical-pad = 8; inner-pad = 8; }; border.radius = 0; }; }; # Panel. programs.waybar = { enable = true; systemd.enable = true; settings.main = { modules-left = ["niri/workspaces"]; modules-center = ["clock"]; modules-right = ["network" "wireplumber" "battery#0" "battery#1"]; "battery#0" = { bat = "BAT0"; format-icons = ["󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂁" "󰂂" "󰁹"]; format = "{icon} {capacity}%"; format-charging = "󱐋 {icon} {capacity}%"; tooltip = false; }; "battery#1" = { bat = "BAT1"; format-icons = ["󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂁" "󰂂" "󰁹"]; format = "{icon} {capacity}%"; tooltip = false; }; "network" = { format-icons = ["󰤯" "󰤟" "󰤢" "󰤥" "󰤨"]; format = "{icon}"; format-disconnected = ""; tooltip = true; tooltip-format = "{essid}"; on-click = "nm-connection-editor"; }; "wireplumber" = { format-icons = ["" "" ""]; format = "{icon} {volume}%"; format-muted = " "; tooltip = false; on-click = "pwvucontrol"; }; "clock" = { format = "{:%a %b %d · %H:%M}"; tooltip = false; }; }; style = '' * { border-radius: 0; } ''; }; stylix.targets.waybar.font = "sansSerif"; # use sans-serif font, not monospaced. # Enable polkit-gnome. services.polkit-gnome.enable = true; # Wallpaper manager. services.hyprpaper.enable = true; # Notifications services.mako.enable = true; # Day/night gamma adjustment. services.wlsunset = { sunset = "18:00"; sunrise = "06:00"; }; # Clipboard manager. services.cliphist.enable = true; # Nextcloud client. services.nextcloud-client.enable = true; # Install some software. programs.ghostty = { enable = true; settings = { window-padding-x = 4; window-padding-y = 4; }; }; programs.firefox = { enable = true; profiles.default = { settings."identity.sync.tokenserver.uri" = "https://fxsync.fern.garden/1.0/sync/1.5"; }; }; stylix.targets.firefox.profileNames = ["default"]; fonts.fontconfig.enable = true; # discover fonts installed by home.packages. home.packages = with pkgs; [ bemoji caligula celluloid decibels deploy-rs feishin file-roller fluffychat fusee-nano gimp3 glabels-qt gnome-calculator gnome-characters gnome-font-viewer hyprpicker jellyfin-media-player libreoffice loupe nautilus nerd-fonts.symbols-only networkmanagerapplet noto-fonts noto-fonts-cjk-sans noto-fonts-cjk-serif ns-usbloader nwg-clipman obsidian papers playerctl prismlauncher protonmail-desktop pwvucontrol rockbox-utility seahorse signal-desktop simple-scan system-config-printer via wdisplays webcord wl-clipboard yubioath-flutter ]; }