From 26b9dbf83cd485e0cdfd4d650afbf03257cb57e9 Mon Sep 17 00:00:00 2001 From: KoenDR06 Date: Wed, 16 Jul 2025 14:45:59 +0200 Subject: [PATCH] restructure so the options don't have the config already mixed in --- modules/wm/hyprland/default.nix | 341 ++++++++++++++++++------- modules/wm/hyprland/options.nix | 430 +++++++++++--------------------- 2 files changed, 389 insertions(+), 382 deletions(-) diff --git a/modules/wm/hyprland/default.nix b/modules/wm/hyprland/default.nix index e92eae9..eaf6f32 100644 --- a/modules/wm/hyprland/default.nix +++ b/modules/wm/hyprland/default.nix @@ -1,19 +1,17 @@ { - inputs, - outputs, lib, config, pkgs, ... }: let - inherit (lib) mkIf trivial strings replaceStrings; - cfg = config.horseman.wm.hyprland; + inherit (lib) mkIf; + cfg123 = config.horseman.wm.hyprland; in { imports = [ ./options.nix ]; - config = mkIf cfg.enable { + config = mkIf cfg123.enable { programs.hyprland = { enable = true; xwayland.enable = true; @@ -41,99 +39,250 @@ in { xdg-desktop-portal-hyprland ]; + horseman.wm.hyprland.config = { + execOnce = [ + "hyprpaper" + "eww daemon" + "hypridle" + "hyprpaper" + "swaync" + ]; + + env = [ + "XCURSOR_SIZE,24" + "HYPRCURSOR_SIZE,24" + ]; + + windowrules = [ + "suppressevent maximize, class:.*" + "nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0" + "rounding 0, floating:0 onworkspace:w[t1]" + "bordersize 0, floating:0 onworkspace:w[t1]" + "float, initialTitle:^Picture-in-Picture$" + "center, initialTitle:^Picture-in-Picture$" + "size 33% 33%, initialTitle:^Picture-in-Picture$" + "float, initialClass:CImg" + ]; + + workspaces = [ + "w[t1], gapsout:0, gapsin:0" + ]; + + general = { + gapsIn = 5; + gapsOut = 5; + borderSize = 2; + + resizeOnBorder = true; + allowTearing = false; + + col.activeBorder = "rgba(b7bdf8ff)"; + col.inactiveBorder = "rgba(b7bdf840)"; + + layout = "dwindle"; + }; + + decoration = { + rounding = 10; + activeOpacity = 1.0; + inactiveOpacity = 1.0; + + shadow = { + enabled = true; + range = 4; + renderPower = 3; + color = "rgba(1a1a1aee)"; + }; + + blur = { + enabled = true; + size = 3; + passes = 3; + vibrancy = 0.1696; + }; + }; + + animations = { + enabled = true; + beziers = [ + { + name = "easeOutQuint"; + startX = 0.23; + startY = 1.0; + endX = 0.32; + endY = 1.0; + } + { + name = "easeInOutCubic"; + startX = 0.65; + startY = 0.05; + endX = 0.36; + endY = 1.0; + } + { + name = "linear"; + startX = 0.0; + startY = 0.0; + endX = 1.0; + endY = 1.0; + } + { + name = "almostLinear"; + startX = 0.5; + startY = 0.5; + endX = 0.75; + endY = 1.0; + } + { + name = "quick"; + startX = 0.15; + startY = 0.0; + endX = 0.1; + endY = 1.0; + } + ]; + + animations = [ + { + name = "global"; + on = true; + speed = 10.0; + curve = "default"; + } + { + name = "border"; + on = true; + speed = 5.39; + curve = "easeOutQuint"; + } + { + name = "windows"; + on = true; + speed = 4.79; + curve = "easeOutQuint"; + } + { + name = "windowsIn"; + on = true; + speed = 4.1; + curve = "easeOutQuint"; + style = "popin 87%"; + } + { + name = "windowsOut"; + on = true; + speed = 1.49; + curve = "linear"; + style = "popin 87%"; + } + { + name = "fadeIn"; + on = true; + speed = 1.73; + curve = "almostLinear"; + } + { + name = "fadeOut"; + on = true; + speed = 1.46; + curve = "almostLinear"; + } + { + name = "fade"; + on = true; + speed = 3.03; + curve = "quick"; + } + { + name = "layers"; + on = true; + speed = 3.81; + curve = "easeOutQuint"; + } + { + name = "layersIn"; + on = true; + speed = 4.0; + curve = "easeOutQuint"; + style = "fade"; + } + { + name = "layersOut"; + on = true; + speed = 1.5; + curve = "linear"; + style = "fade"; + } + { + name = "fadeLayersIn"; + on = true; + speed = 1.79; + curve = "almostLinear"; + } + { + name = "fadeLayersOut"; + on = true; + speed = 1.39; + curve = "almostLinear"; + } + { + name = "workspaces"; + on = true; + speed = 1.94; + curve = "almostLinear"; + style = "fade"; + } + { + name = "workspacesIn"; + on = true; + speed = 1.21; + curve = "almostLinear"; + style = "fade"; + } + { + name = "workspacesOut"; + on = true; + speed = 1.94; + curve = "almostLinear"; + style = "fade"; + } + ]; + }; + + dwindle = { + pseudotile = true; + preserveSplit = true; + }; + + master = { + newStatus = "master"; + }; + + misc = { + forceDefaultWallpaper = 0; + }; + + input = { + kbLayout = "us"; + repeatRate = 50; + repeatDelay = 300; + followMouse = 1; + sensitivity = 0.0; + touchpad.naturalScroll = true; + numlockByDefault = true; + }; + + gestures = { + workspaceSwipe = false; + }; + + monitors = { + defaultMonitor = true; + }; + }; + services.logind.extraConfig = '' HandlePowerKey=ignore ''; - - system.activationScripts.script.text = '' - cd /home/horseman/.config - rm -r hypr/* - touch hypr/hyprland.conf - - printf "# This file has been auto-generated. - - ${builtins.concatStringsSep "\n" (map (x: "exec-once = " + x) cfg.config.execOnce)} - - ${builtins.concatStringsSep "\n" (map (x: "env = " + x) cfg.config.env)} - - general { - gaps_in = ${toString cfg.config.general.gapsIn} - gaps_out = ${toString cfg.config.general.gapsOut} - border_size = ${toString cfg.config.general.borderSize} - col.active_border = ${cfg.config.general.col.activeBorder} - col.inactive_border = ${cfg.config.general.col.inactiveBorder} - resize_on_border = ${trivial.boolToString cfg.config.general.resizeOnBorder} - allow_tearing = ${trivial.boolToString cfg.config.general.allowTearing} - layout = ${cfg.config.general.layout} - } - - decoration { - rounding = ${toString cfg.config.decoration.rounding} - - active_opacity = ${strings.floatToString cfg.config.decoration.activeOpacity} - inactive_opacity = ${strings.floatToString cfg.config.decoration.inactiveOpacity} - - shadow { - enabled = ${trivial.boolToString cfg.config.decoration.shadow.enabled} - range = ${toString cfg.config.decoration.shadow.range} - render_power = ${toString cfg.config.decoration.shadow.renderPower} - color = ${cfg.config.decoration.shadow.color} - } - - blur { - enabled = ${trivial.boolToString cfg.config.decoration.blur.enabled} - size = ${toString cfg.config.decoration.blur.size} - passes = ${toString cfg.config.decoration.blur.passes} - vibrancy = ${strings.floatToString cfg.config.decoration.blur.vibrancy} - } - } - - animations { - enabled = ${trivial.boolToString cfg.config.animations.enabled} - - ${builtins.concatStringsSep "\n " (map(bez: "bezier = ${bez.name}, ${strings.floatToString bez.startX}, ${strings.floatToString bez.startY}, ${strings.floatToString bez.endX}, ${strings.floatToString bez.endY}") cfg.config.animations.beziers)} - - ${builtins.concatStringsSep "\n " (map(anim: "animation = ${anim.name}, ${toString anim.on}, ${strings.floatToString anim.speed}, ${anim.curve}, ${replaceStrings ["%"] ["%%"] anim.style}") cfg.config.animations.animations)} - } - - dwindle { - pseudotile = ${trivial.boolToString cfg.config.dwindle.pseudotile} - preserve_split = ${trivial.boolToString cfg.config.dwindle.preserveSplit} - } - - master { - new_status = ${cfg.config.master.newStatus} - } - - misc { - force_default_wallpaper = ${toString cfg.config.misc.forceDefaultWallpaper} - } - - input { - kb_layout = ${cfg.config.input.kbLayout} - repeat_rate = ${toString cfg.config.input.repeatRate} - repeat_delay = ${toString cfg.config.input.repeatDelay} - follow_mouse = ${toString cfg.config.input.followMouse} - sensitivity = ${strings.floatToString cfg.config.input.sensitivity} - numlock_by_default = ${trivial.boolToString cfg.config.input.numlockByDefault} - - touchpad { - natural_scroll = ${trivial.boolToString cfg.config.input.touchpad.naturalScroll} - } - } - - gestures { - workspace_swipe = ${trivial.boolToString cfg.config.gestures.workspaceSwipe} - } - - ${builtins.concatStringsSep "\n" (map (mon: "monitor = ${mon.output}, ${mon.resolution}@${mon.refreshRate}, ${toString mon.x}x${toString mon.y}, ${strings.floatToString mon.scale}, transform, ${toString mon.transform}") cfg.config.monitors.displays)} - - ${if cfg.config.monitors.defaultMonitor then "monitor = ,preferred, auto, auto" else ""} - - ${builtins.concatStringsSep "\n" (map (ws: "workspace = " + ws) cfg.config.workspaces)} - - ${builtins.concatStringsSep "\n" (map (wr: "windowrule = " + replaceStrings ["%"] ["%%"] wr) cfg.config.windowrules)} - " >> hypr/hyprland.conf - ''; }; } diff --git a/modules/wm/hyprland/options.nix b/modules/wm/hyprland/options.nix index 86cff92..125c3da 100644 --- a/modules/wm/hyprland/options.nix +++ b/modules/wm/hyprland/options.nix @@ -1,162 +1,82 @@ { lib, + config, ... }: let - inherit (lib) mkEnableOption mkOption types; + inherit (lib) mkEnableOption mkOption types trivial strings replaceStrings; + cfg = config.horseman.wm.hyprland; + keybinding = types.submodule { + options = { + flags = mkOption { + type = types.listOf types.enum [ "l" "r" "c" "g" "o" "e" "m" "t" "i" "s" "d" "p" ]; + default = []; + }; + + mods = mkOption { + type = types.listOf types.str; + }; + + key = mkOption { + type = types.str; + }; + + dispatcher = mkOption { + type = types.str; + }; + + params = mkOption { + type = types.str; + }; + }; + }; in { options = { horseman.wm.hyprland = { enable = mkEnableOption "Hyprland"; config = { - execOnce = mkOption { - type = types.listOf types.str; - default = [ - "hyprpaper" - "eww daemon" - "hypridle" - "hyprpaper" - "swaync" - ]; - }; - - env = mkOption { - type = types.listOf types.str; - default = [ - "XCURSOR_SIZE,24" - "HYPRCURSOR_SIZE,24" - ]; - }; - - windowrules = mkOption { - type = types.listOf types.str; - - default = [ - "suppressevent maximize, class:.*" - "nofocus,class:^$,title:^$,xwayland:1,floating:1,fullscreen:0,pinned:0" - "rounding 0, floating:0 onworkspace:w[t1]" - "bordersize 0, floating:0 onworkspace:w[t1]" - "float, initialTitle:^Picture-in-Picture$" - "center, initialTitle:^Picture-in-Picture$" - "size 33% 33%, initialTitle:^Picture-in-Picture$" - "float, initialClass:CImg" - ]; - }; + execOnce = mkOption { type = types.listOf types.str; }; + env = mkOption { type = types.listOf types.str; }; + windowrules = mkOption { type = types.listOf types.str; }; workspaces = mkOption { type = types.listOf types.str; - default = [ - "w[t1], gapsout:0, gapsin:0" - ]; }; general = { - gapsIn = mkOption { - type = types.int; - default = 5; - }; - - gapsOut = mkOption { - type = types.int; - default = 5; - }; - - borderSize = mkOption { - type = types.int; - default = 2; - }; - - col.activeBorder = mkOption { - type = types.str; - default = "rgba(b7bdf8ff)"; - }; - - col.inactiveBorder = mkOption { - type = types.str; - default = "rgba(b7bdf840)"; - }; - - resizeOnBorder = mkOption { - type = types.bool; - default = true; - }; - - allowTearing = mkOption { - type = types.bool; - default = false; - }; - - layout = mkOption { - type = types.enum ["dwindle" "master"]; - default = "dwindle"; - }; + gapsIn = mkOption { type = types.int; }; + gapsOut = mkOption { type = types.int; }; + borderSize = mkOption { type = types.int; }; + col.activeBorder = mkOption { type = types.str; }; + col.inactiveBorder = mkOption { type = types.str; }; + resizeOnBorder = mkOption { type = types.bool; }; + allowTearing = mkOption { type = types.bool; }; + layout = mkOption { type = types.enum ["dwindle" "master"]; }; }; decoration = { - rounding = mkOption { - type = types.int; - default = 10; - }; - - activeOpacity = mkOption { - type = types.float; - default = 1.0; - }; - - inactiveOpacity = mkOption { - type = types.float; - default = 1.0; - }; + rounding = mkOption { type = types.int; }; + activeOpacity = mkOption { type = types.float; }; + inactiveOpacity = mkOption { type = types.float; }; shadow = { - enabled = mkOption { - type = types.bool; - default = true; - }; - - range = mkOption { - type = types.int; - default = 4; - }; - - renderPower = mkOption { - type = types.int; - default = 3; - }; - - color = mkOption { - type = types.str; - default = "rgba(1a1a1aee)"; - }; + enabled = mkOption { type = types.bool; }; + range = mkOption { type = types.int; }; + renderPower = mkOption { type = types.int; }; + color = mkOption { type = types.str; }; }; blur = { - enabled = mkOption { - type = types.bool; - default = true; - }; - - size = mkOption { - type = types.int; - default = 3; - }; - - passes = mkOption { - type = types.int; - default = 3; - }; - - vibrancy = mkOption { - type = types.float; - default = 0.1696; - }; + enabled = mkOption { type = types.bool; }; + size = mkOption { type = types.int; }; + passes = mkOption { type = types.int; }; + vibrancy = mkOption { type = types.float; }; }; }; animations = { enabled = mkOption { type = types.bool; - default = true; }; beziers = mkOption { @@ -169,43 +89,6 @@ in { endY = mkOption {type = types.number;}; }; }); - default = [ - { - name = "easeOutQuint"; - startX = 0.23; - startY = 1.0; - endX = 0.32; - endY = 1.0; - } - { - name = "easeInOutCubic"; - startX = 0.65; - startY = 0.05; - endX = 0.36; - endY = 1.0; - } - { - name = "linear"; - startX = 0.0; - startY = 0.0; - endX = 1.0; - endY = 1.0; - } - { - name = "almostLinear"; - startX = 0.5; - startY = 0.5; - endX = 0.75; - endY = 1.0; - } - { - name = "quick"; - startX = 0.15; - startY = 0.0; - endX = 0.1; - endY = 1.0; - } - ]; }; animations = mkOption { @@ -218,175 +101,59 @@ in { style = mkOption {type = types.str; default = "";}; }; }); - default = [ - { - name = "global"; - on = true; - speed = 10.0; - curve = "default"; - } - { - name = "border"; - on = true; - speed = 5.39; - curve = "easeOutQuint"; - } - { - name = "windows"; - on = true; - speed = 4.79; - curve = "easeOutQuint"; - } - { - name = "windowsIn"; - on = true; - speed = 4.1; - curve = "easeOutQuint"; - style = "popin 87%"; - } - { - name = "windowsOut"; - on = true; - speed = 1.49; - curve = "linear"; - style = "popin 87%"; - } - { - name = "fadeIn"; - on = true; - speed = 1.73; - curve = "almostLinear"; - } - { - name = "fadeOut"; - on = true; - speed = 1.46; - curve = "almostLinear"; - } - { - name = "fade"; - on = true; - speed = 3.03; - curve = "quick"; - } - { - name = "layers"; - on = true; - speed = 3.81; - curve = "easeOutQuint"; - } - { - name = "layersIn"; - on = true; - speed = 4.0; - curve = "easeOutQuint"; - style = "fade"; - } - { - name = "layersOut"; - on = true; - speed = 1.5; - curve = "linear"; - style = "fade"; - } - { - name = "fadeLayersIn"; - on = true; - speed = 1.79; - curve = "almostLinear"; - } - { - name = "fadeLayersOut"; - on = true; - speed = 1.39; - curve = "almostLinear"; - } - { - name = "workspaces"; - on = true; - speed = 1.94; - curve = "almostLinear"; - style = "fade"; - } - { - name = "workspacesIn"; - on = true; - speed = 1.21; - curve = "almostLinear"; - style = "fade"; - } - { - name = "workspacesOut"; - on = true; - speed = 1.94; - curve = "almostLinear"; - style = "fade"; - } - ]; }; }; dwindle = { pseudotile = mkOption { type = types.bool; - default = true; }; preserveSplit = mkOption { type = types.bool; - default = true; }; }; master = { newStatus = mkOption { type = types.enum ["master" "slave" "inherit"]; - default = "master"; }; }; misc = { forceDefaultWallpaper = mkOption { type = types.enum [ 0 1 2 (-1) ]; - default = 0; }; }; input = { kbLayout = mkOption { type = types.str; - default = "us"; }; repeatRate = mkOption { type = types.int; - default = 50; }; repeatDelay = mkOption { type = types.int; - default = 300; }; followMouse = mkOption { type = types.enum [ 0 1 2 3 ]; - default = 1; }; sensitivity = mkOption { type = types.numbers.between (-1.0) 1.0; - default = 0.0; }; numlockByDefault = mkOption { type = types.bool; - default = true; }; touchpad = { naturalScroll = mkOption { type = types.bool; - default = true; }; }; }; @@ -394,14 +161,12 @@ in { gestures = { workspaceSwipe = mkOption { type = types.bool; - default = false; }; }; monitors = { defaultMonitor = mkOption { type = types.bool; - default = true; }; displays = mkOption { @@ -419,10 +184,103 @@ in { }; }; - keybindings = { - + keybindings = mkOption { + type = types.listOf keybinding; }; }; }; }; + + config = { + system.activationScripts.script.text = '' + cd /home/horseman/.config + rm -r hypr/* + touch hypr/hyprland.conf + + printf "# This file has been auto-generated. + + ${builtins.concatStringsSep "\n" (map (x: "exec-once = " + x) cfg.config.execOnce)} + + ${builtins.concatStringsSep "\n" (map (x: "env = " + x) cfg.config.env)} + + general { + gaps_in = ${toString cfg.config.general.gapsIn} + gaps_out = ${toString cfg.config.general.gapsOut} + border_size = ${toString cfg.config.general.borderSize} + col.active_border = ${cfg.config.general.col.activeBorder} + col.inactive_border = ${cfg.config.general.col.inactiveBorder} + resize_on_border = ${trivial.boolToString cfg.config.general.resizeOnBorder} + allow_tearing = ${trivial.boolToString cfg.config.general.allowTearing} + layout = ${cfg.config.general.layout} + } + + decoration { + rounding = ${toString cfg.config.decoration.rounding} + + active_opacity = ${strings.floatToString cfg.config.decoration.activeOpacity} + inactive_opacity = ${strings.floatToString cfg.config.decoration.inactiveOpacity} + + shadow { + enabled = ${trivial.boolToString cfg.config.decoration.shadow.enabled} + range = ${toString cfg.config.decoration.shadow.range} + render_power = ${toString cfg.config.decoration.shadow.renderPower} + color = ${cfg.config.decoration.shadow.color} + } + + blur { + enabled = ${trivial.boolToString cfg.config.decoration.blur.enabled} + size = ${toString cfg.config.decoration.blur.size} + passes = ${toString cfg.config.decoration.blur.passes} + vibrancy = ${strings.floatToString cfg.config.decoration.blur.vibrancy} + } + } + + animations { + enabled = ${trivial.boolToString cfg.config.animations.enabled} + + ${builtins.concatStringsSep "\n " (map(bez: "bezier = ${bez.name}, ${strings.floatToString bez.startX}, ${strings.floatToString bez.startY}, ${strings.floatToString bez.endX}, ${strings.floatToString bez.endY}") cfg.config.animations.beziers)} + + ${builtins.concatStringsSep "\n " (map(anim: "animation = ${anim.name}, ${toString anim.on}, ${strings.floatToString anim.speed}, ${anim.curve}, ${replaceStrings ["%"] ["%%"] anim.style}") cfg.config.animations.animations)} + } + + dwindle { + pseudotile = ${trivial.boolToString cfg.config.dwindle.pseudotile} + preserve_split = ${trivial.boolToString cfg.config.dwindle.preserveSplit} + } + + master { + new_status = ${cfg.config.master.newStatus} + } + + misc { + force_default_wallpaper = ${toString cfg.config.misc.forceDefaultWallpaper} + } + + input { + kb_layout = ${cfg.config.input.kbLayout} + repeat_rate = ${toString cfg.config.input.repeatRate} + repeat_delay = ${toString cfg.config.input.repeatDelay} + follow_mouse = ${toString cfg.config.input.followMouse} + sensitivity = ${strings.floatToString cfg.config.input.sensitivity} + numlock_by_default = ${trivial.boolToString cfg.config.input.numlockByDefault} + + touchpad { + natural_scroll = ${trivial.boolToString cfg.config.input.touchpad.naturalScroll} + } + } + + gestures { + workspace_swipe = ${trivial.boolToString cfg.config.gestures.workspaceSwipe} + } + + ${builtins.concatStringsSep "\n" (map (mon: "monitor = ${mon.output}, ${mon.resolution}@${mon.refreshRate}, ${toString mon.x}x${toString mon.y}, ${strings.floatToString mon.scale}, transform, ${toString mon.transform}") cfg.config.monitors.displays)} + + ${if cfg.config.monitors.defaultMonitor then "monitor = ,preferred, auto, auto" else ""} + + ${builtins.concatStringsSep "\n" (map (ws: "workspace = " + ws) cfg.config.workspaces)} + + ${builtins.concatStringsSep "\n" (map (wr: "windowrule = " + replaceStrings ["%"] ["%%"] wr) cfg.config.windowrules)} + " >> hypr/hyprland.conf + ''; + }; }