commit ad471330e3ae3c05b1f6b62ed4640ed42d53432e
parent b3eaefc3f61713160e93edd4f4e9a5f3e70cae8e
Author: maydayv7 <maydayv7@gmail.com>
Date: Sat, 20 Jun 2026 15:08:21 +0530
feat(Hyprland): LUA
Diffstat:
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"
}