dotfiles

My PC Dotfiles & Website
commit ad471330e3ae3c05b1f6b62ed4640ed42d53432e
parent b3eaefc3f61713160e93edd4f4e9a5f3e70cae8e
Author: maydayv7 <maydayv7@gmail.com>
Date:   Sat, 20 Jun 2026 15:08:21 +0530

feat(Hyprland): LUA

Diffstat:
MCHANGELOG.md | 1+
Mflake.lock | 168++++++++++++++++---------------------------------------------------------------
Mflake.nix | 17+++++------------
Mmodules/desktop/hyprland/_features/shell.nix | 9+++++----
Amodules/desktop/hyprland/_settings/_lib.nix | 20++++++++++++++++++++
Mmodules/desktop/hyprland/_settings/apps.nix | 243++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
Mmodules/desktop/hyprland/_settings/keybinds.nix | 368+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mmodules/desktop/hyprland/_settings/main.nix | 465+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mmodules/desktop/hyprland/_settings/plugins.nix | 62+++++++++++++++++++++++++++++++-------------------------------
Mmodules/hosts/valkyrie/_settings/default.nix | 25++++++++++++++++---------
Mmodules/system/base-ext.nix | 11+----------
Mmodules/system/boot.nix | 1-
Mmodules/system/nix.nix | 7++++++-
Mpackages/_module.nix | 1-
Dpackages/hyprshellevents/default.nix | 41-----------------------------------------
Dpackages/hyprshellevents/metadata.nix | 5-----
Mscripts/hyprutils.nix | 41++++++++---------------------------------
17 files changed, 772 insertions(+), 713 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -2,6 +2,7 @@ ### June +- Migrate Hyprland config to Lua - Use Noctalia Shell & Greeter (v5) with Hyprland - Per-user secrets - Use `zellij` instead of `tmux` diff --git a/flake.lock b/flake.lock @@ -294,22 +294,6 @@ "flake-compat_3": { "flake": false, "locked": { - "lastModified": 1767039857, - "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", - "owner": "NixOS", - "repo": "flake-compat", - "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "flake-compat", - "type": "github" - } - }, - "flake-compat_4": { - "flake": false, - "locked": { "lastModified": 1747046372, "narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=", "owner": "edolstra", @@ -323,7 +307,7 @@ "type": "github" } }, - "flake-compat_5": { + "flake-compat_4": { "locked": { "lastModified": 1733328505, "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", @@ -337,7 +321,7 @@ "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" } }, - "flake-compat_6": { + "flake-compat_5": { "flake": false, "locked": { "lastModified": 1777728799, @@ -425,51 +409,6 @@ "type": "github" } }, - "gaming": { - "inputs": { - "flake-parts": [ - "flake-parts" - ], - "git-hooks": "git-hooks", - "nixpkgs": "nixpkgs" - }, - "locked": { - "lastModified": 1781064751, - "narHash": "sha256-KLhF1KXXGNFXQBLEZWoeMSbxHimMTYZfEilMs6azeY4=", - "owner": "fufexan", - "repo": "nix-gaming", - "rev": "7149d77f66536aaf02c845a9c2a08eb7e57a04c3", - "type": "github" - }, - "original": { - "owner": "fufexan", - "repo": "nix-gaming", - "type": "github" - } - }, - "git-hooks": { - "inputs": { - "flake-compat": "flake-compat_2", - "gitignore": "gitignore_2", - "nixpkgs": [ - "gaming", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1778507602, - "narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=", - "owner": "cachix", - "repo": "git-hooks.nix", - "rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "git-hooks.nix", - "type": "github" - } - }, "gitignore": { "inputs": { "nixpkgs": [ @@ -495,28 +434,6 @@ "gitignore_2": { "inputs": { "nixpkgs": [ - "gaming", - "git-hooks", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "gitignore_3": { - "inputs": { - "nixpkgs": [ "hyprland", "hyprland", "pre-commit-hooks", @@ -556,7 +473,7 @@ }, "hardware": { "inputs": { - "nixpkgs": "nixpkgs_2" + "nixpkgs": "nixpkgs" }, "locked": { "lastModified": 1781168557, @@ -1323,22 +1240,22 @@ "hyprland": [ "hyprland" ], - "nix-filter": [ - "filters" + "nixpkgs": [ + "nixpkgs" ] }, "locked": { - "lastModified": 1780344895, - "narHash": "sha256-jnCF4+i/WITrySyR8U3yklZpijtZmjACoV7GVG8RnKc=", - "owner": "zjeffer", - "repo": "split-monitor-workspaces", - "rev": "6cff8cfffecf4729d1f5bacf82d96c5987f230f3", + "lastModified": 1781205112, + "narHash": "sha256-PaoUtmk+qIP/ESdxkxnY7mUMpMHjix88qu22R5GLQqE=", + "owner": "shezdy", + "repo": "hyprsplit", + "rev": "6b00b677d8905fb38779c91e12d6294e0e586a44", "type": "github" }, "original": { - "owner": "zjeffer", - "ref": "v0.55.4", - "repo": "split-monitor-workspaces", + "owner": "shezdy", + "repo": "hyprsplit", + "rev": "6b00b677d8905fb38779c91e12d6294e0e586a44", "type": "github" } }, @@ -1630,7 +1547,7 @@ }, "minecraft": { "inputs": { - "flake-compat": "flake-compat_4", + "flake-compat": "flake-compat_3", "nixpkgs": [ "nixpkgs" ], @@ -1654,7 +1571,7 @@ }, "nixcord": { "inputs": { - "flake-compat": "flake-compat_5", + "flake-compat": "flake-compat_4", "flake-parts": [ "flake-parts" ], @@ -1679,18 +1596,15 @@ }, "nixpkgs": { "locked": { - "lastModified": 1780747962, - "narHash": "sha256-IX7G1dlKrOqPOImfbo7ADDfV5yU1+j+MRChI3TL4tAA=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "cbb5cf358f50aa6acc9efd6113b7bcfbc352cd73", - "type": "github" + "lastModified": 1767892417, + "narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=", + "rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba", + "type": "tarball", + "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz" }, "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" + "type": "tarball", + "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" } }, "nixpkgs-nixcord": { @@ -1709,19 +1623,6 @@ "type": "github" } }, - "nixpkgs_2": { - "locked": { - "lastModified": 1767892417, - "narHash": "sha256-8bW3q88CEg2u4hSP66Vf4lpbLonHz7hqDNBMcCY7E9U=", - "rev": "3497aa5c9457a9d88d71fa93a4a8368816fbeeba", - "type": "tarball", - "url": "https://releases.nixos.org/nixos/unstable/nixos-26.05pre924538.3497aa5c9457/nixexprs.tar.xz" - }, - "original": { - "type": "tarball", - "url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz" - } - }, "noctalia": { "inputs": { "nixpkgs": [ @@ -1729,11 +1630,11 @@ ] }, "locked": { - "lastModified": 1781888265, - "narHash": "sha256-J+sVIVJ1Uhx2ugZnRqZD75NP0Go78tkupBRlkpC3Ppg=", + "lastModified": 1781935716, + "narHash": "sha256-mlj1OYbT2vMzVYSz8BL+GA7OHbMYmD5yPfjBEjszjKA=", "owner": "noctalia-dev", "repo": "noctalia", - "rev": "e0100eeb6e2fe67b4173a5e555f7901162a2aba2", + "rev": "fd19cec65c33f8da303c02c66445c996721ee205", "type": "github" }, "original": { @@ -1812,8 +1713,8 @@ }, "pre-commit-hooks": { "inputs": { - "flake-compat": "flake-compat_3", - "gitignore": "gitignore_3", + "flake-compat": "flake-compat_2", + "gitignore": "gitignore_2", "nixpkgs": [ "hyprland", "hyprland", @@ -1863,7 +1764,6 @@ "flake-parts": "flake-parts", "flatpak": "flatpak", "formatter": "formatter", - "gaming": "gaming", "hardware": "hardware", "home-manager": "home-manager", "hyprcursors": "hyprcursors", @@ -1958,11 +1858,11 @@ }, "stable": { "locked": { - "lastModified": 1780902259, - "narHash": "sha256-q8yYEC5f1mFlQO9RGna4LTc9QrcvWunX6FYp83munkQ=", + "lastModified": 1781216227, + "narHash": "sha256-9mUW6gNwoN2SWc/l0fW4svPNOulXLl8ijqKyeSOGgJE=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bd0ff2d3eac24699c3664d5966b9ef36f388e2ca", + "rev": "a0374025a863d007d98e3297f6aa46cc3141c2f0", "type": "github" }, "original": { @@ -2131,11 +2031,11 @@ }, "unstable": { "locked": { - "lastModified": 1781074563, - "narHash": "sha256-md8WlXOlfnIeHeOScMTTHFyf2d6iaTwPl2apR5EQ3P4=", + "lastModified": 1781577229, + "narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9ae611a455b90cf061d8f332b977e387bda8e1ca", + "rev": "567a49d1913ce81ac6e9582e3553dd90a955875f", "type": "github" }, "original": { @@ -2205,7 +2105,7 @@ }, "windows": { "inputs": { - "flake-compat": "flake-compat_6", + "flake-compat": "flake-compat_5", "nixpkgs": [ "unstable" ] diff --git a/flake.nix b/flake.nix @@ -41,12 +41,6 @@ # Unstable Packages Repository unstable.url = "github:NixOS/nixpkgs?ref=nixos-unstable"; - # Packaged Games - gaming = { - url = "github:fufexan/nix-gaming"; - inputs.flake-parts.follows = "flake-parts"; - }; - # Proprietary Software proprietary = { url = "github:maydayv7/proprietary"; @@ -202,10 +196,10 @@ # Plugins hyprsplit = { - url = "github:zjeffer/split-monitor-workspaces/v0.55.4"; + url = "github:shezdy/hyprsplit/6b00b677d8905fb38779c91e12d6294e0e586a44"; inputs = { hyprland.follows = "hyprland"; - nix-filter.follows = "filters"; + nixpkgs.follows = "nixpkgs"; }; }; @@ -245,20 +239,20 @@ }; ## Nix Configuration ## - nixConfig = { + nixConfig = rec { commit-lockfile-summary = "chore(flake): Update `inputs`"; # Binary Caches - trusted-substituters = [ + substituters = [ "https://maydayv7-dotfiles.cachix.org" "https://cache.nixos.org" "https://nixpkgs-unfree.cachix.org" "https://nix-community.cachix.org" "https://cache.flox.dev" - "https://nix-gaming.cachix.org" "https://hyprland.cachix.org" "https://catppuccin.cachix.org" ]; + trusted-substituters = substituters; # Public Keys trusted-public-keys = [ @@ -267,7 +261,6 @@ "nixpkgs-unfree.cachix.org-1:hqvoInulhbV4nJ9yJOEr+4wxhDV4xq2d1DK7S6Nj6rs=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" "flox-cache-public-1:7F4OyH7ZCnFhcze3fJdfyXYLQw/aV7GEed86nQ7IsOs=" - "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4=" "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" "catppuccin.cachix.org-1:noG/4HkbhJb+lUAdKrph6LaozJvAeEEZj4N732IysmU=" ]; diff --git a/modules/desktop/hyprland/_features/shell.nix b/modules/desktop/hyprland/_features/shell.nix @@ -100,7 +100,7 @@ type = "custom_button"; glyph = "arrow-bar-to-down"; tooltip = "Minimize window"; - command = "hyprctl dispatch movetoworkspacesilent special:minimized"; + command = ''hyprctl dispatch 'hl.dsp.window.move({ workspace = "special:minimized", follow = false })' ''; right_command = "hyprutils toggle minimized"; }; }; @@ -148,8 +148,9 @@ # Wallpaper wallpaper = { - enabled = false; - default.path = "${osConfig.stylix.image}"; + enabled = true; + fill_mode = "crop"; + default.path = osConfig.stylix.image; }; # Desktop Widgets @@ -304,7 +305,7 @@ { name = "local"; kind = "path"; - location = "${files.hyprland.noctalia}"; + location = files.hyprland.noctalia; } ]; enabled = [ diff --git a/modules/desktop/hyprland/_settings/_lib.nix b/modules/desktop/hyprland/_settings/_lib.nix @@ -0,0 +1,20 @@ +# Lua Config Helpers +lib: let + inherit (lib) concatStringsSep; + inline = lib.generators.mkLuaInline; +in rec { + inherit inline; + + combo = mods: key: + if mods == [] + then key + else concatStringsSep " + " (mods ++ [key]); + + exec = cmd: ''hl.dsp.exec_cmd("${cmd}")''; + bind = keys: disp: {_args = [keys (inline disp)];}; + bindOpts = keys: disp: opts: {_args = [keys (inline disp) opts];}; + env = k: v: {_args = [k v];}; + permission = re: type: act: {_args = [re type act];}; + on = event: fn: {_args = [event (inline fn)];}; + curve = name: spec: {_args = [name spec];}; +} diff --git a/modules/desktop/hyprland/_settings/apps.nix b/modules/desktop/hyprland/_settings/apps.nix @@ -8,144 +8,209 @@ _: { lib.mkIf (osConfig != null) ( let inherit (builtins) map toString; - inherit (lib) flatten getExe head splitString; + inherit (lib) concatStringsSep getExe head splitString; + + lua = import ./_lib.nix lib; + inherit (lua) combo bind exec env on permission; inherit (osConfig.gui) display; inherit (config.stylix) cursor; hyprcursor = "${cursor.name}-Hyprcursor"; + mod = "SUPER"; + unit = command: head (splitString " " command); + toggle = app: "pkill ${app} || uwsm app -u ${app}.scope -- ${app}"; + runOnce = app: "pgrep ${app} || uwsm app -u ${app}.scope -- ${app}"; in { ## App Environment # Cursor xdg.dataFile."icons/${hyprcursor}".source = "${cursor.package}/share/icons/${hyprcursor}"; wayland.windowManager.hyprland.settings = { env = [ - "HYPRCURSOR_THEME, ${hyprcursor}" - "HYPRCURSOR_SIZE, ${toString cursor.size}" + (env "HYPRCURSOR_THEME" hyprcursor) + (env "HYPRCURSOR_SIZE" (toString cursor.size)) # QT Apps - "QT_WAYLAND_DISABLE_WINDOWDECORATION, 1" + (env "QT_WAYLAND_DISABLE_WINDOWDECORATION" "1") ]; - # Window Swallowing - misc.swallow_regex = "^(kitty)$"; - ## Autostart - exec-once = - [ - "uwsm finalize" - "hyprctl setcursor ${hyprcursor} ${toString cursor.size}" - ] - ++ (map (app: "uwsm app -t service -u ${unit app}.service -- " + app) [ - "hyprutils daemon" - - # Pyprland - "pypr" - - # Desktop Icons - "pcmanfm-qt --desktop" - ]); + on = [ + (on "hyprland.start" ("function() " + + concatStringsSep " " (map (c: ''hl.exec_cmd("${c}");'') ([ + "uwsm finalize" + "hyprctl setcursor ${hyprcursor} ${toString cursor.size}" + ] + ++ (map (app: "uwsm app -t service -u ${unit app}.service -- ${app}") [ + # Pyprland + "pypr" + + # Desktop Icons + "pcmanfm-qt --desktop" + ]))) + + " end")) + ]; ## Shortcuts - bind = let - toggle = app: "pkill ${app} || uwsm app -u ${app}.scope -- ${app}"; - runOnce = app: "pgrep ${app} || uwsm app -u ${app}.scope -- ${app}"; - in [ + bind = [ # Applications - "$mod, F, exec, nemo" - "$mod, T, exec, kitty" - "$mod, W, exec, firefox" - "$mod, Return, exec, ${runOnce "resources"}" - "$mod SHIFT, equal, exec, pypr toggle calc" - ", XF86Calculator, exec, qalculate-gtk" + (bind (combo [mod] "F") (exec "nemo")) + (bind (combo [mod] "T") (exec "kitty")) + (bind (combo [mod] "W") (exec "firefox")) + (bind (combo [mod] "Return") (exec (runOnce "resources"))) + (bind (combo [mod "SHIFT"] "equal") (exec "pypr toggle calc")) + (bind (combo [] "XF86Calculator") (exec "qalculate-gtk")) # Utilities - "$mod, A, exec, noctalia msg panel-toggle launcher" - "$mod, slash, exec, ${toggle "kebihelp"} show -a" - "$mod SHIFT, C, exec, ${runOnce "hyprpicker"} -arf hex" - "$mod SHIFT, B, exec, ${runOnce "overskride"}" - "$mod, D, exec, ${runOnce "nwg-displays"}" - "$mod SHIFT, P, exec, pwvucontrol" - "$mod SHIFT, N, exec, sh -c 'env XDG_CURRENT_DESKTOP=GNOME gnome-control-center wifi'" - "$mod, Escape, exec, noctalia msg panel-toggle session" + (bind (combo [mod] "A") (exec "noctalia msg panel-toggle launcher")) + (bind (combo [mod] "slash") (exec "${toggle "kebihelp"} show -a")) + (bind (combo [mod "SHIFT"] "C") (exec "${runOnce "hyprpicker"} -arf hex")) + (bind (combo [mod "SHIFT"] "B") (exec (runOnce "overskride"))) + (bind (combo [mod] "D") (exec (runOnce "nwg-displays"))) + (bind (combo [mod "SHIFT"] "P") (exec "pwvucontrol")) + (bind (combo [mod "SHIFT"] "N") (exec "sh -c 'env XDG_CURRENT_DESKTOP=GNOME gnome-control-center wifi'")) + (bind (combo [mod] "Escape") (exec "noctalia msg panel-toggle session")) # Shell - "$mod SHIFT, A, exec, noctalia msg settings-toggle" - "$mod, Tab, exec, noctalia msg window-switcher" - "$mod, N, exec, noctalia msg panel-toggle notifications" - "$mod, V, exec, noctalia msg panel-toggle clipboard" + (bind (combo [mod "SHIFT"] "A") (exec "noctalia msg settings-toggle")) + (bind (combo [mod] "Tab") (exec "noctalia msg window-switcher")) + (bind (combo [mod] "N") (exec "noctalia msg panel-toggle notifications")) + (bind (combo [mod] "V") (exec "noctalia msg panel-toggle clipboard")) # Tools - "$mod, G, exec, pypr gamemode" - "$mod SHIFT, D, exec, hyprutils toggle monitor ${display}" - "$mod, S, exec, hyprutils toggle shader" - "$mod SHIFT, T, exec, pypr toggle term" - "$mod, backslash, exec, pypr toggle emoji" + (bind (combo [mod] "G") (exec "pypr gamemode")) + (bind (combo [mod "SHIFT"] "D") (exec "hyprutils toggle monitor ${display}")) + (bind (combo [mod] "S") (exec "hyprutils toggle shader")) + (bind (combo [mod "SHIFT"] "T") (exec "pypr toggle term")) + (bind (combo [mod] "backslash") (exec "pypr toggle emoji")) ]; ## Permissions permission = [ - "${osConfig.programs.hyprland.portalPackage}/libexec/.xdg-desktop-portal-hyprland-wrapped, screencopy, allow" - "${getExe pkgs.grim}, screencopy, allow" - "${getExe pkgs.wl-screenrec}, screencopy, allow" + (permission "${osConfig.programs.hyprland.portalPackage}/libexec/.xdg-desktop-portal-hyprland-wrapped" "screencopy" "allow") + (permission (getExe pkgs.grim) "screencopy" "allow") + (permission (getExe pkgs.wl-screenrec) "screencopy" "allow") ]; ## Layer Rules - layerrule = [ - "no_anim on, match:namespace ^(hyprpicker)$" - "blur on, ignore_alpha 0.6, match:namespace ^(noctalia-.*)$" + layer_rule = [ + { + match.namespace = "^(hyprpicker)$"; + no_anim = true; + } + { + match.namespace = "^(noctalia-.*)$"; + blur = true; + ignore_alpha = 0.6; + } + { + match.namespace = "^(noctalia-wallpaper)$"; + order = 1; + } + { + match.namespace = "^(desktop)$"; + order = 0; + } ]; ## Window Rules - windowrule = flatten ( + window_rule = [ # Settings - "stay_focused on, match:class ^(gnome-control-center)$" + { + match.class = "^(gnome-control-center)$"; + stay_focused = true; + } # Keybinds Viewer - "pin on, stay_focused on, opacity 0.9 override, match:title ^(Kebihelp)$" + { + match.title = "^(Kebihelp)$"; + pin = true; + stay_focused = true; + opacity = "0.9 override"; + } # Browser Windows - "float on, match:title ^(Picture-in-[P|p]icture)$" - "workspace special silent, match:title ^(Sharing Indicator)$" - "workspace special silent, match:title ^(.*is sharing (your screen|a window).)$" + { + match.title = "^(Picture-in-[P|p]icture)$"; + float = true; + } + { + match.title = "^(Sharing Indicator)$"; + workspace = "special silent"; + } + { + match.title = "^(.*is sharing (your screen|a window).)$"; + workspace = "special silent"; + } # Media Consumption - "idle_inhibit focus, match:class ^(mpv|.*celluloid.*|.+exe)$" - "idle_inhibit focus, match:class ^(firefox|brave-browser)$, match:title ^(.*YouTube.*)$" - "idle_inhibit fullscreen, match:class ^(firefox|brave-browser)$" + { + match.class = "^(mpv|.*celluloid.*|.+exe)$"; + idle_inhibit = "focus"; + } + { + match = { + class = "^(firefox|brave-browser)$"; + title = "^(.*YouTube.*)$"; + }; + idle_inhibit = "focus"; + } + { + match.class = "^(firefox|brave-browser)$"; + idle_inhibit = "fullscreen"; + } # Screen Tearing - "immediate on, match:class ^(.+exe)$" + { + match.class = "^(.+exe)$"; + immediate = true; + } # Prompt Windows - "float on, dim_around on, match:class ^(xdg-desktop-portal-gtk)$" + { + match.class = "^(xdg-desktop-portal-gtk)$"; + float = true; + dim_around = true; + } ] - ++ (map (class: ["pin on, dim_around on, stay_focused on, match:class ^(${class})$"]) [ - # Authentication - "pinentry-" - "gcr-prompter" - ]) - ++ (map (class: ["float on, pin on, persistent_size on, match:class ^(${class})$"]) [ - # Utilities - "com.saivert.pwvucontrol" - "io.github.kaii_lb.Overskride" - "nwg-displays" - "gnome-control-center" - "org.gnome.Settings" - ]) - ++ (map (title: ["float on, match:title ^(${title})(.*)$"]) [ - # Dialogs - "Library" - "Open File" - "Open Folder" - "Save As" - "Save File" - "Select a File" - ".*Properties" - ]) - ); + ++ (map (class: { + # Authentication + match.class = "^(${class})$"; + pin = true; + dim_around = true; + stay_focused = true; + }) [ + "pinentry-" + "gcr-prompter" + ]) + ++ (map (class: { + # Utilities + match.class = "^(${class})$"; + float = true; + pin = true; + persistent_size = true; + }) [ + "com.saivert.pwvucontrol" + "io.github.kaii_lb.Overskride" + "nwg-displays" + "gnome-control-center" + "org.gnome.Settings" + ]) + ++ (map (title: { + # Dialogs + match.title = "^(${title})(.*)$"; + float = true; + }) [ + "Library" + "Open File" + "Open Folder" + "Save As" + "Save File" + "Select a File" + ".*Properties" + ]); }; } ) diff --git a/modules/desktop/hyprland/_settings/keybinds.nix b/modules/desktop/hyprland/_settings/keybinds.nix @@ -1,205 +1,235 @@ ## Compositor Binds -_: _: let +_: {lib, ...}: let inherit (builtins) concatLists genList toString; + inherit (lib) concatStringsSep; + + lua = import ./_lib.nix lib; + inherit (lua) combo bind bindOpts exec; + + mod = "SUPER"; + + # Bind flags + mouse = {mouse = true;}; + locked = {locked = true;}; + repeat = {repeating = true;}; + lockedRepeat = { + locked = true; + repeating = true; + }; + + # Directions + dir = d: + { + l = "left"; + r = "right"; + u = "up"; + d = "down"; + }.${ + d + }; + + # Dispatchers + focusDir = d: ''hl.dsp.focus({ direction = "${dir d}" })''; + swapDir = d: ''hl.dsp.window.swap({ direction = "${dir d}" })''; + intoGroup = d: ''hl.dsp.window.move({ into_group = "${dir d}" })''; + moveOrGroup = d: ''hl.dsp.window.move({ direction = "${dir d}", group_aware = true })''; + moveActive = x: y: ''hl.dsp.window.move({ x = ${toString x}, y = ${toString y}, relative = true })''; + resizeActive = x: y: ''hl.dsp.window.resize({ x = ${toString x}, y = ${toString y}, relative = true })''; + + multi = disps: "function() " + concatStringsSep " " (map (d: "hl.dispatch(${d});") disps) + " end"; in { wayland.windowManager.hyprland = { ## Keybindings - settings = { - "$mod" = "SUPER"; - bind = - [ - # Compositor Commands - "ALT, F4, killactive," - "$mod, Q, killactive," - "$mod SHIFT, Q, forcekillactive," - "$mod SHIFT, E, fullscreen," - "$mod, C, centerwindow" - "$mod, C, movecursortocorner, 2" - "$mod, E, fullscreen, 1" - "$mod, P, pin" - "$mod, Space, layoutmsg, togglesplit" - "$mod SHIFT, S, toggleswallow" - - # Window Focus - "$mod, left, movefocus, l" - "$mod, right, movefocus, r" - "$mod, up, movefocus, u" - "$mod, down, movefocus, d" - "ALT, A, focusurgentorlast" - "ALT, A, alterzorder, top" - - # Window Swap - "$mod SHIFT, left, swapwindow, l" - "$mod SHIFT, right, swapwindow, r" - "$mod SHIFT, up, swapwindow, u" - "$mod SHIFT, down, swapwindow, d" - - # Window Groups - "$mod SHIFT, space, togglegroup" - "ALT, grave, changegroupactive, f" - "ALT SHIFT, grave, changegroupactive, b" - "$mod CTRL, left, moveintogroup, l" - "$mod CTRL, right, moveintogroup, r" - "$mod CTRL, up, moveintogroup, u" - "$mod CTRL, down, moveintogroup, d" - - # Floating Mode - "$mod, semicolon, togglefloating," - "$mod, apostrophe, exec, hyprutils toggle float" - - # Cycle Workspaces - "$mod, comma, split-cycleworkspaces, prev" - "$mod, period, split-cycleworkspaces, next" - "$mod CTRL, comma, split-cycleworkspaces, prev" - "$mod CTRL, period, split-cycleworkspaces, next" - "$mod, mouse_up, split-cycleworkspaces, prev" - "$mod, mouse_down, split-cycleworkspaces, next" - - # Special Workspace - "$mod, 0, togglespecialworkspace, Stash" - "$mod SHIFT, 0, exec, pypr toggle_special Stash" - - # Move Window to Workspace - "$mod SHIFT, comma, split-movetoworkspace, -1" - "$mod SHIFT, period, split-movetoworkspace, +1" - - # Cycle Monitors - "$mod ALT, comma, focusmonitor, l" - "$mod ALT, period, focusmonitor, r" - - # Move Window to Monitor - "$mod SHIFT ALT, comma, movewindow, mon:-1" - "$mod SHIFT ALT, period, movewindow, mon:+1" - - # Screen Lock - "$mod, L, exec, noctalia msg session lock" - - # Window Minimization - "ALT, Q, movetoworkspacesilent, special:minimized" - "ALT SHIFT, Q, exec, hyprutils toggle minimized" - - # Screenshot - ", Print, exec, noctalia msg screenshot-region" - "SHIFT, Print, exec, noctalia msg screenshot-fullscreen pick" - "CTRL, Print, exec, grimblast --notify --cursor copysave active" - - # Submaps - "$mod SHIFT, Escape, submap, Inhibit" - "$mod, R, submap, Resize" - "$mod, M, submap, Move" - ] - ++ - # Workspaces - (concatLists ( - genList ( - n: let - num = toString (n + 1); - in [ - "$mod, ${num}, split-workspace, ${num}" - "$mod SHIFT, ${num}, split-movetoworkspace, ${num}" - ] - ) - 9 - )); - - # Mouse - bindm = [ - "$mod, mouse:272, movewindow" - "$mod, mouse:273, resizewindow" - ]; + settings.bind = + [ + # Compositor Commands + (bind (combo ["ALT"] "F4") "hl.dsp.window.close()") + (bind (combo [mod] "Q") "hl.dsp.window.close()") + (bind (combo [mod "SHIFT"] "Q") "hl.dsp.window.kill()") + (bind (combo [mod "SHIFT"] "E") "hl.dsp.window.fullscreen()") + (bind (combo [mod] "C") (multi [ + "hl.dsp.window.center()" + "hl.dsp.cursor.move_to_corner({ corner = 2 })" + ])) + (bind (combo [mod] "E") ''hl.dsp.window.fullscreen({ mode = "maximized" })'') + (bind (combo [mod] "P") "hl.dsp.window.pin()") + (bind (combo [mod] "Space") ''hl.dsp.layout("togglesplit")'') + (bind (combo [mod "SHIFT"] "S") "hl.dsp.window.toggle_swallow()") + + # Window Focus + (bind (combo [mod] "left") (focusDir "l")) + (bind (combo [mod] "right") (focusDir "r")) + (bind (combo [mod] "up") (focusDir "u")) + (bind (combo [mod] "down") (focusDir "d")) + (bind (combo ["ALT"] "A") (multi [ + "hl.dsp.focus({ urgent_or_last = true })" + ''hl.dsp.window.alter_zorder({ mode = "top" })'' + ])) + + # Window Swap + (bind (combo [mod "SHIFT"] "left") (swapDir "l")) + (bind (combo [mod "SHIFT"] "right") (swapDir "r")) + (bind (combo [mod "SHIFT"] "up") (swapDir "u")) + (bind (combo [mod "SHIFT"] "down") (swapDir "d")) + + # Window Groups + (bind (combo [mod "SHIFT"] "space") "hl.dsp.group.toggle()") + (bind (combo ["ALT"] "grave") "hl.dsp.group.next()") + (bind (combo ["ALT" "SHIFT"] "grave") "hl.dsp.group.prev()") + (bind (combo [mod "CTRL"] "left") (intoGroup "l")) + (bind (combo [mod "CTRL"] "right") (intoGroup "r")) + (bind (combo [mod "CTRL"] "up") (intoGroup "u")) + (bind (combo [mod "CTRL"] "down") (intoGroup "d")) + + # Floating Mode + (bind (combo [mod] "semicolon") ''hl.dsp.window.float({ action = "toggle" })'') + (bind (combo [mod] "apostrophe") (exec "hyprutils toggle float")) + + # Cycle Workspaces + (bind (combo [mod] "comma") ''hs.dsp.focus({ workspace = "m-1" })'') + (bind (combo [mod] "period") ''hs.dsp.focus({ workspace = "m+1" })'') + (bind (combo [mod "CTRL"] "comma") ''hs.dsp.focus({ workspace = "r-1" })'') + (bind (combo [mod "CTRL"] "period") ''hs.dsp.focus({ workspace = "r+1" })'') + (bind (combo [mod] "mouse_up") ''hs.dsp.focus({ workspace = "r-1" })'') + (bind (combo [mod] "mouse_down") ''hs.dsp.focus({ workspace = "r+1" })'') + + # Special Workspace + (bind (combo [mod] "0") ''hl.dsp.workspace.toggle_special("Stash")'') + (bind (combo [mod "SHIFT"] "0") (exec "pypr toggle_special Stash")) + + # Move Window to Workspace + (bind (combo [mod "SHIFT"] "comma") ''hs.dsp.window.move({ workspace = "-1", follow = false })'') + (bind (combo [mod "SHIFT"] "period") ''hs.dsp.window.move({ workspace = "+1", follow = false })'') + + # Cycle Monitors + (bind (combo [mod "ALT"] "comma") ''hl.dsp.focus({ monitor = "l" })'') + (bind (combo [mod "ALT"] "period") ''hl.dsp.focus({ monitor = "r" })'') + + # Move Window to Monitor + (bind (combo [mod "SHIFT" "ALT"] "comma") ''hl.dsp.window.move({ monitor = "-1" })'') + (bind (combo [mod "SHIFT" "ALT"] "period") ''hl.dsp.window.move({ monitor = "+1" })'') + + # Screen Lock + (bind (combo [mod] "L") (exec "noctalia msg session lock")) + + # Window Minimization + (bind (combo ["ALT"] "Q") ''hl.dsp.window.move({ workspace = "special:minimized", follow = false })'') + (bind (combo ["ALT" "SHIFT"] "Q") (exec "hyprutils toggle minimized")) + + # Screenshot + (bind (combo [] "Print") (exec "noctalia msg screenshot-region")) + (bind (combo ["SHIFT"] "Print") (exec "noctalia msg screenshot-fullscreen pick")) + (bind (combo ["CTRL"] "Print") (exec "grimblast --notify --cursor copysave active")) + + # Submaps + (bind (combo [mod "SHIFT"] "Escape") ''hl.dsp.submap("Inhibit")'') + (bind (combo [mod] "R") ''hl.dsp.submap("Resize")'') + (bind (combo [mod] "M") ''hl.dsp.submap("Move")'') + ] + ++ + # Workspaces + (concatLists ( + genList ( + n: let + i = toString (n + 1); + in [ + (bind (combo [mod] i) "hs.dsp.focus({ workspace = ${i} })") + (bind (combo [mod "SHIFT"] i) "hs.dsp.window.move({ workspace = ${i}, follow = false })") + ] + ) + 9 + )) + ++ [ + # Mouse + (bindOpts (combo [mod] "mouse:272") "hl.dsp.window.drag()" mouse) + (bindOpts (combo [mod] "mouse:273") "hl.dsp.window.resize()" mouse) - # Ignore Locked State - bindl = [ # Media Controls - ", XF86AudioPlay, exec, noctalia msg media toggle" - ", XF86AudioPrev, exec, noctalia msg media previous" - ", XF86AudioNext, exec, noctalia msg media next" + (bindOpts (combo [] "XF86AudioPlay") (exec "noctalia msg media toggle") locked) + (bindOpts (combo [] "XF86AudioPrev") (exec "noctalia msg media previous") locked) + (bindOpts (combo [] "XF86AudioNext") (exec "noctalia msg media next") locked) # Volume - ", XF86AudioMute, exec, noctalia msg volume-mute" + (bindOpts (combo [] "XF86AudioMute") (exec "noctalia msg volume-mute") locked) # Keyboard Backlight - ", XF86KbdBrightnessUp, exec, hyprutils backlight up" - ", XF86KbdBrightnessDown, exec, hyprutils backlight down" + (bindOpts (combo [] "XF86KbdBrightnessUp") (exec "hyprutils backlight up") locked) + (bindOpts (combo [] "XF86KbdBrightnessDown") (exec "hyprutils backlight down") locked) # Touchpad - ", XF86TouchpadToggle, exec, hyprutils toggle touchpad" + (bindOpts (combo [] "XF86TouchpadToggle") (exec "hyprutils toggle touchpad") locked) # Laptop Lid - ", switch:on:Lid Switch, exec, noctalia msg session lock" - ]; + (bindOpts (combo [] "switch:on:Lid Switch") (exec "noctalia msg session lock") locked) - # Repeat on Hold - bindle = [ # Volume - ", XF86AudioRaiseVolume, exec, noctalia msg volume-up" - ", XF86AudioLowerVolume, exec, noctalia msg volume-down" + (bindOpts (combo [] "XF86AudioRaiseVolume") (exec "noctalia msg volume-up") lockedRepeat) + (bindOpts (combo [] "XF86AudioLowerVolume") (exec "noctalia msg volume-down") lockedRepeat) # Backlight - ", XF86MonBrightnessUp, exec, noctalia msg brightness-up" - ", XF86MonBrightnessDown, exec, noctalia msg brightness-down" + (bindOpts (combo [] "XF86MonBrightnessUp") (exec "noctalia msg brightness-up") lockedRepeat) + (bindOpts (combo [] "XF86MonBrightnessDown") (exec "noctalia msg brightness-down") lockedRepeat) # Magnifier - "$mod, equal, exec, pypr zoom ++0.5" - "$mod, minus, exec, pypr zoom --0.5" - "$mod SHIFT, minus, exec, pypr zoom" + (bindOpts (combo [mod] "equal") (exec "pypr zoom ++0.5") lockedRepeat) + (bindOpts (combo [mod] "minus") (exec "pypr zoom --0.5") lockedRepeat) + (bindOpts (combo [mod "SHIFT"] "minus") (exec "pypr zoom") lockedRepeat) ]; - }; ## Submaps submaps = { # Inhibit Keybinds - Inhibit.settings.bind = ["$mod SHIFT, Escape, submap, reset"]; + Inhibit.settings.bind = [(bind (combo [mod "SHIFT"] "Escape") ''hl.dsp.submap("reset")'')]; # Window Resize - Resize.settings = { - binde = [ - ", right, resizeactive, 10 0" - ", left, resizeactive, -10 0" - ", up, resizeactive, 0 -10" - ", down, resizeactive, 0 10" - ]; - bindm = [", mouse:272, resizewindow"]; - bind = [ - ", escape, submap, reset" - "$mod, R, submap, reset" - ]; - }; + Resize.settings.bind = [ + (bindOpts (combo [] "right") (resizeActive 10 0) repeat) + (bindOpts (combo [] "left") (resizeActive (-10) 0) repeat) + (bindOpts (combo [] "up") (resizeActive 0 (-10)) repeat) + (bindOpts (combo [] "down") (resizeActive 0 10) repeat) + (bindOpts (combo [] "mouse:272") "hl.dsp.window.resize()" mouse) + (bind (combo [] "escape") ''hl.dsp.submap("reset")'') + (bind (combo [mod] "R") ''hl.dsp.submap("reset")'') + ]; # Window Movement - Move.settings = { - bind = [ - ", C, centerwindow" - ", P, pin" - ", left, movewindoworgroup, l" - ", right, movewindoworgroup, r" - ", up, movewindoworgroup, u" - ", down, movewindoworgroup, d" - "SHIFT, left, moveactive, -30 0" - "SHIFT, right, moveactive, 30 0" - "SHIFT, up, moveactive, 0 -30" - "SHIFT, down, moveactive, 0 30" - ", comma, split-movetoworkspace, -1" - ", period, split-movetoworkspace, +1" - ", escape, submap, reset" - "$mod, M, submap, reset" - ]; - bindm = [", mouse:272, movewindow"]; - }; + Move.settings.bind = [ + (bind (combo [] "C") "hl.dsp.window.center()") + (bind (combo [] "P") "hl.dsp.window.pin()") + (bind (combo [] "left") (moveOrGroup "l")) + (bind (combo [] "right") (moveOrGroup "r")) + (bind (combo [] "up") (moveOrGroup "u")) + (bind (combo [] "down") (moveOrGroup "d")) + (bind (combo ["SHIFT"] "left") (moveActive (-30) 0)) + (bind (combo ["SHIFT"] "right") (moveActive 30 0)) + (bind (combo ["SHIFT"] "up") (moveActive 0 (-30))) + (bind (combo ["SHIFT"] "down") (moveActive 0 30)) + (bind (combo [] "comma") ''hs.dsp.window.move({ workspace = "-1", follow = false })'') + (bind (combo [] "period") ''hs.dsp.window.move({ workspace = "+1", follow = false })'') + (bindOpts (combo [] "mouse:272") "hl.dsp.window.drag()" mouse) + (bind (combo [] "escape") ''hl.dsp.submap("reset")'') + (bind (combo [mod] "M") ''hl.dsp.submap("reset")'') + ]; # Window Minimization Minimized.settings.bind = [ - ", left, movefocus, l" - ", right, movefocus, r" - ", up, movefocus, u" - ", down, movefocus, d" - ", Q, killactive," - ", Return, movetoworkspace, +0" - ", Return, submap, reset" - ", mouse:272, movetoworkspace, +0" - ", mouse:272, submap, reset" - ", escape, togglespecialworkspace, minimized" - ", escape, submap, reset" + (bind (combo [] "left") (focusDir "l")) + (bind (combo [] "right") (focusDir "r")) + (bind (combo [] "up") (focusDir "u")) + (bind (combo [] "down") (focusDir "d")) + (bind (combo [] "Q") "hl.dsp.window.close()") + (bind (combo [] "Return") (multi [ + ''hl.dsp.window.move({ workspace = "+0" })'' + ''hl.dsp.submap("reset")'' + ])) + (bind (combo [] "mouse:272") (multi [ + ''hl.dsp.window.move({ workspace = "+0" })'' + ''hl.dsp.submap("reset")'' + ])) + (bind (combo [] "escape") (multi [ + ''hl.dsp.workspace.toggle_special("minimized")'' + ''hl.dsp.submap("reset")'' + ])) ]; }; }; diff --git a/modules/desktop/hyprland/_settings/main.nix b/modules/desktop/hyprland/_settings/main.nix @@ -6,214 +6,333 @@ _: { }: lib.mkIf (osConfig != null) ( let - inherit (lib) mkForce mkIf; + lua = import ./_lib.nix lib; + inherit (lua) curve; + inherit (osConfig.gui) display fancy; inherit (osConfig.lib.stylix.colors) base03 base05 base0D; + + gradient = a: b: { + colors = ["rgb(${a})" "rgb(${b})"]; + angle = 90; + }; in { - stylix.targets.hyprland.enable = true; + stylix.targets.hyprland.enable = false; wayland.windowManager.hyprland = { inherit (osConfig.programs.hyprland) enable package portalPackage; - # ! # TODO - configType = "hyprlang"; - # Use 'nwg-displays' to configure monitors extraConfig = '' - source = ~/.config/hypr/monitors.conf - source = ~/.config/hypr/workspaces.conf + pcall(require, "monitors") + pcall(require, "workspaces") ''; settings = { # Display - monitor = ", preferred, auto, 1"; - xwayland = { - enabled = true; - force_zero_scaling = true; + monitor = { + output = ""; + mode = "preferred"; + position = "auto"; + scale = 1; }; - input = { - follow_mouse = 1; # Focus on cursor move - follow_mouse_threshold = 15; - focus_on_close = 1; - - # Keyboard - kb_layout = "us"; - numlock_by_default = true; - - # Mouse - accel_profile = "flat"; - touchpad = { - tap-to-click = true; - tap-and-drag = true; - natural_scroll = true; - disable_while_typing = false; - drag_3fg = 1; # 3-finger window drag - }; - }; + # Touchpad Gestures + gesture = [ + { + fingers = 3; + direction = "horizontal"; + action = "workspace"; + } + ]; - # Workspace Behaviour - binds = { - workspace_center_on = 1; - movefocus_cycles_fullscreen = true; - workspace_back_and_forth = true; - drag_threshold = 30; - }; + # Smart Gaps + workspace_rule = [ + { + workspace = "w[tv1]s[false]"; + gaps_out = 0; + gaps_in = 0; + } + { + workspace = "f[1]s[false]"; + gaps_out = 0; + gaps_in = 0; + } + ]; + window_rule = [ + { + name = "no-gaps-wtv1"; + match = { + float = false; + workspace = "w[tv1]s[false]"; + }; + border_size = 0; + rounding = 0; + } + { + name = "no-gaps-f1"; + match = { + float = false; + workspace = "f[1]s[false]"; + }; + border_size = 0; + rounding = 0; + } + ]; - gesture = [ - "3, horizontal, workspace" + # Custom Animations + curve = lib.optionals fancy [ + (curve "accelerate" { + type = "bezier"; + points = [[0.3 0] [0.8 0.15]]; + }) + (curve "decelerate" { + type = "bezier"; + points = [[0.05 0.7] [0.1 1]]; + }) + (curve "zoom" { + type = "bezier"; + points = [[0.38 0.04] [1 0.07]]; + }) + (curve "crash" { + type = "bezier"; + points = [[0.1 1] [0 1]]; + }) + ]; + animation = lib.optionals fancy [ + { + leaf = "border"; + enabled = true; + speed = 10; + bezier = "default"; + } + { + leaf = "fade"; + enabled = true; + speed = 3; + bezier = "decelerate"; + } + { + leaf = "fadeLayersIn"; + enabled = true; + speed = 2; + bezier = "crash"; + } + { + leaf = "fadeLayersOut"; + enabled = true; + speed = 0.5; + bezier = "zoom"; + } + { + leaf = "layersIn"; + enabled = true; + speed = 3; + bezier = "crash"; + style = "slide"; + } + { + leaf = "layersOut"; + enabled = true; + speed = 1.6; + bezier = "zoom"; + } + { + leaf = "specialWorkspace"; + enabled = true; + speed = 3; + bezier = "decelerate"; + style = "slidevert"; + } + { + leaf = "windows"; + enabled = true; + speed = 3; + bezier = "decelerate"; + style = "popin 60%"; + } + { + leaf = "windowsIn"; + enabled = true; + speed = 3; + bezier = "decelerate"; + style = "popin 60%"; + } + { + leaf = "windowsOut"; + enabled = true; + speed = 3; + bezier = "accelerate"; + style = "popin 60%"; + } + { + leaf = "workspaces"; + enabled = true; + speed = 7; + bezier = "crash"; + style = "slide"; + } ]; - # Touchpad Gestures - gestures = { - workspace_swipe_use_r = false; - workspace_swipe_create_new = true; - }; + config = + { + xwayland = { + enabled = true; + force_zero_scaling = true; + }; - # Cursor Settings - cursor = { - default_monitor = display; - hide_on_key_press = true; - sync_gsettings_theme = true; - warp_on_change_workspace = true; - }; + input = { + follow_mouse = 1; # Focus on cursor move + follow_mouse_threshold = 15; + focus_on_close = 1; - # Tiling Layout - dwindle = { - preserve_split = true; - smart_split = true; - }; + # Keyboard + kb_layout = "us"; + numlock_by_default = true; - # Smart Gaps - workspace = [ - "w[tv1]s[false], gapsout:0, gapsin:0" - "f[1]s[false], gapsout:0, gapsin:0" - ]; - windowrule = [ - "border_size 0, rounding 0, match:float 0, match:workspace w[tv1]s[false]" - "border_size 0, rounding 0, match:float 0, match:workspace f[1]s[false]" - ]; + # Mouse + accel_profile = "flat"; + touchpad = { + tap_to_click = true; + tap_and_drag = true; + natural_scroll = true; + disable_while_typing = false; + drag_3fg = 1; # 3-finger window drag + }; + }; - misc = { - disable_autoreload = true; # Disable configuration Polling - enable_swallow = true; # Window Swallowing + # Workspace Behaviour + binds = { + workspace_center_on = 1; + movefocus_cycles_fullscreen = true; + workspace_back_and_forth = true; + drag_threshold = 30; + }; - focus_on_activate = true; - initial_workspace_tracking = 1; - middle_click_paste = false; - on_focus_under_fullscreen = 2; + # Touchpad Gestures + gestures = { + workspace_swipe_use_r = false; + workspace_swipe_create_new = true; + }; - # Interfere with wallpaper daemons - force_default_wallpaper = 0; - disable_hyprland_logo = true; + # Cursor Settings + cursor = { + default_monitor = display; + hide_on_key_press = true; + sync_gsettings_theme = true; + warp_on_change_workspace = true; + }; - # Graphics - vrr = 1; - }; - render.direct_scanout = 1; + # Tiling Layout + dwindle = { + preserve_split = true; + smart_split = true; + }; - general = { - allow_tearing = !fancy; - resize_on_border = true; + misc = { + disable_autoreload = true; # Disable configuration Polling + enable_swallow = true; # Window Swallowing + swallow_regex = "^(kitty)$"; - # Floating Layout - snap = { - enabled = true; - border_overlap = true; - respect_gaps = true; - monitor_gap = 10; - window_gap = 15; - }; + focus_on_activate = true; + initial_workspace_tracking = 1; + middle_click_paste = false; + on_focus_under_fullscreen = 2; - # Visuals - gaps_in = 3; - gaps_out = 3; - float_gaps = 3; - border_size = 2; - "col.active_border" = mkForce "rgb(${base0D}) rgb(${base05}) 90deg"; - }; + # Interfere with wallpaper daemons + force_default_wallpaper = 0; + disable_hyprland_logo = true; - group = { - auto_group = true; - insert_after_current = true; - drag_into_group = 2; - merge_groups_on_drag = true; - merge_groups_on_groupbar = true; - merge_floated_into_tiled_on_groupbar = false; - group_on_movetoworkspace = false; - "col.border_active" = mkForce "rgb(${base05}) rgb(${base0D}) 90deg"; - "col.border_inactive" = mkForce "rgb(${base05}) rgb(${base03}) 90deg"; - - groupbar = { - enabled = true; - scrolling = true; - gradients = true; - blur = true; - height = 15; - render_titles = true; - font_size = 10; - font_weight_active = "bold"; - keep_upper_gap = false; - middle_click_close = true; - indicator_height = 0; - gradient_rounding = 5; - gradient_round_only_edges = false; - "col.active" = mkForce "rgba(${base0D}99)"; - "col.inactive" = mkForce "rgb(${base03})"; - }; - }; + # Graphics + vrr = 1; + }; + render.direct_scanout = 1; - animation = mkIf fancy { - bezier = [ - "accelerate, 0.3, 0, 0.8, 0.15" - "decelerate, 0.05, 0.7, 0.1, 1" - "zoom, 0.38, 0.04, 1, 0.07" - "crash, 0.1, 1, 0, 1" - ]; - - animation = [ - "border, 1, 10, default" - "fade, 1, 3, decelerate" - "fadeLayersIn, 1, 2, crash" - "fadeLayersOut, 1, 0.5, zoom" - "layersIn, 1, 3, crash, slide" - "layersOut, 1, 1.6, zoom" - "specialWorkspace, 1, 3, decelerate, slidevert" - "windows, 1, 3, decelerate, popin 60%" - "windowsIn, 1, 3, decelerate, popin 60%" - "windowsOut, 1, 3, accelerate, popin 60%" - "workspaces, 1, 7, crash, slide" - ]; - }; + general = { + allow_tearing = !fancy; + resize_on_border = true; - decoration = mkIf fancy { - rounding = 10; - rounding_power = 3.0; - dim_special = 0.3; + # Floating Layout + snap = { + enabled = true; + border_overlap = true; + respect_gaps = true; + monitor_gap = 10; + window_gap = 15; + }; - shadow = { - enabled = true; - offset = "0 2"; - range = 20; - }; + # Visuals + gaps_in = 3; + gaps_out = 3; + float_gaps = 3; + border_size = 2; + col.active_border = gradient base0D base05; + }; - blur = { - enabled = true; - brightness = 1.0; - contrast = 1.0; - passes = 2; - input_methods = true; - }; - }; + group = { + auto_group = true; + insert_after_current = true; + drag_into_group = 2; + merge_groups_on_drag = true; + merge_groups_on_groupbar = true; + merge_floated_into_tiled_on_groupbar = false; + group_on_movetoworkspace = false; + col = { + border_active = gradient base05 base0D; + border_inactive = gradient base05 base03; + }; - debug = { - disable_logs = false; - error_position = 1; - }; + groupbar = { + enabled = true; + scrolling = true; + gradients = true; + blur = true; + height = 15; + render_titles = true; + font_size = 10; + font_weight_active = "bold"; + keep_upper_gap = false; + middle_click_close = true; + indicator_height = 0; + gradient_rounding = 5; + gradient_round_only_edges = false; + col = { + active = "rgba(${base0D}99)"; + inactive = "rgb(${base03})"; + }; + }; + }; - ecosystem = { - no_update_news = true; - no_donation_nag = true; - }; + debug = { + disable_logs = false; + error_position = 1; + }; + + ecosystem = { + no_update_news = true; + no_donation_nag = true; + }; + } + // lib.optionalAttrs fancy { + decoration = { + rounding = 10; + rounding_power = 3.0; + dim_special = 0.3; + + shadow = { + enabled = true; + offset = "0 2"; + range = 20; + }; + + blur = { + enabled = true; + brightness = 1.0; + contrast = 1.0; + passes = 2; + input_methods = true; + }; + }; + }; }; }; } diff --git a/modules/desktop/hyprland/_settings/plugins.nix b/modules/desktop/hyprland/_settings/plugins.nix @@ -5,38 +5,38 @@ _: { osConfig ? null, ... }: -lib.mkIf (osConfig != null) { - wayland.windowManager.hyprland = { - plugins = with pkgs.hyprworld; [ - split-monitor-workspaces - hypr-dynamic-cursors - ]; +lib.mkIf (osConfig != null) ( + let + inherit (pkgs.hyprworld) hyprsplitlua hypr-dynamic-cursors; - settings.plugin = { - # Workspaces per Monitor - split-monitor-workspaces.count = 9; + lua = import ./_lib.nix lib; + inherit (lua) inline; - # Cursor Effects - dynamic-cursors = { - enabled = true; - mode = - if osConfig.gui.fancy - then "tilt" - else "none"; - - hyprcursor = { - enabled = true; - nearest = true; - }; - - shake = { - enabled = true; - effects = false; - ipc = false; - }; - - tilt.activation = "negative_quadratic"; + cursorMode = + if osConfig.gui.fancy + then "tilt" + else "none"; + in { + # Workspaces per Monitor + xdg.configFile."hypr/hyprsplit/init.lua".source = "${hyprsplitlua}/share/hyprsplit/init.lua"; + wayland.windowManager.hyprland = { + settings.hs = { + _var = inline ''(function() local hs = require("hyprsplit"); hs.config({ num_workspaces = 9 }); return hs end)()''; }; + + # Cursor Effects + plugins = [hypr-dynamic-cursors]; + extraConfig = '' + if hl.plugin.dynamic_cursors then + hl.config({ plugin = { dynamic_cursors = { + enabled = true, + mode = "${cursorMode}", + hyprcursor = { enabled = true, nearest = 1 }, + shake = { enabled = true, effects = false, ipc = false }, + tilt = { activation = "negative_quadratic" }, + } } }) + end + ''; }; - }; -} + } +) diff --git a/modules/hosts/valkyrie/_settings/default.nix b/modules/hosts/valkyrie/_settings/default.nix @@ -5,11 +5,15 @@ _: { pkgs, ... }: { - # ! # https://gitlab.freedesktop.org/drm/amd/-/issues/3388 - boot.kernelParams = lib.mkIf (config.hardware.cpu.mode == "performance") [ - "amdgpu.dcdebugmask=0x10" - "usbcore.autosuspend=-1" - ]; + boot = { + plymouth.extraConfig = "DeviceScale=2"; + + # ! # https://gitlab.freedesktop.org/drm/amd/-/issues/3388 + kernelParams = lib.mkIf (config.hardware.cpu.mode == "performance") [ + "amdgpu.dcdebugmask=0x10" + "usbcore.autosuspend=-1" + ]; + }; services = { fwupd.enable = true; @@ -63,7 +67,7 @@ _: { }; }; - home = _: { + home = {lib, ...}: { home.persist.directories = [ ".copilot" ".mongodb" @@ -74,9 +78,12 @@ _: { ]; # Keybinds - wayland.windowManager.hyprland.settings.bindl = [ - ", XF86Launch3, exec, asusctl aura -n" - ", XF86Launch4, exec, asusctl profile -n" + wayland.windowManager.hyprland.settings.bind = let + inline = lib.generators.mkLuaInline; + locked = {locked = true;}; + in [ + {_args = ["XF86Launch3" (inline ''hl.dsp.exec_cmd("asusctl aura -n")'') locked];} + {_args = ["XF86Launch4" (inline ''hl.dsp.exec_cmd("asusctl profile -n")'') locked];} ]; # Development diff --git a/modules/system/base-ext.nix b/modules/system/base-ext.nix @@ -1,9 +1,7 @@ ## Extended Base Configuration ## -{inputs, ...}: { +_: { flake.modules = { nixos.base-ext = _: { - imports = [inputs.gaming.nixosModules.pipewireLowLatency]; - config = { # AppImage Support programs.appimage = { @@ -16,13 +14,6 @@ dev.enable = true; man.enable = true; }; - - # Low Latency Audio - services.pipewire.lowLatency = { - enable = true; - quantum = 64; - rate = 48000; - }; }; }; }; diff --git a/modules/system/boot.nix b/modules/system/boot.nix @@ -103,7 +103,6 @@ enable = true; autoReboot = true; }; - settings.console-mode = "max"; }; environment = { diff --git a/modules/system/nix.nix b/modules/system/nix.nix @@ -34,7 +34,12 @@ ]; # Binary Cache - inherit ((import ../../flake.nix).nixConfig) trusted-substituters trusted-public-keys; + inherit + ((import ../../flake.nix).nixConfig) + substituters + trusted-substituters + trusted-public-keys + ; }; # Garbage Collection diff --git a/packages/_module.nix b/packages/_module.nix @@ -36,7 +36,6 @@ in { config = nixpkgsConfig; }; - gaming = gaming.packages."${system}"; wine = windows.packages."${system}"; winelib = windows.lib."${system}"; spicetify = spicetify.legacyPackages."${system}"; diff --git a/packages/hyprshellevents/default.nix b/packages/hyprshellevents/default.nix @@ -1,41 +0,0 @@ -{ - lib, - pkgs, - ... -}: -with pkgs; let - metadata = import ./metadata.nix; -in - stdenvNoCC.mkDerivation (final: { - pname = "hyprshellevents"; - version = metadata.rev; - sourceRoot = "${final.src.name}/shellevents"; - - src = fetchFromGitHub { - owner = "hyprwm"; - repo = "contrib"; - inherit (metadata) rev sha256; - }; - - buildInputs = [bash]; - makeFlags = ["PREFIX=$(out)"]; - nativeBuildInputs = [makeWrapper]; - postInstall = '' - wrapProgram $out/bin/shellevents --prefix PATH ':' \ - "${ - lib.makeBinPath [ - coreutils - hyprland - ] - }" - ''; - - meta = with lib; { - mainProgram = "shellevents"; - description = "Run shell scripts in response to Hyprland events"; - homepage = metadata.repo; - license = licenses.mit; - platforms = platforms.unix; - maintainers = ["maydayv7"]; - }; - }) diff --git a/packages/hyprshellevents/metadata.nix b/packages/hyprshellevents/metadata.nix @@ -1,5 +0,0 @@ -{ - repo = "https://github.com/hyprwm/contrib"; - rev = "541628cebe42792ddf5063c4abd6402c2f1bd68f"; - sha256 = "sha256-CopNx3j//gZ2mE0ggEK9dZ474UcbDhpTw+KMor8mSxI="; -} diff --git a/scripts/hyprutils.nix b/scripts/hyprutils.nix @@ -20,25 +20,6 @@ shader - Toggle Compositor Shader touchpad - Toggle touchpad ''; - - daemon = builtins.toFile "daemon.sh" '' - event_activespecial() { - case "$WORKSPACENAME" in - special:minimized*) - hyprctl dispatch submap reset - hyprctl dispatch submap Minimized - ;; - esac - } - - event_minimized() { - WINDOW="address:0x$WINDOWADDRESS" - case "$MINIMIZED" in - 0) hyprctl dispatch movetoworkspace "+0, $WINDOW" ;; - 1) hyprctl dispatch movetoworkspacesilent "special:minimized, $WINDOW" ;; - esac - } - ''; in recursiveUpdate { @@ -56,10 +37,8 @@ in runtimeInputs = with pkgs; [ coreutils gnugrep - socat brightnessctl - custom.hyprshellevents hyprland hyprshade zenity @@ -80,10 +59,6 @@ in case "$1" in "") error "Expected an Option" "${help}";; "help") echo -e "## Hyprland Utility Script ##\n${help}";; - "daemon") - info "Monitoring Hyprland Socket..." - socat -u UNIX-CONNECT:"$XDG_RUNTIME_DIR"/hypr/"$HYPRLAND_INSTANCE_SIGNATURE"/.socket2.sock EXEC:"shellevents ${daemon}",nofork - ;; "backlight") case "$2" in "up") brightnessctl -d "*::kbd_backlight" set 33%+ ;; @@ -97,12 +72,13 @@ in "float") WORKSPACE=$(hyprctl activeworkspace | grep "workspace ID" | awk '{print $3}') hyprnotify 1 "Toggled window floating on Workspace $WORKSPACE" - hyprctl dispatch workspaceopt allfloat + hyprctl eval 'local ws = hl.get_active_workspace(); if ws then for _, w in ipairs(hl.get_workspace_windows(ws)) do hl.dispatch(hl.dsp.window.float({ action = "toggle", window = w })) end end' ;; "minimized") - if hyprctl workspaces | grep "special:minimize" + if hyprctl workspaces | grep "special:minimized" then - hyprctl dispatch workspace special:minimized + hyprctl dispatch 'hl.dsp.focus({ workspace = "special:minimized" })' + hyprctl dispatch 'hl.dsp.submap("Minimized")' else hyprnotify 1 "No minimized windows present" fi @@ -115,11 +91,10 @@ in if hyprctl monitors | grep "Monitor $3" then - hyprctl keyword monitor "$3, disable" + hyprctl eval 'hl.monitor({ output = "'"$3"'", disabled = true })' else - hyprctl keyword monitor "$3, preferred, auto, 1" + hyprctl eval 'hl.monitor({ output = "'"$3"'", mode = "preferred", position = "auto", scale = 1 })' fi - hyprctl reload ;; "shader") hyprshade off @@ -133,13 +108,13 @@ in touchpad=$(hyprctl devices | grep touchpad | xargs) enable() { - hyprctl keyword "device[$touchpad]:enabled" true + hyprctl eval 'hl.device({ name = "'"$touchpad"'", enabled = true })' printf "true" >"$STATUS" hyprnotify 1 "Touchpad Enabled" } disable() { - hyprctl keyword "device[$touchpad]:enabled" false + hyprctl eval 'hl.device({ name = "'"$touchpad"'", enabled = false })' printf "false" >"$STATUS" hyprnotify 1 "Touchpad Disabled" }