diff --git a/lib/default.nix b/lib/default.nix index c2085d74..e399bb03 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -3,15 +3,15 @@ inputs, }: let flake = import ./flake inputs; + hypr = import ./hypr inputs.nixpkgs.lib; strings = import ./strings inputs.nixpkgs.lib; - lib = flake // strings; + lib = flake // hypr // strings; in # Expose main attrs lib # Expose all funcs - // strings - // flake + // {inherit flake hypr strings;} # Expose funcs that require pkgs // perSystem ( pkgs: diff --git a/lib/hypr/default.nix b/lib/hypr/default.nix new file mode 100644 index 00000000..34cecbab --- /dev/null +++ b/lib/hypr/default.nix @@ -0,0 +1,57 @@ +{ + concatStringsSep, + elemAt, + optionals, + ... +}: rec { + pointToStr = p: "${toString (elemAt p 0)}, ${toString (elemAt p 1)}"; + + mkBezier = { + name, + p0, + p1, + }: + concatStringsSep "," [name (pointToStr p0) (pointToStr p1)]; + + mkAnimation = { + name, + enable ? true, + duration ? 0, # in ds (100ms) + bezier ? "default", + style ? null, + }: + concatStringsSep "," ( + [ + name + ( + if enable + then "1" + else "0" + ) + ] + ++ optionals enable ( + [ + (toString duration) + bezier + ] + ++ optionals (style != null) [style] + ) + ); + + mkLayerRule = { + rule, + namespace, + }: + concatStringsSep "," [rule namespace]; + + mkBind = { + modifier ? "", + key, + dispatcher ? "exec", + command ? null, + }: + concatStringsSep "," ( + [modifier key dispatcher] + ++ optionals (command != null) [command] + ); +} diff --git a/lib/strings/default.nix b/lib/strings/default.nix index 77c26df5..884c3663 100644 --- a/lib/strings/default.nix +++ b/lib/strings/default.nix @@ -1,5 +1,5 @@ { - concatStringsSep, + concatStrings, stringToCharacters, substring, tail, @@ -7,5 +7,5 @@ ... }: { mkVersion = src: "0.0.0+" + src.shortRev; - capitalise = str: (toUpper (substring 0 1 str) + (concatStringsSep "" (tail (stringToCharacters str)))); + capitalise = str: (toUpper (substring 0 1 str) + (concatStrings (tail (stringToCharacters str)))); } diff --git a/nixosModules/ags/default.nix b/nixosModules/ags/default.nix index 617fd262..b9ab1750 100644 --- a/nixosModules/ags/default.nix +++ b/nixosModules/ags/default.nix @@ -53,7 +53,7 @@ in { home-manager.users.${cfgDesktop.user}.imports = [ hmOpts (import ./packages.nix self) - ./hyprland.nix + (import ./hyprland.nix self) ]; }; diff --git a/nixosModules/ags/hyprland.nix b/nixosModules/ags/hyprland.nix index bb9716d9..75fd022b 100644 --- a/nixosModules/ags/hyprland.nix +++ b/nixosModules/ags/hyprland.nix @@ -1,5 +1,8 @@ -{...}: { - wayland.windowManager.hyprland = { +self: {lib, ...}: let + inherit (lib) map; + inherit (self.lib.hypr) mkAnimation mkBezier mkBind mkLayerRule; +in { + config.wayland.windowManager.hyprland = { settings = { general = { gaps_in = 5; @@ -22,35 +25,95 @@ animations = { enabled = true; - bezier = [ - "easeInQuart , 0.895, 0.03, 0.685, 0.22" - "easeOutQuart , 0.165, 0.84, 0.44 , 1" - "easeInOutQuart, 0.77, 0 , 0.175, 1" + bezier = map mkBezier [ + { + name = "easeInQuart"; + p0 = [0.895 0.030]; + p1 = [0.685 0.220]; + } + { + name = "easeOutQuart"; + p0 = [0.165 0.840]; + p1 = [0.440 1.000]; + } + { + name = "easeInOutQuart"; + p0 = [0.770 0.000]; + p1 = [0.175 1.000]; + } - # Fade out - "easeInExpo , 0.95, 0.05, 0.795, 0.035" + # fade out + { + name = "easeInExpo"; + p0 = [0.950 0.050]; + p1 = [0.795 0.035]; + } ]; - animation = [ - "workspaces, 1, 6, easeOutQuart, slide" + animation = map mkAnimation [ + { + name = "workspaces"; + duration = 6; + bezier = "easeOutQuart"; + style = "slide"; + } - "windows, 1, 4, easeOutQuart, slide" - "fadeIn , 0" - "fadeOut, 1, 3000, easeInExpo" + { + name = "windows"; + duration = 4; + bezier = "easeOutQuart"; + style = "slide"; + } + { + name = "fadeIn"; + enable = false; + } + { + name = "fadeOut"; + duration = 4; + bezier = "easeInExpo"; + } - "fadeLayersIn , 0" - "fadeLayersOut, 1, 3000, easeInExpo" - "layers , 1, 4 , easeInOutQuart, slide left" + { + name = "fadeLayersIn"; + enable = false; + } + { + name = "fadeLayersOut"; + duration = 4; + bezier = "easeInExpo"; + } + { + name = "layers"; + duration = 4; + bezier = "easeInOutQuart"; + style = "fade"; + } ]; }; - layerrule = [ - "animation popin, ^(hyprpaper.*)" - "animation fade, ^(bg-layer.*)" + layerrule = map mkLayerRule [ + { + rule = "animation popin"; + namespace = "^(hyprpaper.*)"; + } + { + rule = "animation fade"; + namespace = "^(bg-layer.*)"; + } + { + rule = "noanim"; + namespace = "^(noanim-.*)"; + } - # Lockscreen blur - "blur, ^(blur-bg.*)" - "ignorealpha 0.19, ^(blur-bg.*)" + { + rule = "blur"; + namespace = "^(blur-bg.*)"; + } + { + rule = "ignorealpha 0.19"; + namespace = "^(blur-bg.*)"; + } ]; exec-once = [ @@ -58,23 +121,79 @@ "sleep 3; ags request 'open win-applauncher'" ]; - bind = [ - "$mainMod SHIFT, E , exec, ags toggle win-powermenu" - "$mainMod , D , exec, ags toggle win-applauncher" - "$mainMod , V , exec, ags toggle win-clipboard" - " , Print, exec, ags toggle win-screenshot" - ]; - binde = [ - ## Brightness control - ", XF86MonBrightnessUp , exec, ags request 'Brightness.screen +0.05'" - ", XF86MonBrightnessDown, exec, ags request 'Brightness.screen -0.05'" + bind = map mkBind [ + { + modifier = "$mainMod SHIFT"; + key = "E"; + command = "ags toggle win-powermenu"; + } + { + modifier = "$mainMod"; + key = "D"; + command = "ags toggle win-applauncher"; + } + { + modifier = "$mainMod"; + key = "V"; + command = "ags toggle win-clipboard"; + } + { + key = "Print"; + command = "ags toggle win-screenshot"; + } - ## Volume control - ", XF86AudioRaiseVolume , exec, wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ & ags request 'popup speaker' &" - ", XF86AudioLowerVolume , exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- & ags request 'popup speaker' &" + { + key = "XF86AudioMute"; + command = "pactl set-sink-mute @DEFAULT_SINK@ toggle"; + } + { + key = "XF86AudioMicMute"; + command = "pactl set-source-mute @DEFAULT_SOURCE@ toggle"; + } + { + modifier = "$mainMod"; + key = "Print"; + command = "bash -c \"grim -g \\\"$(slurp)\\\" - | satty -f -\""; + } + ]; + + binde = map mkBind [ + { + key = "XF86MonBrightnessUp"; + command = "ags request 'Brightness.screen +0.05'"; + } + { + key = "XF86MonBrightnessDown"; + command = "ags request 'Brightness.screen -0.05'"; + } + + { + key = "XF86AudioRaiseVolume"; + command = "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+ & ags request 'popup speaker' &"; + } + { + key = "XF86AudioLowerVolume"; + command = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%- & ags request 'popup speaker' &"; + } + ]; + + bindn = map mkBind [ + { + key = "Escape"; + command = "ags request closeAll"; + } + ]; + + bindr = map mkBind [ + { + modifier = "CAPS"; + key = "Caps_Lock"; + command = "ags request fetchCapsState"; + } ]; - bindn = [" , Escape , exec, ags request closeAll"]; - bindr = ["CAPS, Caps_Lock, exec, ags request fetchCapsState"]; }; }; + + # For accurate stack trace + _file = ./default.nix; } diff --git a/nixosModules/desktop/environment/default.nix b/nixosModules/desktop/environment/default.nix index b232ef0c..e6a23edb 100644 --- a/nixosModules/desktop/environment/default.nix +++ b/nixosModules/desktop/environment/default.nix @@ -4,17 +4,18 @@ self: { pkgs, ... }: let - inherit (self.inputs) hyprgrass hyprland hyprland-plugins; + inherit (self.inputs) hyprland; + inherit (self.lib.hypr) mkBind; in { imports = [ (import ../../ags self) ./modules/dconf.nix ./modules/printer.nix - ./modules/security.nix (import ./modules/audio.nix self) (import ./modules/packages.nix self) (import ./modules/ratbag-mice.nix self) + (import ./modules/security.nix self) ]; config = let @@ -73,10 +74,10 @@ in { ./home/dev.nix # Plugins - (import ./home/hyprexpo.nix hyprland-plugins) - (import ./home/hyprgrass.nix hyprgrass) + (import ./home/hyprexpo.nix self) + (import ./home/hyprgrass.nix self) - ./home/inputs.nix + (import ./home/inputs.nix self) (import ../theme self) ]; @@ -179,16 +180,20 @@ in { "$mainMod SHIFT, 8, movetoworkspace, 8" "$mainMod SHIFT, 9, movetoworkspace, 9" "$mainMod SHIFT, 0, movetoworkspace, 10" - - ",XF86AudioMute, exec, pactl set-sink-mute @DEFAULT_SINK@ toggle" - ",XF86AudioMicMute, exec, pactl set-source-mute @DEFAULT_SOURCE@ toggle" - "$mainMod, Print, exec, bash -c \"grim -g \\\"$(slurp)\\\" - | satty -f -\"" ]; # Mouse Binds - bindm = [ - "$mainMod, mouse:272, movewindow" - "$mainMod, mouse:273, resizewindow" + bindm = map mkBind [ + { + modifier = "$mainMod"; + key = "mouse:272"; + dispatcher = "movewindow"; + } + { + modifier = "$mainMod"; + key = "mouse:273"; + dispatcher = "resizewindow"; + } ]; misc = { diff --git a/nixosModules/desktop/environment/home/hyprexpo.nix b/nixosModules/desktop/environment/home/hyprexpo.nix index 4828e383..65dfb5ca 100644 --- a/nixosModules/desktop/environment/home/hyprexpo.nix +++ b/nixosModules/desktop/environment/home/hyprexpo.nix @@ -1,25 +1,30 @@ -hyprland-plugins: {pkgs, ...}: { +self: {pkgs, ...}: let + inherit (self.lib.hypr) mkBind; +in { config = { wayland.windowManager.hyprland = { - plugins = [hyprland-plugins.packages.${pkgs.system}.hyprexpo]; + plugins = [self.inputs.hyprland-plugins.packages.${pkgs.system}.hyprexpo]; settings = { - plugin = { - hyprexpo = { - columns = 3; - gap_size = 5; - bg_col = "rgb(111111)"; - workspace_method = "center current"; # [center/first] [workspace] e.g. first 1 or center m+1 + plugin.hyprexpo = { + columns = 3; + gap_size = 5; + bg_col = "rgb(111111)"; + workspace_method = "center current"; # [center/first] [workspace] e.g. first 1 or center m+1 - enable_gesture = true; # laptop touchpad - gesture_fingers = 3; - gesture_distance = 300; # how far is the "max" - gesture_positive = true; # positive = swipe down. Negative = swipe up. - }; + enable_gesture = true; # laptop touchpad + gesture_fingers = 3; + gesture_distance = 300; # how far is the "max" + gesture_positive = true; # positive = swipe down. Negative = swipe up. }; bind = [ - "ALT, tab, hyprexpo:expo, toggle" # can be: toggle, off/disable or on/enable + (mkBind { + modifier = "ALT"; + key = "tab"; + dispatcher = "hyprexpo:expo"; + command = "toggle"; # can be: toggle, off/disable or on/enable + }) ]; }; }; diff --git a/nixosModules/desktop/environment/home/hyprgrass.nix b/nixosModules/desktop/environment/home/hyprgrass.nix index 5ba3694c..92f8e41d 100644 --- a/nixosModules/desktop/environment/home/hyprgrass.nix +++ b/nixosModules/desktop/environment/home/hyprgrass.nix @@ -1,54 +1,65 @@ -hyprgrass: { +self: { lib, osConfig, pkgs, ... }: let - inherit (lib) mkIf; + inherit (lib) map mkIf; + inherit (self.lib.hypr) mkBind; cfg = osConfig.roles.desktop; in { config = mkIf cfg.isTouchscreen { wayland.windowManager.hyprland = { - plugins = [hyprgrass.packages.${pkgs.system}.default]; + plugins = [self.inputs.hyprgrass.packages.${pkgs.system}.default]; settings = { - plugin = { - touch_gestures = { - # The default sensitivity is probably too low on tablet screens, - # I recommend turning it up to 4.0 - sensitivity = 4.0; + plugin.touch_gestures = { + # The default sensitivity is probably too low on tablet screens, + # I recommend turning it up to 4.0 + sensitivity = 4.0; - # must be >= 3 - workspace_swipe_fingers = 3; + # must be >= 3 + workspace_swipe_fingers = 3; - # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers - # and can be used at the same time - # possible values: l, r, u, or d - # to disable it set it to anything else - # workspace_swipe_edge = "d"; + # switching workspaces by swiping from an edge, this is separate from workspace_swipe_fingers + # and can be used at the same time + # possible values: l, r, u, or d + # to disable it set it to anything else + # workspace_swipe_edge = "d"; - # in milliseconds - long_press_delay = 400; + # in milliseconds + long_press_delay = 400; - # resize windows by long-pressing on window borders and gaps. - # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating - # windows - resize_on_border_long_press = true; + # resize windows by long-pressing on window borders and gaps. + # If general:resize_on_border is enabled, general:extend_border_grab_area is used for floating + # windows + resize_on_border_long_press = true; - # in pixels, the distance from the edge that is considered an edge - edge_margin = 10; + # in pixels, the distance from the edge that is considered an edge + edge_margin = 10; - # send proper cancel events to windows instead of hacky touch_up events, - # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default - experimental.send_cancel = 0; + # send proper cancel events to windows instead of hacky touch_up events, + # NOT recommended as it crashed a few times, once it's stabilized I'll make it the default + experimental.send_cancel = 0; - hyprgrass-bind = [ - ", edge:u:d, exec, ags request 'open win-applauncher'" - ", edge:d:u, exec, ags request 'osk open'" - ]; - hyprgrass-bindm = [", longpress:2, movewindow"]; - }; + hyprgrass-bind = map mkBind [ + { + key = "edge:u:d"; + command = "ags request 'open win-applauncher'"; + } + { + key = "edge:d:u"; + command = "ags request 'osk open'"; + } + ]; + + hyprgrass-bindm = map mkBind [ + { + key = "longpress:2"; + dispatcher = "movewindow"; + } + ]; }; gestures = { diff --git a/nixosModules/desktop/environment/home/inputs.nix b/nixosModules/desktop/environment/home/inputs.nix index 39ac3eae..ae2a21c2 100644 --- a/nixosModules/desktop/environment/home/inputs.nix +++ b/nixosModules/desktop/environment/home/inputs.nix @@ -1,5 +1,12 @@ -{osConfig, ...}: { +self: { + osConfig, + lib, + ... +}: { config = let + inherit (lib) map; + inherit (self.lib.hypr) mkBind; + inherit (osConfig.services.xserver) xkb; inherit (osConfig.roles.desktop) mainMonitor; @@ -16,7 +23,7 @@ in { wayland.windowManager.hyprland = { settings = { - device = map (d: (mkConf d)) miceNames; + device = map mkConf miceNames; cursor = { no_hardware_cursors = osConfig.nvidia.enable; @@ -47,11 +54,23 @@ }; }; - bind = [ - ",XF86AudioPlay, exec, playerctl play-pause" - ",XF86AudioStop, exec, playerctl stop" - ",XF86AudioNext, exec, playerctl next" - ",XF86AudioPrev, exec, playerctl previous" + bind = map mkBind [ + { + key = "XF86AudioPlay"; + command = "playerctl play-pause"; + } + { + key = "XF86AudioStop"; + command = "playerctl stop"; + } + { + key = "XF86AudioNext"; + command = "playerctl next"; + } + { + key = "XF86AudioPrev"; + command = "playerctl previous"; + } ]; }; }; diff --git a/nixosModules/desktop/environment/modules/packages.nix b/nixosModules/desktop/environment/modules/packages.nix index 7148f0fe..e63445b0 100644 --- a/nixosModules/desktop/environment/modules/packages.nix +++ b/nixosModules/desktop/environment/modules/packages.nix @@ -4,12 +4,13 @@ self: { pkgs, ... }: let + inherit (self.lib.hypr) mkBind; inherit (self.inputs) jellyfin-flake; in { imports = [./dolphin.nix]; config = let - inherit (lib) getExe optionals; + inherit (lib) getExe map optionals; inherit (pkgs.writers) writeTOML; flakeDir = config.environment.variables.FLAKE; @@ -187,13 +188,31 @@ in { "workspace special:spot silent,^(Spotify)$" ]; - bind = [ - "$mainMod, Q, exec, foot" + bind = map mkBind [ + { + modifier = "$mainMod"; + key = "Q"; + command = "foot"; + } - "$mainMod SHIFT, C, exec, wl-color-picker" + { + modifier = "$mainMod SHIFT"; + key = "C"; + command = "wl-color-picker"; + } - "$mainMod, P, togglespecialworkspace, protonmail" - "$mainMod, S, togglespecialworkspace, spot" + { + modifier = "$mainMod"; + key = "P"; + dispatcher = "togglespecialworkspace"; + command = "protonmail"; + } + { + modifier = "$mainMod"; + key = "S"; + dispatcher = "togglespecialworkspace"; + command = "spot"; + } ]; }; }; diff --git a/nixosModules/desktop/environment/modules/security.nix b/nixosModules/desktop/environment/modules/security.nix index 9f2ebd03..5814ab87 100644 --- a/nixosModules/desktop/environment/modules/security.nix +++ b/nixosModules/desktop/environment/modules/security.nix @@ -1,11 +1,12 @@ -{ +self: { config, lib, pkgs, ... }: { config = let - inherit (lib) getExe mkIf; + inherit (self.lib.hypr) mkBind; + inherit (lib) getExe map mkIf; cfg = config.roles.desktop; @@ -71,27 +72,29 @@ lockPkg ]; - wayland.windowManager.hyprland = { - settings = { - exec-once = [ - "gnome-keyring-daemon --start --components=secrets" - "${pkgs.plasma5Packages.polkit-kde-agent}/libexec/polkit-kde-authentication-agent-1" - ]; + wayland.windowManager.hyprland.settings = { + exec-once = [ + "gnome-keyring-daemon --start --components=secrets" + "${pkgs.plasma5Packages.polkit-kde-agent}/libexec/polkit-kde-authentication-agent-1" + ]; - windowrule = [ - "float,^(org.kde.polkit-kde-authentication-agent-1)$" - "size 741 288,^(org.kde.polkit-kde-authentication-agent-1)$" - "center,^(org.kde.polkit-kde-authentication-agent-1)$" + windowrule = [ + "float,^(org.kde.polkit-kde-authentication-agent-1)$" + "size 741 288,^(org.kde.polkit-kde-authentication-agent-1)$" + "center,^(org.kde.polkit-kde-authentication-agent-1)$" - # For GParted auth - "size 741 288,^(org.kde.ksshaskpass)$" - "move cursor -370 -144,^(org.kde.ksshaskpass)$" - ]; + # For GParted auth + "size 741 288,^(org.kde.ksshaskpass)$" + "move cursor -370 -144,^(org.kde.ksshaskpass)$" + ]; - bind = [ - "$mainMod, L, exec, ${getExe lockPkg}" - ]; - }; + bind = map mkBind [ + { + modifier = "$mainMod"; + key = "L"; + command = getExe lockPkg; + } + ]; }; }; }; diff --git a/nixosModules/desktop/manager/hyprland.nix b/nixosModules/desktop/manager/hyprland.nix index 5d7fab3d..87aec19f 100644 --- a/nixosModules/desktop/manager/hyprland.nix +++ b/nixosModules/desktop/manager/hyprland.nix @@ -5,7 +5,8 @@ self: { ... }: { config = let - inherit (lib) filterAttrs hasPrefix optionals; + inherit (lib) optionals; + inherit (self.lib.hypr) mkAnimation; inherit (import ./setupMonitors.nix {inherit config pkgs;}) setupMonitors; @@ -20,8 +21,6 @@ self: { .wayland .windowManager .hyprland; - - devices = filterAttrs (n: v: hasPrefix "device:" n) cfgHypr.settings; in { home-manager.users.greeter = { imports = [ @@ -30,39 +29,45 @@ self: { wayland.windowManager.hyprland = { enable = true; - package = cfgHypr.finalPackage; systemd.enable = false; - settings = - { - inherit (cfgHypr.settings) cursor input misc monitor; + package = cfgHypr.finalPackage; - envd = optionals (config.nvidia.enable) [ - "LIBVA_DRIVER_NAME, nvidia" - "NVD_BACKEND, direct" - "XDG_SESSION_TYPE, wayland" - "GBM_BACKEND, nvidia-drm" - "__GLX_VENDOR_LIBRARY_NAME, nvidia" - ]; + settings = { + inherit (cfgHypr.settings) cursor device input misc monitor; - general.border_size = 0; + envd = optionals (config.nvidia.enable) [ + "LIBVA_DRIVER_NAME, nvidia" + "NVD_BACKEND, direct" + "XDG_SESSION_TYPE, wayland" + "GBM_BACKEND, nvidia-drm" + "__GLX_VENDOR_LIBRARY_NAME, nvidia" + ]; - decoration = { - blur.enabled = false; - shadow.enabled = false; - }; + general.border_size = 0; - animation = [ - "fadeLayersIn, 0" - "layers, 1, 4, default, popin 0%" - ]; + decoration = { + blur.enabled = false; + shadow.enabled = false; + }; - exec-once = [ - setupMonitors - "agsGreeter &> /tmp/ags-greetd.log; hyprctl dispatch exit" - ]; - } - // devices; + animation = map mkAnimation [ + { + name = "fadeLayersIn"; + enable = false; + } + { + name = "layers"; + duration = 4; + style = "popin"; + } + ]; + + exec-once = [ + setupMonitors + "agsGreeter &> /tmp/ags-greetd.log; hyprctl dispatch exit" + ]; + }; }; }; }; diff --git a/nixosModules/desktop/theme/cursors.nix b/nixosModules/desktop/theme/cursors.nix index 20b62b50..1c323631 100644 --- a/nixosModules/desktop/theme/cursors.nix +++ b/nixosModules/desktop/theme/cursors.nix @@ -22,17 +22,15 @@ self: {pkgs, ...}: { home.file.".local/share/icons/${hyprcursorThemeName}".source = cursorTheme; - wayland.windowManager.hyprland = { - settings = { - envd = [ - "XCURSOR_THEME, ${cursorThemeName}" - "XCURSOR_SIZE, ${toString cursorSize}" - ]; + wayland.windowManager.hyprland.settings = { + envd = [ + "XCURSOR_THEME, ${cursorThemeName}" + "XCURSOR_SIZE, ${toString cursorSize}" + ]; - exec-once = [ - "hyprctl setcursor ${hyprcursorThemeName} ${toString cursorSize}" - ]; - }; + exec-once = [ + "hyprctl setcursor ${hyprcursorThemeName} ${toString cursorSize}" + ]; }; };