summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flake.nix218
-rw-r--r--nix/default.nix328
-rw-r--r--nix/formatter.nix10
-rw-r--r--nix/hm-module.nix10
-rw-r--r--nix/lib.nix123
-rw-r--r--nix/module.nix109
-rw-r--r--nix/overlays.nix115
-rw-r--r--nix/tests/default.nix112
8 files changed, 543 insertions, 482 deletions
diff --git a/flake.nix b/flake.nix
index 21561cc5..6d695bfb 100644
--- a/flake.nix
+++ b/flake.nix
@@ -88,108 +88,122 @@
};
};
- outputs = inputs @ {
- self,
- nixpkgs,
- systems,
- ...
- }: let
- inherit (nixpkgs) lib;
- eachSystem = lib.genAttrs (import systems);
- pkgsFor = eachSystem (system:
- import nixpkgs {
- localSystem = system;
- overlays = with self.overlays; [
- hyprland-packages
- hyprland-extras
- ];
- });
- pkgsCrossFor = eachSystem (system: crossSystem:
- import nixpkgs {
- localSystem = system;
- inherit crossSystem;
- overlays = with self.overlays; [
- hyprland-packages
- hyprland-extras
- ];
- });
- pkgsDebugFor = eachSystem (system:
- import nixpkgs {
- localSystem = system;
- overlays = with self.overlays; [
- hyprland-debug
- ];
- });
- pkgsDebugCrossFor = eachSystem (system: crossSystem:
- import nixpkgs {
- localSystem = system;
- inherit crossSystem;
- overlays = with self.overlays; [
- hyprland-debug
- ];
- });
- in {
- overlays = import ./nix/overlays.nix {inherit self lib inputs;};
-
- checks = eachSystem (system:
- (lib.filterAttrs
- (n: _: (lib.hasPrefix "hyprland" n) && !(lib.hasSuffix "debug" n))
- self.packages.${system})
- // {
- inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
- pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
- src = ./.;
- hooks = {
- hyprland-treewide-formatter = {
- enable = true;
- entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter";
- pass_filenames = false;
- excludes = ["subprojects"];
- always_run = true;
+ outputs =
+ inputs@{
+ self,
+ nixpkgs,
+ systems,
+ ...
+ }:
+ let
+ inherit (nixpkgs) lib;
+ eachSystem = lib.genAttrs (import systems);
+ pkgsFor = eachSystem (
+ system:
+ import nixpkgs {
+ localSystem = system;
+ overlays = with self.overlays; [
+ hyprland-packages
+ hyprland-extras
+ ];
+ }
+ );
+ pkgsCrossFor = eachSystem (
+ system: crossSystem:
+ import nixpkgs {
+ localSystem = system;
+ inherit crossSystem;
+ overlays = with self.overlays; [
+ hyprland-packages
+ hyprland-extras
+ ];
+ }
+ );
+ pkgsDebugFor = eachSystem (
+ system:
+ import nixpkgs {
+ localSystem = system;
+ overlays = with self.overlays; [
+ hyprland-debug
+ ];
+ }
+ );
+ pkgsDebugCrossFor = eachSystem (
+ system: crossSystem:
+ import nixpkgs {
+ localSystem = system;
+ inherit crossSystem;
+ overlays = with self.overlays; [
+ hyprland-debug
+ ];
+ }
+ );
+ in
+ {
+ overlays = import ./nix/overlays.nix { inherit self lib inputs; };
+
+ checks = eachSystem (
+ system:
+ (lib.filterAttrs (
+ n: _: (lib.hasPrefix "hyprland" n) && !(lib.hasSuffix "debug" n)
+ ) self.packages.${system})
+ // {
+ inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
+ pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
+ src = ./.;
+ hooks = {
+ hyprland-treewide-formatter = {
+ enable = true;
+ entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter";
+ pass_filenames = false;
+ excludes = [ "subprojects" ];
+ always_run = true;
+ };
};
};
- };
- }
- // (import ./nix/tests inputs pkgsFor.${system}));
-
- packages = eachSystem (system: {
- default = self.packages.${system}.hyprland;
- inherit
- (pkgsFor.${system})
- # hyprland-packages
- hyprland
- hyprland-unwrapped
- hyprland-with-tests
- # hyprland-extras
- xdg-desktop-portal-hyprland
- ;
- inherit (pkgsDebugFor.${system}) hyprland-debug;
- hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
- hyprland-debug-cross = (pkgsDebugCrossFor.${system} "aarch64-linux").hyprland-debug;
- });
-
- devShells = eachSystem (system: {
- default =
- pkgsFor.${system}.mkShell.override {
- inherit (self.packages.${system}.default) stdenv;
- } {
- name = "hyprland-shell";
- hardeningDisable = ["fortify"];
- inputsFrom = [pkgsFor.${system}.hyprland];
- packages = [pkgsFor.${system}.clang-tools];
- inherit (self.checks.${system}.pre-commit-check) shellHook;
- };
- });
-
- formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix {});
-
- nixosModules.default = import ./nix/module.nix inputs;
- homeManagerModules.default = import ./nix/hm-module.nix self;
-
- # Hydra build jobs
- # Recent versions of Hydra can aggregate jobsets from 'hydraJobs' instead of a release.nix
- # or similar. Remember to filter large or incompatible attributes here. More eval jobs can
- # be added by merging, e.g., self.packages // self.devShells.
- hydraJobs = self.packages;
- };
+ }
+ // (import ./nix/tests inputs pkgsFor.${system})
+ );
+
+ packages = eachSystem (system: {
+ default = self.packages.${system}.hyprland;
+ inherit (pkgsFor.${system})
+ # hyprland-packages
+ hyprland
+ hyprland-unwrapped
+ hyprland-with-tests
+ # hyprland-extras
+ xdg-desktop-portal-hyprland
+ ;
+ inherit (pkgsDebugFor.${system}) hyprland-debug;
+ hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
+ hyprland-debug-cross = (pkgsDebugCrossFor.${system} "aarch64-linux").hyprland-debug;
+ });
+
+ devShells = eachSystem (system: {
+ default =
+ pkgsFor.${system}.mkShell.override
+ {
+ inherit (self.packages.${system}.default) stdenv;
+ }
+ {
+ name = "hyprland-shell";
+ hardeningDisable = [ "fortify" ];
+ inputsFrom = [ pkgsFor.${system}.hyprland ];
+ packages = [ pkgsFor.${system}.clang-tools ];
+ inherit (self.checks.${system}.pre-commit-check) shellHook;
+ };
+ });
+
+ formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix { });
+
+ nixosModules.default = import ./nix/module.nix inputs;
+ homeManagerModules.default = import ./nix/hm-module.nix self;
+
+ # Hydra build jobs
+ # Recent versions of Hydra can aggregate jobsets from 'hydraJobs' instead of a release.nix
+ # or similar. Remember to filter large or incompatible attributes here. More eval jobs can
+ # be added by merging, e.g., self.packages // self.devShells.
+ hydraJobs = self.packages;
+ };
}
diff --git a/nix/default.nix b/nix/default.nix
index eee38887..af1503f9 100644
--- a/nix/default.nix
+++ b/nix/default.nix
@@ -60,12 +60,23 @@
hidpiXWayland ? false,
legacyRenderer ? false,
withHyprtester ? false,
-}: let
+}:
+let
inherit (builtins) foldl' readFile;
inherit (lib.asserts) assertMsg;
inherit (lib.attrsets) mapAttrsToList;
- inherit (lib.lists) flatten concatLists optional optionals;
- inherit (lib.strings) makeBinPath optionalString cmakeBool trim;
+ inherit (lib.lists)
+ flatten
+ concatLists
+ optional
+ optionals
+ ;
+ inherit (lib.strings)
+ makeBinPath
+ optionalString
+ cmakeBool
+ trim
+ ;
fs = lib.fileset;
adapters = flatten [
@@ -75,22 +86,28 @@
customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters;
in
- assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
- assert assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
- assert assertMsg (!hidpiXWayland) "The option `hidpiXWayland` has been removed. Please refer https://wiki.hypr.land/Configuring/XWayland";
- assert assertMsg (!legacyRenderer) "The option `legacyRenderer` has been removed. Legacy renderer is no longer supported.";
- assert assertMsg (!withHyprtester) "The option `withHyprtester` has been removed. Hyprtester is always built now.";
- customStdenv.mkDerivation (finalAttrs: {
- pname = "hyprland${optionalString debug "-debug"}";
- inherit version withTests;
-
- src = fs.toSource {
- root = ../.;
- fileset =
- fs.intersection
- # allows non-flake builds to only include files tracked by git
- (fs.gitTracked ../.)
- (fs.unions (flatten [
+assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
+assert assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` has been removed.";
+assert assertMsg (!hidpiXWayland)
+ "The option `hidpiXWayland` has been removed. Please refer https://wiki.hypr.land/Configuring/XWayland";
+assert assertMsg (
+ !legacyRenderer
+) "The option `legacyRenderer` has been removed. Legacy renderer is no longer supported.";
+assert assertMsg (
+ !withHyprtester
+) "The option `withHyprtester` has been removed. Hyprtester is always built now.";
+customStdenv.mkDerivation (finalAttrs: {
+ pname = "hyprland${optionalString debug "-debug"}";
+ inherit version withTests;
+
+ src = fs.toSource {
+ root = ../.;
+ fileset =
+ fs.intersection
+ # allows non-flake builds to only include files tracked by git
+ (fs.gitTracked ../.)
+ (
+ fs.unions (flatten [
../assets/hyprland-portals.conf
../assets/install
../hyprctl
@@ -106,142 +123,145 @@ in
(fs.fileFilter (file: file.hasExt "conf" || file.hasExt "in") ../example)
(fs.fileFilter (file: file.hasExt "sh") ../scripts)
(fs.fileFilter (file: file.name == "CMakeLists.txt") ../.)
- (optional withTests [../tests ../hyprtester])
- ]));
- };
-
- postPatch = ''
- # Fix hardcoded paths to /usr installation
- sed -i "s#/usr#$out#" src/render/OpenGL.cpp
-
- # Remove extra @PREFIX@ to fix some paths
- sed -i "s#@PREFIX@/##g" hyprland.pc.in
- sed -i "s#@PREFIX@/##g" example/hyprland.desktop.in
- '';
-
- env = {
- GIT_COMMITS = revCount;
- GIT_COMMIT_DATE = date;
- GIT_COMMIT_HASH = commit;
- GIT_DIRTY = if (commit == "") then "clean" else "dirty";
- GIT_TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}";
- };
-
- depsBuildBuild = [
- pkg-config
- ];
-
- nativeBuildInputs = [
- hyprwayland-scanner
- hyprwire
- makeWrapper
- cmake
- pkg-config
- ];
-
- outputs = [
- "out"
- "man"
- "dev"
- ];
-
- buildInputs = concatLists [
- [
- aquamarine
- cairo
- git
- glaze-hyprland
- gtest
- hyprcursor
- hyprgraphics
- hyprland-protocols
- hyprlang
- hyprutils
- hyprwire
- libdrm
- libgbm
- libGL
- libinput
- libuuid
- libxcursor
- libxkbcommon
- muparser
- pango
- pciutils
- re2
- tomlplusplus
- udis86-hyprland
- wayland
- wayland-protocols
- wayland-scanner
- ]
- (optionals customStdenv.hostPlatform.isBSD [epoll-shim])
- (optionals customStdenv.hostPlatform.isMusl [libexecinfo])
- (optionals enableXWayland [
- libxcb
- libxcb-errors
- libxcb-render-util
- libxcb-wm
- libxdmcp
- xwayland
- ])
- (optional withSystemd systemd)
- ];
-
- strictDeps = true;
-
- cmakeBuildType =
- if debug
- then "Debug"
- else "RelWithDebInfo";
-
- # we want as much debug info as possible
- dontStrip = debug;
-
- cmakeFlags = mapAttrsToList cmakeBool {
- "BUILT_WITH_NIX" = true;
- "NO_XWAYLAND" = !enableXWayland;
- "LEGACY_RENDERER" = legacyRenderer;
- "NO_SYSTEMD" = !withSystemd;
- "CMAKE_DISABLE_PRECOMPILE_HEADERS" = true;
- "NO_UWSM" = !withSystemd;
- "TRACY_ENABLE" = false;
- "WITH_TESTS" = withTests;
- };
-
- preConfigure = ''
- substituteInPlace hyprtester/CMakeLists.txt --replace-fail \
- "\''${CMAKE_CURRENT_BINARY_DIR}" \
- "${placeholder "out"}/bin"
- '';
-
- postInstall = ''
- ${optionalString wrapRuntimeDeps ''
- wrapProgram $out/bin/Hyprland \
- --suffix PATH : ${makeBinPath [
+ (optional withTests [
+ ../tests
+ ../hyprtester
+ ])
+ ])
+ );
+ };
+
+ postPatch = ''
+ # Fix hardcoded paths to /usr installation
+ sed -i "s#/usr#$out#" src/render/OpenGL.cpp
+
+ # Remove extra @PREFIX@ to fix some paths
+ sed -i "s#@PREFIX@/##g" hyprland.pc.in
+ sed -i "s#@PREFIX@/##g" example/hyprland.desktop.in
+ '';
+
+ env = {
+ GIT_COMMITS = revCount;
+ GIT_COMMIT_DATE = date;
+ GIT_COMMIT_HASH = commit;
+ GIT_DIRTY = if (commit == "") then "clean" else "dirty";
+ GIT_TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}";
+ };
+
+ depsBuildBuild = [
+ pkg-config
+ ];
+
+ nativeBuildInputs = [
+ hyprwayland-scanner
+ hyprwire
+ makeWrapper
+ cmake
+ pkg-config
+ ];
+
+ outputs = [
+ "out"
+ "man"
+ "dev"
+ ];
+
+ buildInputs = concatLists [
+ [
+ aquamarine
+ cairo
+ git
+ glaze-hyprland
+ gtest
+ hyprcursor
+ hyprgraphics
+ hyprland-protocols
+ hyprlang
+ hyprutils
+ hyprwire
+ libdrm
+ libgbm
+ libGL
+ libinput
+ libuuid
+ libxcursor
+ libxkbcommon
+ muparser
+ pango
+ pciutils
+ re2
+ tomlplusplus
+ udis86-hyprland
+ wayland
+ wayland-protocols
+ wayland-scanner
+ ]
+ (optionals customStdenv.hostPlatform.isBSD [ epoll-shim ])
+ (optionals customStdenv.hostPlatform.isMusl [ libexecinfo ])
+ (optionals enableXWayland [
+ libxcb
+ libxcb-errors
+ libxcb-render-util
+ libxcb-wm
+ libxdmcp
+ xwayland
+ ])
+ (optional withSystemd systemd)
+ ];
+
+ strictDeps = true;
+
+ cmakeBuildType = if debug then "Debug" else "RelWithDebInfo";
+
+ # we want as much debug info as possible
+ dontStrip = debug;
+
+ cmakeFlags = mapAttrsToList cmakeBool {
+ "BUILT_WITH_NIX" = true;
+ "NO_XWAYLAND" = !enableXWayland;
+ "LEGACY_RENDERER" = legacyRenderer;
+ "NO_SYSTEMD" = !withSystemd;
+ "CMAKE_DISABLE_PRECOMPILE_HEADERS" = true;
+ "NO_UWSM" = !withSystemd;
+ "TRACY_ENABLE" = false;
+ "WITH_TESTS" = withTests;
+ };
+
+ preConfigure = ''
+ substituteInPlace hyprtester/CMakeLists.txt --replace-fail \
+ "\''${CMAKE_CURRENT_BINARY_DIR}" \
+ "${placeholder "out"}/bin"
+ '';
+
+ postInstall = ''
+ ${optionalString wrapRuntimeDeps ''
+ wrapProgram $out/bin/Hyprland \
+ --suffix PATH : ${
+ makeBinPath [
binutils
hyprland-guiutils
pciutils
pkgconf
- ]}
- ''}
-
- ${optionalString withTests ''
- install hyprtester/pointer-warp -t $out/bin
- install hyprtester/pointer-scroll -t $out/bin
- install hyprtester/shortcut-inhibitor -t $out/bin
- install hyprland_gtests -t $out/bin
- install hyprtester/child-window -t $out/bin
- ''}
- '';
-
- passthru.providedSessions = ["hyprland"] ++ optionals withSystemd ["hyprland-uwsm"];
-
- meta = {
- homepage = "https://github.com/hyprwm/Hyprland";
- description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
- license = lib.licenses.bsd3;
- platforms = lib.platforms.linux;
- mainProgram = "Hyprland";
- };
- })
+ ]
+ }
+ ''}
+
+ ${optionalString withTests ''
+ install hyprtester/pointer-warp -t $out/bin
+ install hyprtester/pointer-scroll -t $out/bin
+ install hyprtester/shortcut-inhibitor -t $out/bin
+ install hyprland_gtests -t $out/bin
+ install hyprtester/child-window -t $out/bin
+ ''}
+ '';
+
+ passthru.providedSessions = [ "hyprland" ] ++ optionals withSystemd [ "hyprland-uwsm" ];
+
+ meta = {
+ homepage = "https://github.com/hyprwm/Hyprland";
+ description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
+ license = lib.licenses.bsd3;
+ platforms = lib.platforms.linux;
+ mainProgram = "Hyprland";
+ };
+})
diff --git a/nix/formatter.nix b/nix/formatter.nix
index 66721c2c..ac340ae2 100644
--- a/nix/formatter.nix
+++ b/nix/formatter.nix
@@ -2,7 +2,7 @@
writeShellApplication,
deadnix,
statix,
- alejandra,
+ nixfmt,
llvmPackages_19,
fd,
}:
@@ -11,7 +11,7 @@ writeShellApplication {
runtimeInputs = [
deadnix
statix
- alejandra
+ nixfmt
llvmPackages_19.clang-tools
fd
];
@@ -24,14 +24,14 @@ writeShellApplication {
nix_format() {
if [ "$*" = 0 ]; then
fd '.*\.nix' . -E "$excludes" -x statix fix -- {} \;
- fd '.*\.nix' . -E "$excludes" -X deadnix -e -- {} \; -X alejandra {} \;
+ fd '.*\.nix' . -E "$excludes" -X deadnix -e -- {} \; -X nixfmt {} \;
elif [ -d "$1" ]; then
fd '.*\.nix' "$1" -E "$excludes" -i -x statix fix -- {} \;
- fd '.*\.nix' "$1" -E "$excludes" -i -X deadnix -e -- {} \; -X alejandra {} \;
+ fd '.*\.nix' "$1" -E "$excludes" -i -X deadnix -e -- {} \; -X nixfmt {} \;
else
statix fix -- "$1"
deadnix -e "$1"
- alejandra "$1"
+ nixfmt "$1"
fi
}
diff --git a/nix/hm-module.nix b/nix/hm-module.nix
index e3c788d0..948b8217 100644
--- a/nix/hm-module.nix
+++ b/nix/hm-module.nix
@@ -1,13 +1,15 @@
-self: {
- config,
+self:
+{
lib,
pkgs,
...
-}: let
+}:
+let
inherit (pkgs.stdenv.hostPlatform) system;
package = self.packages.${system}.default;
-in {
+in
+{
config = {
wayland.windowManager.hyprland.package = lib.mkDefault package;
};
diff --git a/nix/lib.nix b/nix/lib.nix
index ca3aadee..54d23440 100644
--- a/nix/lib.nix
+++ b/nix/lib.nix
@@ -1,4 +1,5 @@
-lib: let
+lib:
+let
inherit (lib)
attrNames
filterAttrs
@@ -17,7 +18,7 @@ lib: let
This function takes a nested attribute set and converts it into Hyprland-compatible
configuration syntax, supporting top, bottom, and regular command sections.
-
+
Commands are flattened using the `flattenAttrs` function, and attributes are formatted as
`key = value` pairs. Lists are expanded as duplicate keys to match Hyprland's expected format.
@@ -81,44 +82,51 @@ lib: let
:::
*/
- toHyprlang = {
- topCommandsPrefixes ? ["$" "bezier"],
- bottomCommandsPrefixes ? [],
- }: attrs: let
- toHyprlang' = attrs: let
- # Specially configured `toKeyValue` generator with support for duplicate keys
- # and a legible key-value separator.
- mkCommands = generators.toKeyValue {
- mkKeyValue = generators.mkKeyValueDefault {} " = ";
- listsAsDuplicateKeys = true;
- indent = ""; # No indent, since we don't have nesting
- };
-
- # Flatten the attrset, combining keys in a "path" like `"a:b:c" = "x"`.
- # Uses `flattenAttrs` with a colon separator.
- commands = flattenAttrs (p: k: "${p}:${k}") attrs;
-
- # General filtering function to check if a key starts with any prefix in a given list.
- filterCommands = list: n:
- foldl (acc: prefix: acc || hasPrefix prefix n) false list;
-
- # Partition keys into top commands and the rest
- result = partition (filterCommands topCommandsPrefixes) (attrNames commands);
- topCommands = filterAttrs (n: _: builtins.elem n result.right) commands;
- remainingCommands = removeAttrs commands result.right;
-
- # Partition remaining commands into bottom commands and regular commands
- result2 = partition (filterCommands bottomCommandsPrefixes) result.wrong;
- bottomCommands = filterAttrs (n: _: builtins.elem n result2.right) remainingCommands;
- regularCommands = removeAttrs remainingCommands result2.right;
+ toHyprlang =
+ {
+ topCommandsPrefixes ? [
+ "$"
+ "bezier"
+ ],
+ bottomCommandsPrefixes ? [ ],
+ }:
+ attrs:
+ let
+ toHyprlang' =
+ attrs:
+ let
+ # Specially configured `toKeyValue` generator with support for duplicate keys
+ # and a legible key-value separator.
+ mkCommands = generators.toKeyValue {
+ mkKeyValue = generators.mkKeyValueDefault { } " = ";
+ listsAsDuplicateKeys = true;
+ indent = ""; # No indent, since we don't have nesting
+ };
+
+ # Flatten the attrset, combining keys in a "path" like `"a:b:c" = "x"`.
+ # Uses `flattenAttrs` with a colon separator.
+ commands = flattenAttrs (p: k: "${p}:${k}") attrs;
+
+ # General filtering function to check if a key starts with any prefix in a given list.
+ filterCommands = list: n: foldl (acc: prefix: acc || hasPrefix prefix n) false list;
+
+ # Partition keys into top commands and the rest
+ result = partition (filterCommands topCommandsPrefixes) (attrNames commands);
+ topCommands = filterAttrs (n: _: builtins.elem n result.right) commands;
+ remainingCommands = removeAttrs commands result.right;
+
+ # Partition remaining commands into bottom commands and regular commands
+ result2 = partition (filterCommands bottomCommandsPrefixes) result.wrong;
+ bottomCommands = filterAttrs (n: _: builtins.elem n result2.right) remainingCommands;
+ regularCommands = removeAttrs remainingCommands result2.right;
+ in
+ # Concatenate strings from mapping `mkCommands` over top, regular, and bottom commands.
+ concatMapStrings mkCommands [
+ topCommands
+ regularCommands
+ bottomCommands
+ ];
in
- # Concatenate strings from mapping `mkCommands` over top, regular, and bottom commands.
- concatMapStrings mkCommands [
- topCommands
- regularCommands
- bottomCommands
- ];
- in
toHyprlang' attrs;
/**
@@ -131,7 +139,7 @@ lib: let
Configuration:
* `pred` - A function `(string -> string -> string)` defining how keys should be concatenated.
-
+
# Inputs
Structured function argument:
@@ -139,7 +147,7 @@ lib: let
: pred (required)
: A function that determines how parent and child keys should be combined into a single key.
It takes a `prefix` (parent key) and `key` (current key) and returns the joined key.
-
+
Value:
: The nested attribute set to be flattened.
@@ -174,26 +182,21 @@ lib: let
```
:::
-
*/
- flattenAttrs = pred: attrs: let
- flattenAttrs' = prefix: attrs:
- builtins.foldl' (
- acc: key: let
- value = attrs.${key};
- newKey =
- if prefix == ""
- then key
- else pred prefix key;
- in
- acc
- // (
- if builtins.isAttrs value
- then flattenAttrs' newKey value
- else {"${newKey}" = value;}
- )
- ) {} (builtins.attrNames attrs);
- in
+ flattenAttrs =
+ pred: attrs:
+ let
+ flattenAttrs' =
+ prefix: attrs:
+ builtins.foldl' (
+ acc: key:
+ let
+ value = attrs.${key};
+ newKey = if prefix == "" then key else pred prefix key;
+ in
+ acc // (if builtins.isAttrs value then flattenAttrs' newKey value else { "${newKey}" = value; })
+ ) { } (builtins.attrNames attrs);
+ in
flattenAttrs' "" attrs;
in
{
diff --git a/nix/module.nix b/nix/module.nix
index 91705347..32263943 100644
--- a/nix/module.nix
+++ b/nix/module.nix
@@ -1,18 +1,21 @@
-inputs: {
+inputs:
+{
config,
lib,
pkgs,
...
-}: let
+}:
+let
inherit (pkgs.stdenv.hostPlatform) system;
selflib = import ./lib.nix lib;
cfg = config.programs.hyprland;
-in {
+in
+{
options = {
programs.hyprland = {
plugins = lib.mkOption {
type = with lib.types; listOf (either package path);
- default = [];
+ default = [ ];
description = ''
List of Hyprland plugins to use. Can either be packages or
absolute plugin paths.
@@ -20,23 +23,25 @@ in {
};
settings = lib.mkOption {
- type = with lib.types; let
- valueType =
- nullOr (oneOf [
- bool
- int
- float
- str
- path
- (attrsOf valueType)
- (listOf valueType)
- ])
- // {
- description = "Hyprland configuration value";
- };
- in
+ type =
+ with lib.types;
+ let
+ valueType =
+ nullOr (oneOf [
+ bool
+ int
+ float
+ str
+ path
+ (attrsOf valueType)
+ (listOf valueType)
+ ])
+ // {
+ description = "Hyprland configuration value";
+ };
+ in
valueType;
- default = {};
+ default = { };
description = ''
Hyprland configuration written in Nix. Entries with the same key
should be written as lists. Variables' and colors' names should be
@@ -92,8 +97,15 @@ in {
topPrefixes = lib.mkOption {
type = with lib.types; listOf str;
- default = ["$" "bezier"];
- example = ["$" "bezier" "source"];
+ default = [
+ "$"
+ "bezier"
+ ];
+ example = [
+ "$"
+ "bezier"
+ "source"
+ ];
description = ''
List of prefix of attributes to put at the top of the config.
'';
@@ -101,8 +113,8 @@ in {
bottomPrefixes = lib.mkOption {
type = with lib.types; listOf str;
- default = [];
- example = ["source"];
+ default = [ ];
+ example = [ "source" ];
description = ''
List of prefix of attributes to put at the bottom of the config.
'';
@@ -117,35 +129,36 @@ in {
};
}
(lib.mkIf cfg.enable {
- environment.etc."xdg/hypr/hyprland.conf" = let
- shouldGenerate = cfg.extraConfig != "" || cfg.settings != {} || cfg.plugins != [];
+ environment.etc."xdg/hypr/hyprland.conf" =
+ let
+ shouldGenerate = cfg.extraConfig != "" || cfg.settings != { } || cfg.plugins != [ ];
- pluginsToHyprlang = plugins:
- selflib.toHyprlang {
- topCommandsPrefixes = cfg.topPrefixes;
- bottomCommandsPrefixes = cfg.bottomPrefixes;
- }
- {
- "exec-once" = let
- mkEntry = entry:
- if lib.types.package.check entry
- then "${entry}/lib/lib${entry.pname}.so"
- else entry;
- hyprctl = lib.getExe' config.programs.hyprland.package "hyprctl";
- in
- map (p: "${hyprctl} plugin load ${mkEntry p}") cfg.plugins;
- };
- in
+ pluginsToHyprlang =
+ _plugins:
+ selflib.toHyprlang
+ {
+ topCommandsPrefixes = cfg.topPrefixes;
+ bottomCommandsPrefixes = cfg.bottomPrefixes;
+ }
+ {
+ "exec-once" =
+ let
+ mkEntry =
+ entry: if lib.types.package.check entry then "${entry}/lib/lib${entry.pname}.so" else entry;
+ hyprctl = lib.getExe' config.programs.hyprland.package "hyprctl";
+ in
+ map (p: "${hyprctl} plugin load ${mkEntry p}") cfg.plugins;
+ };
+ in
lib.mkIf shouldGenerate {
text =
- lib.optionalString (cfg.plugins != [])
- (pluginsToHyprlang cfg.plugins)
- + lib.optionalString (cfg.settings != {})
- (selflib.toHyprlang {
+ lib.optionalString (cfg.plugins != [ ]) (pluginsToHyprlang cfg.plugins)
+ + lib.optionalString (cfg.settings != { }) (
+ selflib.toHyprlang {
topCommandsPrefixes = cfg.topPrefixes;
bottomCommandsPrefixes = cfg.bottomPrefixes;
- }
- cfg.settings)
+ } cfg.settings
+ )
+ lib.optionalString (cfg.extraConfig != "") cfg.extraConfig;
};
})
diff --git a/nix/overlays.nix b/nix/overlays.nix
index fdb3e652..0d157701 100644
--- a/nix/overlays.nix
+++ b/nix/overlays.nix
@@ -2,20 +2,27 @@
self,
lib,
inputs,
-}: let
- mkDate = longDate: (lib.concatStringsSep "-" [
- (builtins.substring 0 4 longDate)
- (builtins.substring 4 2 longDate)
- (builtins.substring 6 2 longDate)
- ]);
+}:
+let
+ mkDate =
+ longDate:
+ (lib.concatStringsSep "-" [
+ (builtins.substring 0 4 longDate)
+ (builtins.substring 4 2 longDate)
+ (builtins.substring 6 2 longDate)
+ ]);
ver = lib.removeSuffix "\n" (builtins.readFile ../VERSION);
-in {
+in
+{
# Contains what a user is most likely to care about:
# Hyprland itself, XDPH and the Share Picker.
- default = lib.composeManyExtensions (with self.overlays; [
- hyprland-packages
- hyprland-extras
- ]);
+ default = lib.composeManyExtensions (
+ with self.overlays;
+ [
+ hyprland-packages
+ hyprland-extras
+ ]
+ );
# Packages for variations of Hyprland, dependencies included.
hyprland-packages = lib.composeManyExtensions [
@@ -33,49 +40,45 @@ in {
self.overlays.glaze
# Hyprland packages themselves
- (final: _prev: let
- date = mkDate (self.lastModifiedDate or "19700101");
- version = "${ver}+date=${date}_${self.shortRev or "dirty"}";
- in {
- hyprland = final.callPackage ./default.nix {
- stdenv = final.gcc15Stdenv;
- commit = self.rev or "";
- revCount = self.sourceInfo.revCount or "";
- inherit date version;
- };
- hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;};
+ (
+ final: _prev:
+ let
+ date = mkDate (self.lastModifiedDate or "19700101");
+ version = "${ver}+date=${date}_${self.shortRev or "dirty"}";
+ in
+ {
+ hyprland = final.callPackage ./default.nix {
+ stdenv = final.gcc15Stdenv;
+ commit = self.rev or "";
+ revCount = self.sourceInfo.revCount or "";
+ inherit date version;
+ };
+ hyprland-unwrapped = final.hyprland.override { wrapRuntimeDeps = false; };
- hyprland-with-tests = final.hyprland.override {withTests = true;};
+ hyprland-with-tests = final.hyprland.override { withTests = true; };
- hyprland-with-hyprtester =
- builtins.trace ''
+ hyprland-with-hyprtester = builtins.trace ''
hyprland-with-hyprtester was removed. Please use the hyprland package.
Hyprtester is always built now.
- ''
- final.hyprland;
+ '' final.hyprland;
- # deprecated packages
- hyprland-legacy-renderer =
- builtins.trace ''
+ # deprecated packages
+ hyprland-legacy-renderer = builtins.trace ''
hyprland-legacy-renderer was removed. Please use the hyprland package.
Legacy renderer is no longer supported.
- ''
- final.hyprland;
+ '' final.hyprland;
- hyprland-nvidia =
- builtins.trace ''
+ hyprland-nvidia = builtins.trace ''
hyprland-nvidia was removed. Please use the hyprland package.
Nvidia patches are no longer needed.
- ''
- final.hyprland;
+ '' final.hyprland;
- hyprland-hidpi =
- builtins.trace ''
+ hyprland-hidpi = builtins.trace ''
hyprland-hidpi was removed. Please use the hyprland package.
For more information, refer to https://wiki.hypr.land/Configuring/XWayland.
- ''
- final.hyprland;
- })
+ '' final.hyprland;
+ }
+ )
];
# Debug
@@ -83,10 +86,10 @@ in {
# Dependencies
self.overlays.hyprland-packages
- (final: prev: {
- aquamarine = prev.aquamarine.override {debug = true;};
- hyprutils = prev.hyprutils.override {debug = true;};
- hyprland-debug = prev.hyprland.override {debug = true;};
+ (_final: prev: {
+ aquamarine = prev.aquamarine.override { debug = true; };
+ hyprutils = prev.hyprutils.override { debug = true; };
+ hyprland-debug = prev.hyprland.override { debug = true; };
})
];
@@ -100,21 +103,23 @@ in {
# this version is the one used in the git submodule, and allows us to
# fetch the source without '?submodules=1'
udis86 = final: prev: {
- udis86-hyprland = prev.udis86.overrideAttrs (_self: _super: {
- src = final.fetchFromGitHub {
- owner = "canihavesomecoffee";
- repo = "udis86";
- rev = "5336633af70f3917760a6d441ff02d93477b0c86";
- hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
- };
+ udis86-hyprland = prev.udis86.overrideAttrs (
+ _self: _super: {
+ src = final.fetchFromGitHub {
+ owner = "canihavesomecoffee";
+ repo = "udis86";
+ rev = "5336633af70f3917760a6d441ff02d93477b0c86";
+ hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
+ };
- patches = [];
- });
+ patches = [ ];
+ }
+ );
};
# Even though glaze itself disables it by default, nixpkgs sets ENABLE_SSL set to true.
# Since we don't include openssl, the build failes without the `enableSSL = false;` override
- glaze = final: prev: {
+ glaze = _final: prev: {
glaze-hyprland = prev.glaze.override {
enableSSL = false;
enableInterop = false;
diff --git a/nix/tests/default.nix b/nix/tests/default.nix
index 6052ee16..25c4077b 100644
--- a/nix/tests/default.nix
+++ b/nix/tests/default.nix
@@ -1,71 +1,75 @@
-inputs: pkgs: let
+inputs: pkgs:
+let
flake = inputs.self.packages.${pkgs.stdenv.hostPlatform.system};
hyprland = flake.hyprland-with-tests;
-in {
+in
+{
tests = pkgs.testers.runNixOSTest {
name = "hyprland-tests";
- nodes.machine = {pkgs, ...}: {
- environment.systemPackages = with pkgs; [
- # Programs needed for tests
- jq
- kitty
- wl-clipboard
- xeyes
- ];
-
- # Enabled by default for some reason
- services.speechd.enable = false;
-
- environment.variables = {
- "AQ_TRACE" = "1";
- "HYPRLAND_TRACE" = "1";
- "XDG_RUNTIME_DIR" = "/tmp";
- "XDG_CACHE_HOME" = "/tmp";
- "KITTY_CONFIG_DIRECTORY" = "/etc/kitty";
- };
-
- environment.etc."kitty/kitty.conf".text = ''
- confirm_os_window_close 0
- remember_window_size no
- initial_window_width 640
- initial_window_height 400
- '';
-
- programs.hyprland = {
- enable = true;
- package = hyprland;
- # We don't need portals in this test, so we don't set portalPackage
- };
+ nodes.machine =
+ { pkgs, ... }:
+ {
+ environment.systemPackages = with pkgs; [
+ # Programs needed for tests
+ jq
+ kitty
+ wl-clipboard
+ xeyes
+ ];
+
+ # Enabled by default for some reason
+ services.speechd.enable = false;
+
+ environment.variables = {
+ "AQ_TRACE" = "1";
+ "HYPRLAND_TRACE" = "1";
+ "XDG_RUNTIME_DIR" = "/tmp";
+ "XDG_CACHE_HOME" = "/tmp";
+ "KITTY_CONFIG_DIRECTORY" = "/etc/kitty";
+ };
- # Test configuration
- environment.etc."test.conf".source = "${hyprland}/share/hypr/test.conf";
+ environment.etc."kitty/kitty.conf".text = ''
+ confirm_os_window_close 0
+ remember_window_size no
+ initial_window_width 640
+ initial_window_height 400
+ '';
+
+ programs.hyprland = {
+ enable = true;
+ package = hyprland;
+ # We don't need portals in this test, so we don't set portalPackage
+ };
- # Disable portals
- xdg.portal.enable = pkgs.lib.mkForce false;
+ # Test configuration
+ environment.etc."test.conf".source = "${hyprland}/share/hypr/test.conf";
- # Autologin root into tty
- services.getty.autologinUser = "alice";
+ # Disable portals
+ xdg.portal.enable = pkgs.lib.mkForce false;
- system.stateVersion = "24.11";
+ # Autologin root into tty
+ services.getty.autologinUser = "alice";
- users.users.alice = {
- isNormalUser = true;
- };
+ system.stateVersion = "24.11";
- virtualisation = {
- cores = 4;
- # Might crash with less
- memorySize = 8192;
- resolution = {
- x = 1920;
- y = 1080;
+ users.users.alice = {
+ isNormalUser = true;
};
- # Doesn't seem to do much, thought it would fix XWayland crashing
- qemu.options = ["-vga none -device virtio-gpu-pci"];
+ virtualisation = {
+ cores = 4;
+ # Might crash with less
+ memorySize = 8192;
+ resolution = {
+ x = 1920;
+ y = 1080;
+ };
+
+ # Doesn't seem to do much, thought it would fix XWayland crashing
+ qemu.options = [ "-vga none -device virtio-gpu-pci" ];
+ };
};
- };
testScript = ''
# Wait for tty to be up