From 444186a0df6d4a1a89b59f318a748dd09f62ed67 Mon Sep 17 00:00:00 2001 From: KoenDR06 Date: Tue, 15 Jul 2025 17:35:38 +0200 Subject: [PATCH] hyprnix but I made it (and it hopefully works) --- machines/terra/modules.nix | 4 +- modules/wm/hyprland/default.nix | 96 +++++++- modules/wm/hyprland/options.nix | 405 ++++++++++++++++++++++++++++++++ 3 files changed, 495 insertions(+), 10 deletions(-) create mode 100644 modules/wm/hyprland/options.nix diff --git a/machines/terra/modules.nix b/machines/terra/modules.nix index 5fd7c6f..c892856 100644 --- a/machines/terra/modules.nix +++ b/machines/terra/modules.nix @@ -24,8 +24,8 @@ refind.enable = true; }; - wm = { - hyprland.enable = true; + wm.hyprland = { + enable = true; }; hardware = { diff --git a/modules/wm/hyprland/default.nix b/modules/wm/hyprland/default.nix index 320180b..e2cda6a 100644 --- a/modules/wm/hyprland/default.nix +++ b/modules/wm/hyprland/default.nix @@ -6,14 +6,12 @@ pkgs, ... }: let - inherit (lib) mkEnableOption mkIf mkOption types; + inherit (lib) mkIf trivial strings replaceStrings; cfg = config.horseman.wm.hyprland; in { - options = { - horseman.wm.hyprland = { - enable = mkEnableOption "HyprLand"; - }; - }; + imports = [ + ./options.nix + ]; config = mkIf cfg.enable { programs.hyprland = { @@ -48,8 +46,90 @@ in { ''; system.activationScripts.script.text = '' - cd /home/horseman; - cp -r nix-config/modules/wm/hyprland/config/* .config; + 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 (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 new file mode 100644 index 0000000..0b1fda5 --- /dev/null +++ b/modules/wm/hyprland/options.nix @@ -0,0 +1,405 @@ +{ + lib, + ... +}: let + inherit (lib) mkEnableOption mkOption types; +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" + ]; + }; + + 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"; + }; + }; + + decoration = { + rounding = mkOption { + type = types.int; + default = 10; + }; + + activeOpacity = mkOption { + type = types.float; + default = 1.0; + }; + + inactiveOpacity = mkOption { + type = types.float; + default = 1.0; + }; + + 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)"; + }; + }; + + 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; + }; + }; + }; + + animations = { + enabled = mkOption { + type = types.bool; + default = true; + }; + + beziers = mkOption { + type = types.listOf (types.submodule { + options = { + name = mkOption {type = types.str;}; + startX = mkOption {type = types.number;}; + startY = mkOption {type = types.number;}; + endX = mkOption {type = types.number;}; + 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 { + type = types.listOf (types.submodule { + options = { + name = mkOption {type = types.str;}; + on = mkOption {type = types.bool;}; + speed = mkOption {type = types.number; default = 0;}; + curve = mkOption {type = types.str; default = "";}; + 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; + }; + }; + }; + + gestures = { + workspaceSwipe = mkOption { + type = types.bool; + default = false; + }; + }; + + + }; + }; + }; +}