treewide: alejandra -> nixfmt

This commit is contained in:
Mihai Fufezan 2026-03-02 20:56:00 +02:00
parent d98f7ffaf5
commit 52ece2b017
No known key found for this signature in database
8 changed files with 521 additions and 460 deletions

206
flake.nix
View file

@ -88,108 +88,122 @@
}; };
}; };
outputs = inputs @ { outputs =
self, inputs@{
nixpkgs, self,
systems, nixpkgs,
... systems,
}: let ...
inherit (nixpkgs) lib; }:
eachSystem = lib.genAttrs (import systems); let
pkgsFor = eachSystem (system: inherit (nixpkgs) lib;
import nixpkgs { eachSystem = lib.genAttrs (import systems);
localSystem = system; pkgsFor = eachSystem (
overlays = with self.overlays; [ system:
hyprland-packages import nixpkgs {
hyprland-extras localSystem = system;
]; overlays = with self.overlays; [
}); hyprland-packages
pkgsCrossFor = eachSystem (system: crossSystem: hyprland-extras
import nixpkgs { ];
localSystem = system; }
inherit crossSystem; );
overlays = with self.overlays; [ pkgsCrossFor = eachSystem (
hyprland-packages system: crossSystem:
hyprland-extras import nixpkgs {
]; localSystem = system;
}); inherit crossSystem;
pkgsDebugFor = eachSystem (system: overlays = with self.overlays; [
import nixpkgs { hyprland-packages
localSystem = system; hyprland-extras
overlays = with self.overlays; [ ];
hyprland-debug }
]; );
}); pkgsDebugFor = eachSystem (
pkgsDebugCrossFor = eachSystem (system: crossSystem: system:
import nixpkgs { import nixpkgs {
localSystem = system; localSystem = system;
inherit crossSystem; overlays = with self.overlays; [
overlays = with self.overlays; [ hyprland-debug
hyprland-debug ];
]; }
}); );
in { pkgsDebugCrossFor = eachSystem (
overlays = import ./nix/overlays.nix {inherit self lib inputs;}; 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: checks = eachSystem (
(lib.filterAttrs system:
(n: _: (lib.hasPrefix "hyprland" n) && !(lib.hasSuffix "debug" n)) (lib.filterAttrs (
self.packages.${system}) 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 { inherit (self.packages.${system}) xdg-desktop-portal-hyprland;
src = ./.; pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
hooks = { src = ./.;
hyprland-treewide-formatter = { hooks = {
enable = true; hyprland-treewide-formatter = {
entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter"; enable = true;
pass_filenames = false; entry = "${self.formatter.${system}}/bin/hyprland-treewide-formatter";
excludes = ["subprojects"]; pass_filenames = false;
always_run = true; excludes = [ "subprojects" ];
always_run = true;
};
}; };
}; };
}; }
} // (import ./nix/tests inputs pkgsFor.${system})
// (import ./nix/tests inputs pkgsFor.${system})); );
packages = eachSystem (system: { packages = eachSystem (system: {
default = self.packages.${system}.hyprland; default = self.packages.${system}.hyprland;
inherit inherit (pkgsFor.${system})
(pkgsFor.${system}) # hyprland-packages
# hyprland-packages hyprland
hyprland hyprland-unwrapped
hyprland-unwrapped hyprland-with-tests
hyprland-with-tests # hyprland-extras
# hyprland-extras xdg-desktop-portal-hyprland
xdg-desktop-portal-hyprland ;
; inherit (pkgsDebugFor.${system}) hyprland-debug;
inherit (pkgsDebugFor.${system}) hyprland-debug; hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland;
hyprland-cross = (pkgsCrossFor.${system} "aarch64-linux").hyprland; hyprland-debug-cross = (pkgsDebugCrossFor.${system} "aarch64-linux").hyprland-debug;
hyprland-debug-cross = (pkgsDebugCrossFor.${system} "aarch64-linux").hyprland-debug; });
});
devShells = eachSystem (system: { devShells = eachSystem (system: {
default = default =
pkgsFor.${system}.mkShell.override { pkgsFor.${system}.mkShell.override
inherit (self.packages.${system}.default) stdenv; {
} { inherit (self.packages.${system}.default) stdenv;
name = "hyprland-shell"; }
hardeningDisable = ["fortify"]; {
inputsFrom = [pkgsFor.${system}.hyprland]; name = "hyprland-shell";
packages = [pkgsFor.${system}.clang-tools]; hardeningDisable = [ "fortify" ];
inherit (self.checks.${system}.pre-commit-check) shellHook; 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 {}); formatter = eachSystem (system: pkgsFor.${system}.callPackage ./nix/formatter.nix { });
nixosModules.default = import ./nix/module.nix inputs; nixosModules.default = import ./nix/module.nix inputs;
homeManagerModules.default = import ./nix/hm-module.nix self; homeManagerModules.default = import ./nix/hm-module.nix self;
# Hydra build jobs # Hydra build jobs
# Recent versions of Hydra can aggregate jobsets from 'hydraJobs' instead of a release.nix # 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 # or similar. Remember to filter large or incompatible attributes here. More eval jobs can
# be added by merging, e.g., self.packages // self.devShells. # be added by merging, e.g., self.packages // self.devShells.
hydraJobs = self.packages; hydraJobs = self.packages;
}; };
} }

View file

@ -60,12 +60,23 @@
hidpiXWayland ? false, hidpiXWayland ? false,
legacyRenderer ? false, legacyRenderer ? false,
withHyprtester ? false, withHyprtester ? false,
}: let }:
let
inherit (builtins) foldl' readFile; inherit (builtins) foldl' readFile;
inherit (lib.asserts) assertMsg; inherit (lib.asserts) assertMsg;
inherit (lib.attrsets) mapAttrsToList; inherit (lib.attrsets) mapAttrsToList;
inherit (lib.lists) flatten concatLists optional optionals; inherit (lib.lists)
inherit (lib.strings) makeBinPath optionalString cmakeBool trim; flatten
concatLists
optional
optionals
;
inherit (lib.strings)
makeBinPath
optionalString
cmakeBool
trim
;
fs = lib.fileset; fs = lib.fileset;
adapters = flatten [ adapters = flatten [
@ -75,22 +86,28 @@
customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters; customStdenv = foldl' (acc: adapter: adapter acc) stdenv adapters;
in in
assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed."; assert assertMsg (!nvidiaPatches) "The option `nvidiaPatches` has been removed.";
assert assertMsg (!enableNvidiaPatches) "The option `enableNvidiaPatches` 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 (!hidpiXWayland)
assert assertMsg (!legacyRenderer) "The option `legacyRenderer` has been removed. Legacy renderer is no longer supported."; "The option `hidpiXWayland` has been removed. Please refer https://wiki.hypr.land/Configuring/XWayland";
assert assertMsg (!withHyprtester) "The option `withHyprtester` has been removed. Hyprtester is always built now."; assert assertMsg (
customStdenv.mkDerivation (finalAttrs: { !legacyRenderer
pname = "hyprland${optionalString debug "-debug"}"; ) "The option `legacyRenderer` has been removed. Legacy renderer is no longer supported.";
inherit version withTests; 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 { src = fs.toSource {
root = ../.; root = ../.;
fileset = fileset =
fs.intersection fs.intersection
# allows non-flake builds to only include files tracked by git # allows non-flake builds to only include files tracked by git
(fs.gitTracked ../.) (fs.gitTracked ../.)
(fs.unions (flatten [ (
fs.unions (flatten [
../assets/hyprland-portals.conf ../assets/hyprland-portals.conf
../assets/install ../assets/install
../hyprctl ../hyprctl
@ -106,142 +123,145 @@ in
(fs.fileFilter (file: file.hasExt "conf" || file.hasExt "in") ../example) (fs.fileFilter (file: file.hasExt "conf" || file.hasExt "in") ../example)
(fs.fileFilter (file: file.hasExt "sh") ../scripts) (fs.fileFilter (file: file.hasExt "sh") ../scripts)
(fs.fileFilter (file: file.name == "CMakeLists.txt") ../.) (fs.fileFilter (file: file.name == "CMakeLists.txt") ../.)
(optional withTests [../tests ../hyprtester]) (optional withTests [
])); ../tests
}; ../hyprtester
])
])
);
};
postPatch = '' postPatch = ''
# Fix hardcoded paths to /usr installation # Fix hardcoded paths to /usr installation
sed -i "s#/usr#$out#" src/render/OpenGL.cpp sed -i "s#/usr#$out#" src/render/OpenGL.cpp
# Remove extra @PREFIX@ to fix some paths # Remove extra @PREFIX@ to fix some paths
sed -i "s#@PREFIX@/##g" hyprland.pc.in sed -i "s#@PREFIX@/##g" hyprland.pc.in
sed -i "s#@PREFIX@/##g" example/hyprland.desktop.in sed -i "s#@PREFIX@/##g" example/hyprland.desktop.in
''; '';
env = { env = {
GIT_COMMITS = revCount; GIT_COMMITS = revCount;
GIT_COMMIT_DATE = date; GIT_COMMIT_DATE = date;
GIT_COMMIT_HASH = commit; GIT_COMMIT_HASH = commit;
GIT_DIRTY = if (commit == "") then "clean" else "dirty"; GIT_DIRTY = if (commit == "") then "clean" else "dirty";
GIT_TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}"; GIT_TAG = "v${trim (readFile "${finalAttrs.src}/VERSION")}";
}; };
depsBuildBuild = [ depsBuildBuild = [
pkg-config pkg-config
]; ];
nativeBuildInputs = [ nativeBuildInputs = [
hyprwayland-scanner hyprwayland-scanner
hyprwire hyprwire
makeWrapper makeWrapper
cmake cmake
pkg-config pkg-config
]; ];
outputs = [ outputs = [
"out" "out"
"man" "man"
"dev" "dev"
]; ];
buildInputs = concatLists [ buildInputs = concatLists [
[ [
aquamarine aquamarine
cairo cairo
git git
glaze-hyprland glaze-hyprland
gtest gtest
hyprcursor hyprcursor
hyprgraphics hyprgraphics
hyprland-protocols hyprland-protocols
hyprlang hyprlang
hyprutils hyprutils
hyprwire hyprwire
libdrm libdrm
libgbm libgbm
libGL libGL
libinput libinput
libuuid libuuid
libxcursor libxcursor
libxkbcommon libxkbcommon
muparser muparser
pango pango
pciutils pciutils
re2 re2
tomlplusplus tomlplusplus
udis86-hyprland udis86-hyprland
wayland wayland
wayland-protocols wayland-protocols
wayland-scanner wayland-scanner
] ]
(optionals customStdenv.hostPlatform.isBSD [epoll-shim]) (optionals customStdenv.hostPlatform.isBSD [ epoll-shim ])
(optionals customStdenv.hostPlatform.isMusl [libexecinfo]) (optionals customStdenv.hostPlatform.isMusl [ libexecinfo ])
(optionals enableXWayland [ (optionals enableXWayland [
libxcb libxcb
libxcb-errors libxcb-errors
libxcb-render-util libxcb-render-util
libxcb-wm libxcb-wm
libxdmcp libxdmcp
xwayland xwayland
]) ])
(optional withSystemd systemd) (optional withSystemd systemd)
]; ];
strictDeps = true; strictDeps = true;
cmakeBuildType = cmakeBuildType = if debug then "Debug" else "RelWithDebInfo";
if debug
then "Debug"
else "RelWithDebInfo";
# we want as much debug info as possible # we want as much debug info as possible
dontStrip = debug; dontStrip = debug;
cmakeFlags = mapAttrsToList cmakeBool { cmakeFlags = mapAttrsToList cmakeBool {
"BUILT_WITH_NIX" = true; "BUILT_WITH_NIX" = true;
"NO_XWAYLAND" = !enableXWayland; "NO_XWAYLAND" = !enableXWayland;
"LEGACY_RENDERER" = legacyRenderer; "LEGACY_RENDERER" = legacyRenderer;
"NO_SYSTEMD" = !withSystemd; "NO_SYSTEMD" = !withSystemd;
"CMAKE_DISABLE_PRECOMPILE_HEADERS" = true; "CMAKE_DISABLE_PRECOMPILE_HEADERS" = true;
"NO_UWSM" = !withSystemd; "NO_UWSM" = !withSystemd;
"TRACY_ENABLE" = false; "TRACY_ENABLE" = false;
"WITH_TESTS" = withTests; "WITH_TESTS" = withTests;
}; };
preConfigure = '' preConfigure = ''
substituteInPlace hyprtester/CMakeLists.txt --replace-fail \ substituteInPlace hyprtester/CMakeLists.txt --replace-fail \
"\''${CMAKE_CURRENT_BINARY_DIR}" \ "\''${CMAKE_CURRENT_BINARY_DIR}" \
"${placeholder "out"}/bin" "${placeholder "out"}/bin"
''; '';
postInstall = '' postInstall = ''
${optionalString wrapRuntimeDeps '' ${optionalString wrapRuntimeDeps ''
wrapProgram $out/bin/Hyprland \ wrapProgram $out/bin/Hyprland \
--suffix PATH : ${makeBinPath [ --suffix PATH : ${
makeBinPath [
binutils binutils
hyprland-guiutils hyprland-guiutils
pciutils pciutils
pkgconf pkgconf
]} ]
''} }
''}
${optionalString withTests '' ${optionalString withTests ''
install hyprtester/pointer-warp -t $out/bin install hyprtester/pointer-warp -t $out/bin
install hyprtester/pointer-scroll -t $out/bin install hyprtester/pointer-scroll -t $out/bin
install hyprtester/shortcut-inhibitor -t $out/bin install hyprtester/shortcut-inhibitor -t $out/bin
install hyprland_gtests -t $out/bin install hyprland_gtests -t $out/bin
install hyprtester/child-window -t $out/bin install hyprtester/child-window -t $out/bin
''} ''}
''; '';
passthru.providedSessions = ["hyprland"] ++ optionals withSystemd ["hyprland-uwsm"]; passthru.providedSessions = [ "hyprland" ] ++ optionals withSystemd [ "hyprland-uwsm" ];
meta = { meta = {
homepage = "https://github.com/hyprwm/Hyprland"; homepage = "https://github.com/hyprwm/Hyprland";
description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks"; description = "Dynamic tiling Wayland compositor that doesn't sacrifice on its looks";
license = lib.licenses.bsd3; license = lib.licenses.bsd3;
platforms = lib.platforms.linux; platforms = lib.platforms.linux;
mainProgram = "Hyprland"; mainProgram = "Hyprland";
}; };
}) })

