{ lib, namespace, ... }: with lib; { options.${namespace}.programs.hyprland = { enable = mkEnableOption "enable hyprland"; primaryDisplay = mkOption { type = types.str; default = "DP-1"; description = "Primary display identifier"; }; display1 = { input = mkOption { type = types.str; default = "DP-1"; description = "First display identifier (Deprecated: prefer monitorv2)"; }; resolution = mkOption { type = types.str; default = "3840x2160"; description = "First display resolution (Deprecated: prefer monitorv2)"; }; refreshRate = mkOption { type = types.str; default = "240.00000"; description = "First display refresh rate (Deprecated: prefer monitorv2)"; }; }; display2 = { input = mkOption { type = types.str; default = "DP-1"; description = "Second display identifier (Deprecated: prefer monitorv2)"; }; resolution = mkOption { type = types.str; default = "3840x2160"; description = "Second display resolution (Deprecated: prefer monitorv2)"; }; refreshRate = mkOption { type = types.str; default = "240.00000"; description = "Second display refresh rate (Deprecated: prefer monitorv2)"; }; }; # Deprecated: prefer hyprpaper.* options wallpaper = mkOption { type = with types; listOf str; default = [ ]; description = "Deprecated: no longer used; prefer hyprpaper.wallpaperPath and hyprpaper.usePerMonitor."; }; hyprpaper = mkOption { type = types.submodule { options = { wallpaperPath = mkOption { type = types.str; default = "/run/wallpaper.jpg"; description = "Path to the wallpaper used by hyprpaper."; }; usePerMonitor = mkOption { type = types.bool; default = true; description = "If true, generate one wallpaper entry per monitor (monitorv2 preferred, falls back to display1/display2)."; }; }; }; default = { }; description = "Hyprpaper configuration."; }; monitor = mkOption { type = with types; listOf str; default = [ ]; description = "List of Hyprland monitor configs (legacy). Example: [ \"eDP-1, 1920x1080@60, 0x0, 1\" ]"; }; monitorv2 = mkOption { type = with types; listOf ( types.submodule { options = { name = mkOption { type = types.str; description = "Monitor name (e.g., DP-1, eDP-1)."; }; mode = mkOption { type = types.nullOr types.str; default = null; description = "Resolution@Hz or keyword (e.g., \"3840x2160@144\" or \"preferred\")."; }; position = mkOption { type = types.nullOr types.str; default = null; description = "Position like \"0x0\" or \"auto\"."; }; scale = mkOption { type = types.nullOr types.float; default = null; description = "Scale factor (e.g., 1.0)."; }; transform = mkOption { type = types.nullOr types.str; default = null; description = "Rotation/transform (e.g., \"normal\", \"90\", \"180\", \"270\", \"flipped\")."; }; disabled = mkOption { type = types.bool; default = false; description = "Disable this monitor."; }; mirrorOf = mkOption { type = types.nullOr types.str; default = null; description = "Mirror another monitor by name."; }; extra = mkOption { type = with types; listOf str; default = [ ]; description = "Additional monitorv2 flags appended as-is."; }; }; } ); default = [ ]; description = "Hyprland monitorv2 entries as structured options; rendered to lines like \"name, mode, position, scale, transform, ...\"."; }; workspace = mkOption { type = with types; listOf str; default = [ ]; description = "List of hyprland workspace definitions"; }; windowRule = mkOption { type = with types; listOf str; default = [ ]; description = "List of hyprland window rules"; }; extraConfig = mkOption { type = with types; str; default = ""; description = "Any extra configuration options"; }; defaultApps = mkOption { type = types.submodule (import ../common/default-apps.nix); description = "Default applications used across the system"; }; autostartCommands = mkOption { type = with types; listOf str; default = [ "nwg-look -a" "nwg-dock-hyprland -x" ]; description = "Commands to run via Hyprland exec-once"; }; launcher = mkOption { type = types.enum [ "wofi" "rofi" ]; default = "wofi"; description = "Application launcher to use in keybinds and packages."; }; notificationDaemon = mkOption { type = types.enum [ "mako" "dunst" ]; default = "mako"; description = "Notification daemon to install."; }; modKey = mkOption { type = types.str; default = "SUPER"; description = "Modifier key used for Hyprland binds (e.g., SUPER, ALT)."; }; enableVRR = mkOption { type = types.bool; default = true; description = "Enable variable refresh rate (maps to Hyprland misc.vrr)."; }; allowTearing = mkOption { type = types.bool; default = true; description = "Allow tearing (maps to Hyprland general.allow_tearing)."; }; debug = mkOption { type = types.submodule { options = { disableLogs = mkOption { type = types.bool; default = false; description = "Set Hyprland debug.disable_logs."; }; fullCmProto = mkOption { type = types.bool; default = false; description = "Set Hyprland debug.full_cm_proto."; }; disableScaleChecks = mkOption { type = types.bool; default = false; description = "Set Hyprland debug.disable_scale_checks."; }; }; }; default = { }; description = "Hyprland debug flags."; }; keybinds = mkOption { type = types.submodule { options = { bind = mkOption { type = with types; listOf str; default = [ ]; description = "Hyprland bind entries."; }; bindm = mkOption { type = with types; listOf str; default = [ ]; description = "Hyprland bindm entries."; }; bindel = mkOption { type = with types; listOf str; default = [ ]; description = "Hyprland bindel entries."; }; bindl = mkOption { type = with types; listOf str; default = [ ]; description = "Hyprland bindl entries."; }; }; }; default = { }; description = "Keybinding lists for Hyprland; useful for host-level overrides."; }; gestures = mkOption { type = with types; listOf str; default = [ ]; description = "Hyprland gesture entries."; }; hyprIdle = { lockScreenTimer = mkOption { type = with types; int; default = 300; description = "Time in seconds before locking the screen"; }; screenOffTimer = mkOption { type = with types; int; default = 900; description = "Time in seconds before turning off the screen"; }; suspendTimer = mkOption { type = with types; int; default = 1800; description = "Time in seconds before suspending"; }; }; }; }