{ config, pkgs, ... }: # Hyprland Wayland compositor + QuickShell desktop shell. # This is the Hyprland counterpart to modules/desktop/gnome.nix — import this # INSTEAD of gnome.nix when a host should run Hyprland + QuickShell. { # Hyprland compositor with XWayland (for legacy apps) programs.hyprland = { enable = true; xwayland.enable = true; }; # hyprlock PAM service — required for password authentication to work. programs.hyprlock.enable = true; # Minimal display manager: greetd + tuigreet (TTY greeter). # The greetd NixOS module creates the "greeter" system user/group for us. services.greetd = { enable = true; useTextGreeter = true; settings = { default_session = { # Launch via start-hyprland (not the raw Hyprland binary) so the session # env (XDG_CURRENT_DESKTOP, portals, etc.) is set up and the # "started without start-hyprland" watchdog warning is avoided. command = "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd start-hyprland"; user = "greeter"; }; }; }; # Enable XDG Desktop Portal (Flatpak/file pickers/screen sharing) via Hyprland xdg.portal = { enable = true; extraPortals = [ pkgs.xdg-desktop-portal-hyprland ]; # Explicit portal backend config (xdg-desktop-portal >= 1.17 behavior). config.common.default = "hyprland"; }; # dconf is required by many GTK apps regardless of desktop environment programs.dconf.enable = true; # NixOS grants all NetworkManager polkit actions to members of the # "networkmanager" group. Membership is required here because greetd starts # the graphical session inside the greetd.service cgroup instead of an # *active* logind session scope, so NetworkManager's default # allow_active-only policy would reject connection changes from the # QuickShell wifi menu / nmcli with "insufficient privileges". users.groups.networkmanager.members = [ "petere" ]; # Audio via PipeWire (GNOME pulls this in automatically; Hyprland does not) services.pipewire = { enable = true; alsa.enable = true; alsa.support32Bit = true; pulse.enable = true; wireplumber.enable = true; }; security.rtkit.enable = true; # UPower daemon — the QuickShell bar reads battery state through # Quickshell.Services.UPower. services.upower.enable = true; # Power profiles (power-saver / balanced / performance) over DBus — exposed # in the QuickShell quick-settings panel via PowerProfiles.profile. services.power-profiles-daemon.enable = true; # Explicit lid policy: closing the lid always locks then suspends — on # battery AND on external power. hypridle's `before_sleep_cmd = # loginctl lock-session` fires before logind sleeps (lock_cmd -> hyprlock), # so reopening the lid resumes to a locked screen. Docked stays on logind's # default "ignore" so external displays keep working with the lid shut. services.logind.settings.Login = { HandleLidSwitch = "suspend"; HandleLidSwitchExternalPower = "suspend"; }; # Core Wayland / Hyprland ecosystem + QuickShell shell environment.systemPackages = with pkgs; [ quickshell hyprlock hypridle hyprpaper hyprpicker wlogout wayland-utils wl-clipboard grim slurp grimblast wofi # Screen backlight control (QuickShell quick-settings brightness slider) brightnessctl # Media keys: volume (PipeWire via Pulse compat), MPRIS playback control pamixer playerctl # notify-send for QuickShell battery-low toasts (native NotificationServer) libnotify # Blue-light filter toggled from Hyprland (SUPER+SHIFT+N) hyprsunset # File manager (lightweight GTK; gvfs adds trash/mount support) thunar gvfs ]; }