View file

@ -2,7 +2,7 @@
writeShellApplication, writeShellApplication,
deadnix, deadnix,
statix, statix,
alejandra, nixfmt,
llvmPackages_19, llvmPackages_19,
fd, fd,
}: }:
@ -11,7 +11,7 @@ writeShellApplication {
runtimeInputs = [ runtimeInputs = [
deadnix deadnix
statix statix
alejandra nixfmt
llvmPackages_19.clang-tools llvmPackages_19.clang-tools
fd fd
]; ];
@ -24,14 +24,14 @@ writeShellApplication {
nix_format() { nix_format() {
if [ "$*" = 0 ]; then if [ "$*" = 0 ]; then
fd '.*\.nix' . -E "$excludes" -x statix fix -- {} \; 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 elif [ -d "$1" ]; then
fd '.*\.nix' "$1" -E "$excludes" -i -x statix fix -- {} \; 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 else
statix fix -- "$1" statix fix -- "$1"
deadnix -e "$1" deadnix -e "$1"
alejandra "$1" nixfmt "$1"
fi fi
} }

View file

@ -1,13 +1,15 @@
self: { self:
config, {
lib, lib,
pkgs, pkgs,
... ...
}: let }:
let
inherit (pkgs.stdenv.hostPlatform) system; inherit (pkgs.stdenv.hostPlatform) system;
package = self.packages.${system}.default; package = self.packages.${system}.default;
in { in
{
config = { config = {
wayland.windowManager.hyprland.package = lib.mkDefault package; wayland.windowManager.hyprland.package = lib.mkDefault package;
}; };

View file

@ -1,4 +1,5 @@
lib: let lib:
let
inherit (lib) inherit (lib)
attrNames attrNames
filterAttrs filterAttrs
@ -81,44 +82,51 @@ lib: let
::: :::
*/ */
toHyprlang = { toHyprlang =
topCommandsPrefixes ? ["$" "bezier"], {
bottomCommandsPrefixes ? [], topCommandsPrefixes ? [
}: attrs: let "$"
toHyprlang' = attrs: let "bezier"
# Specially configured `toKeyValue` generator with support for duplicate keys ],
# and a legible key-value separator. bottomCommandsPrefixes ? [ ],
mkCommands = generators.toKeyValue { }:
mkKeyValue = generators.mkKeyValueDefault {} " = "; attrs:
listsAsDuplicateKeys = true; let
indent = ""; # No indent, since we don't have nesting 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"`. # Flatten the attrset, combining keys in a "path" like `"a:b:c" = "x"`.
# Uses `flattenAttrs` with a colon separator. # Uses `flattenAttrs` with a colon separator.
commands = flattenAttrs (p: k: "${p}:${k}") attrs; commands = flattenAttrs (p: k: "${p}:${k}") attrs;
# General filtering function to check if a key starts with any prefix in a given list. # General filtering function to check if a key starts with any prefix in a given list.
filterCommands = list: n: filterCommands = list: n: foldl (acc: prefix: acc || hasPrefix prefix n) false list;
foldl (acc: prefix: acc || hasPrefix prefix n) false list;
# Partition keys into top commands and the rest # Partition keys into top commands and the rest
result = partition (filterCommands topCommandsPrefixes) (attrNames commands); result = partition (filterCommands topCommandsPrefixes) (attrNames commands);
topCommands = filterAttrs (n: _: builtins.elem n result.right) commands; topCommands = filterAttrs (n: _: builtins.elem n result.right) commands;
remainingCommands = removeAttrs commands result.right; remainingCommands = removeAttrs commands result.right;
# Partition remaining commands into bottom commands and regular commands # Partition remaining commands into bottom commands and regular commands
result2 = partition (filterCommands bottomCommandsPrefixes) result.wrong; result2 = partition (filterCommands bottomCommandsPrefixes) result.wrong;
bottomCommands = filterAttrs (n: _: builtins.elem n result2.right) remainingCommands; bottomCommands = filterAttrs (n: _: builtins.elem n result2.right) remainingCommands;
regularCommands = removeAttrs remainingCommands result2.right; regularCommands = removeAttrs remainingCommands result2.right;
in
# Concatenate strings from mapping `mkCommands` over top, regular, and bottom commands.
concatMapStrings mkCommands [
topCommands
regularCommands
bottomCommands
];
in in
# Concatenate strings from mapping `mkCommands` over top, regular, and bottom commands.
concatMapStrings mkCommands [
topCommands
regularCommands
bottomCommands
];
in
toHyprlang' attrs; toHyprlang' attrs;
/** /**
@ -174,26 +182,21 @@ lib: let
``` ```
::: :::
*/ */
flattenAttrs = pred: attrs: let flattenAttrs =
flattenAttrs' = prefix: attrs: pred: attrs:
builtins.foldl' ( let
acc: key: let flattenAttrs' =
value = attrs.${key}; prefix: attrs:
newKey = builtins.foldl' (
if prefix == "" acc: key:
then key let
else pred prefix key; value = attrs.${key};
in newKey = if prefix == "" then key else pred prefix key;
acc in
// ( acc // (if builtins.isAttrs value then flattenAttrs' newKey value else { "${newKey}" = value; })
if builtins.isAttrs value ) { } (builtins.attrNames attrs);
then flattenAttrs' newKey value in
else {"${newKey}" = value;}
)
) {} (builtins.attrNames attrs);
in
flattenAttrs' "" attrs; flattenAttrs' "" attrs;
in in
{ {

View file

@ -1,18 +1,21 @@
inputs: { inputs:
{
config, config,
lib, lib,
pkgs, pkgs,
... ...
}: let }:
let
inherit (pkgs.stdenv.hostPlatform) system; inherit (pkgs.stdenv.hostPlatform) system;
selflib = import ./lib.nix lib; selflib = import ./lib.nix lib;
cfg = config.programs.hyprland; cfg = config.programs.hyprland;
in { in
{
options = { options = {
programs.hyprland = { programs.hyprland = {
plugins = lib.mkOption { plugins = lib.mkOption {
type = with lib.types; listOf (either package path); type = with lib.types; listOf (either package path);
default = []; default = [ ];
description = '' description = ''
List of Hyprland plugins to use. Can either be packages or List of Hyprland plugins to use. Can either be packages or
absolute plugin paths. absolute plugin paths.
@ -20,23 +23,25 @@ in {
}; };
settings = lib.mkOption { settings = lib.mkOption {
type = with lib.types; let type =
valueType = with lib.types;
nullOr (oneOf [ let
bool valueType =
int nullOr (oneOf [
float bool
str int
path float
(attrsOf valueType) str
(listOf valueType) path
]) (attrsOf valueType)
// { (listOf valueType)
description = "Hyprland configuration value"; ])
}; // {
in description = "Hyprland configuration value";
};
in
valueType; valueType;
default = {}; default = { };
description = '' description = ''
Hyprland configuration written in Nix. Entries with the same key Hyprland configuration written in Nix. Entries with the same key
should be written as lists. Variables' and colors' names should be should be written as lists. Variables' and colors' names should be
@ -92,8 +97,15 @@ in {
topPrefixes = lib.mkOption { topPrefixes = lib.mkOption {
type = with lib.types; listOf str; type = with lib.types; listOf str;
default = ["$" "bezier"]; default = [
example = ["$" "bezier" "source"]; "$"
"bezier"
];
example = [
"$"
"bezier"
"source"
];
description = '' description = ''
List of prefix of attributes to put at the top of the config. List of prefix of attributes to put at the top of the config.
''; '';
@ -101,8 +113,8 @@ in {
bottomPrefixes = lib.mkOption { bottomPrefixes = lib.mkOption {
type = with lib.types; listOf str; type = with lib.types; listOf str;
default = []; default = [ ];
example = ["source"]; example = [ "source" ];
description = '' description = ''
List of prefix of attributes to put at the bottom of the config. List of prefix of attributes to put at the bottom of the config.
''; '';
@ -117,35 +129,36 @@ in {
}; };
} }
(lib.mkIf cfg.enable { (lib.mkIf cfg.enable {
environment.etc."xdg/hypr/hyprland.conf" = let environment.etc."xdg/hypr/hyprland.conf" =
shouldGenerate = cfg.extraConfig != "" || cfg.settings != {} || cfg.plugins != []; let
shouldGenerate = cfg.extraConfig != "" || cfg.settings != { } || cfg.plugins != [ ];
pluginsToHyprlang = plugins: pluginsToHyprlang =
selflib.toHyprlang { _plugins:
topCommandsPrefixes = cfg.topPrefixes; selflib.toHyprlang
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 {
topCommandsPrefixes = cfg.topPrefixes; topCommandsPrefixes = cfg.topPrefixes;
bottomCommandsPrefixes = cfg.bottomPrefixes; bottomCommandsPrefixes = cfg.bottomPrefixes;
} }
cfg.settings) {
"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 {
topCommandsPrefixes = cfg.topPrefixes;
bottomCommandsPrefixes = cfg.bottomPrefixes;
} cfg.settings
)
+ lib.optionalString (cfg.extraConfig != "") cfg.extraConfig; + lib.optionalString (cfg.extraConfig != "") cfg.extraConfig;
}; };
}) })

View file

@ -2,20 +2,27 @@
self, self,
lib, lib,
inputs, inputs,
}: let }:
mkDate = longDate: (lib.concatStringsSep "-" [ let
(builtins.substring 0 4 longDate) mkDate =
(builtins.substring 4 2 longDate) longDate:
(builtins.substring 6 2 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); ver = lib.removeSuffix "\n" (builtins.readFile ../VERSION);
in { in
{
# Contains what a user is most likely to care about: # Contains what a user is most likely to care about:
# Hyprland itself, XDPH and the Share Picker. # Hyprland itself, XDPH and the Share Picker.
default = lib.composeManyExtensions (with self.overlays; [ default = lib.composeManyExtensions (
hyprland-packages with self.overlays;
hyprland-extras [
]); hyprland-packages
hyprland-extras
]
);
# Packages for variations of Hyprland, dependencies included. # Packages for variations of Hyprland, dependencies included.
hyprland-packages = lib.composeManyExtensions [ hyprland-packages = lib.composeManyExtensions [
@ -33,49 +40,45 @@ in {
self.overlays.glaze self.overlays.glaze
# Hyprland packages themselves # Hyprland packages themselves
(final: _prev: let (
date = mkDate (self.lastModifiedDate or "19700101"); final: _prev:
version = "${ver}+date=${date}_${self.shortRev or "dirty"}"; let
in { date = mkDate (self.lastModifiedDate or "19700101");
hyprland = final.callPackage ./default.nix { version = "${ver}+date=${date}_${self.shortRev or "dirty"}";
stdenv = final.gcc15Stdenv; in
commit = self.rev or ""; {
revCount = self.sourceInfo.revCount or ""; hyprland = final.callPackage ./default.nix {
inherit date version; stdenv = final.gcc15Stdenv;
}; commit = self.rev or "";
hyprland-unwrapped = final.hyprland.override {wrapRuntimeDeps = false;}; 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 = hyprland-with-hyprtester = builtins.trace ''
builtins.trace ''
hyprland-with-hyprtester was removed. Please use the hyprland package. hyprland-with-hyprtester was removed. Please use the hyprland package.
Hyprtester is always built now. Hyprtester is always built now.
'' '' final.hyprland;
final.hyprland;
# deprecated packages # deprecated packages
hyprland-legacy-renderer = hyprland-legacy-renderer = builtins.trace ''
builtins.trace ''
hyprland-legacy-renderer was removed. Please use the hyprland package. hyprland-legacy-renderer was removed. Please use the hyprland package.
Legacy renderer is no longer supported. Legacy renderer is no longer supported.
'' '' final.hyprland;
final.hyprland;
hyprland-nvidia = hyprland-nvidia = builtins.trace ''
builtins.trace ''
hyprland-nvidia was removed. Please use the hyprland package. hyprland-nvidia was removed. Please use the hyprland package.
Nvidia patches are no longer needed. Nvidia patches are no longer needed.
'' '' final.hyprland;
final.hyprland;
hyprland-hidpi = hyprland-hidpi = builtins.trace ''
builtins.trace ''
hyprland-hidpi was removed. Please use the hyprland package. hyprland-hidpi was removed. Please use the hyprland package.
For more information, refer to https://wiki.hypr.land/Configuring/XWayland. For more information, refer to https://wiki.hypr.land/Configuring/XWayland.
'' '' final.hyprland;
final.hyprland; }
}) )
]; ];
# Debug # Debug
@ -83,10 +86,10 @@ in {
# Dependencies # Dependencies
self.overlays.hyprland-packages self.overlays.hyprland-packages
(final: prev: { (_final: prev: {
aquamarine = prev.aquamarine.override {debug = true;}; aquamarine = prev.aquamarine.override { debug = true; };
hyprutils = prev.hyprutils.override {debug = true;}; hyprutils = prev.hyprutils.override { debug = true; };
hyprland-debug = prev.hyprland.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 # this version is the one used in the git submodule, and allows us to
# fetch the source without '?submodules=1' # fetch the source without '?submodules=1'
udis86 = final: prev: { udis86 = final: prev: {
udis86-hyprland = prev.udis86.overrideAttrs (_self: _super: { udis86-hyprland = prev.udis86.overrideAttrs (
src = final.fetchFromGitHub { _self: _super: {
owner = "canihavesomecoffee"; src = final.fetchFromGitHub {
repo = "udis86"; owner = "canihavesomecoffee";
rev = "5336633af70f3917760a6d441ff02d93477b0c86"; repo = "udis86";
hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g="; rev = "5336633af70f3917760a6d441ff02d93477b0c86";
}; hash = "sha256-HifdUQPGsKQKQprByeIznvRLONdOXeolOsU5nkwIv3g=";
};
patches = []; patches = [ ];
}); }
);
}; };
# Even though glaze itself disables it by default, nixpkgs sets ENABLE_SSL set to true. # 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 # 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 { glaze-hyprland = prev.glaze.override {
enableSSL = false; enableSSL = false;
enableInterop = false; enableInterop = false;

View file

@ -1,71 +1,75 @@
inputs: pkgs: let inputs: pkgs:
let
flake = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}; flake = inputs.self.packages.${pkgs.stdenv.hostPlatform.system};
hyprland = flake.hyprland-with-tests; hyprland = flake.hyprland-with-tests;
in { in
{
tests = pkgs.testers.runNixOSTest { tests = pkgs.testers.runNixOSTest {
name = "hyprland-tests"; name = "hyprland-tests";
nodes.machine = {pkgs, ...}: { nodes.machine =
environment.systemPackages = with pkgs; [ { pkgs, ... }:
# Programs needed for tests {
jq environment.systemPackages = with pkgs; [
kitty # Programs needed for tests
wl-clipboard jq
xeyes kitty
]; wl-clipboard
xeyes
];
# Enabled by default for some reason # Enabled by default for some reason
services.speechd.enable = false; services.speechd.enable = false;
environment.variables = { environment.variables = {
"AQ_TRACE" = "1"; "AQ_TRACE" = "1";
"HYPRLAND_TRACE" = "1"; "HYPRLAND_TRACE" = "1";
"XDG_RUNTIME_DIR" = "/tmp"; "XDG_RUNTIME_DIR" = "/tmp";
"XDG_CACHE_HOME" = "/tmp"; "XDG_CACHE_HOME" = "/tmp";
"KITTY_CONFIG_DIRECTORY" = "/etc/kitty"; "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
};
# Test configuration
environment.etc."test.conf".source = "${hyprland}/share/hypr/test.conf";
# Disable portals
xdg.portal.enable = pkgs.lib.mkForce false;
# Autologin root into tty
services.getty.autologinUser = "alice";
system.stateVersion = "24.11";
users.users.alice = {
isNormalUser = true;
};
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 environment.etc."kitty/kitty.conf".text = ''
qemu.options = ["-vga none -device virtio-gpu-pci"]; 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
};
# Test configuration
environment.etc."test.conf".source = "${hyprland}/share/hypr/test.conf";
# Disable portals
xdg.portal.enable = pkgs.lib.mkForce false;
# Autologin root into tty
services.getty.autologinUser = "alice";
system.stateVersion = "24.11";
users.users.alice = {
isNormalUser = true;
};
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 = '' testScript = ''
# Wait for tty to be up # Wait for tty to be up