diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index 6319d635..dbbca455 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -1618,6 +1618,17 @@ in {
https://github.com/fastfetch-cli/fastfetch for more.
'';
}
+
+ {
+ time = "2024-05-10T11:48:34+00:00";
+ condition = hostPlatform.isLinux;
+ message = ''
+ A new module is available: 'programs.hyprlock'.
+
+ Hyprland's simple, yet multi-threaded and GPU-accelerated screen
+ locking utility. See https://github.com/hyprwm/hyprlock for more.
+ '';
+ }
];
};
}
diff --git a/modules/modules.nix b/modules/modules.nix
index 22664091..05692356 100644
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -118,6 +118,7 @@ let
./programs/hstr.nix
./programs/htop.nix
./programs/hyfetch.nix
+ ./programs/hyprlock.nix
./programs/i3blocks.nix
./programs/i3status-rust.nix
./programs/i3status.nix
diff --git a/modules/programs/hyprlock.nix b/modules/programs/hyprlock.nix
new file mode 100644
index 00000000..25d87188
--- /dev/null
+++ b/modules/programs/hyprlock.nix
@@ -0,0 +1,127 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+ cfg = config.programs.hyprlock;
+
+in {
+ meta.maintainers = [ maintainers.khaneliman maintainers.fufexan ];
+
+ options.programs.hyprlock = {
+ enable = mkEnableOption "" // {
+ description = ''
+ Whether to enable Hyprlock, Hyprland's GPU-accelerated lock screen
+ utility.
+
+ Note that PAM must be configured to enable hyprlock to perform
+ authentication. The package installed through home-manager will *not* be
+ able to unlock the session without this configuration.
+
+ On NixOS, it can be enabled using:
+
+ ```nix
+ security.pam.services.hyprlock = {};
+ ```
+ '';
+ };
+
+ package = mkPackageOption pkgs "hyprlock" { };
+
+ settings = lib.mkOption {
+ type = with lib.types;
+ let
+ valueType = nullOr (oneOf [
+ bool
+ int
+ float
+ str
+ path
+ (attrsOf valueType)
+ (listOf valueType)
+ ]) // {
+ description = "Hyprlock configuration value";
+ };
+ in valueType;
+ default = { };
+ example = lib.literalExpression ''
+ {
+ general = {
+ disable_loading_bar = true;
+ grace = 300;
+ hide_cursor = true;
+ no_fade_in = false;
+ };
+
+ background = [
+ {
+ path = "screenshot";
+ blur_passes = 3;
+ blur_size = 8;
+ }
+ ];
+
+ input-field = [
+ {
+ size = "200, 50";
+ position = "0, -80";
+ monitor = "";
+ dots_center = true;
+ fade_on_empty = false;
+ font_color = "rgb(202, 211, 245)";
+ inner_color = "rgb(91, 96, 120)";
+ outer_color = "rgb(24, 25, 38)";
+ outline_thickness = 5;
+ placeholder_text = '\'Password...'\';
+ shadow_passes = 2;
+ }
+ ];
+ }
+ '';
+ description = ''
+ Hyprlock configuration written in Nix. Entries with the same key should
+ be written as lists. Variables' and colors' names should be quoted. See
+ for more examples.
+ '';
+ };
+
+ extraConfig = lib.mkOption {
+ type = lib.types.lines;
+ default = "";
+ description = ''
+ Extra configuration lines to add to `~/.config/hypr/hyprlock.conf`.
+ '';
+ };
+
+ sourceFirst = lib.mkEnableOption ''
+ putting source entries at the top of the configuration
+ '' // {
+ default = true;
+ };
+
+ importantPrefixes = lib.mkOption {
+ type = with lib.types; listOf str;
+ default = [ "$" "monitor" "size" ]
+ ++ lib.optionals cfg.sourceFirst [ "source" ];
+ example = [ "$" "monitor" "size" ];
+ description = ''
+ List of prefix of attributes to source at the top of the config.
+ '';
+ };
+ };
+
+ config = mkIf cfg.enable {
+ home.packages = [ cfg.package ];
+
+ xdg.configFile."hypr/hyprlock.conf" =
+ let shouldGenerate = cfg.extraConfig != "" || cfg.settings != { };
+ in mkIf shouldGenerate {
+ text = lib.optionalString (cfg.settings != { })
+ (lib.hm.generators.toHyprconf {
+ attrs = cfg.settings;
+ inherit (cfg) importantPrefixes;
+ }) + lib.optionalString (cfg.extraConfig != null) cfg.extraConfig;
+ };
+ };
+}
diff --git a/tests/default.nix b/tests/default.nix
index 0ebf4715..f5b0cbc6 100644
--- a/tests/default.nix
+++ b/tests/default.nix
@@ -197,6 +197,7 @@ in import nmtSrc {
./modules/programs/gnome-shell
./modules/programs/gnome-terminal
./modules/programs/hexchat
+ ./modules/programs/hyprlock
./modules/programs/i3blocks
./modules/programs/i3status-rust
./modules/programs/imv
diff --git a/tests/modules/programs/hyprlock/basic-configuration.conf b/tests/modules/programs/hyprlock/basic-configuration.conf
new file mode 100644
index 00000000..3fdf9ce3
--- /dev/null
+++ b/tests/modules/programs/hyprlock/basic-configuration.conf
@@ -0,0 +1,27 @@
+background {
+ monitor=
+ blur_passes=3
+ blur_size=8
+ path=screenshot
+}
+
+general {
+ disable_loading_bar=true
+ grace=300
+ hide_cursor=true
+ no_fade_in=false
+}
+
+input-field {
+ monitor=
+ size=200, 50
+ dots_center=true
+ fade_on_empty=false
+ font_color=rgb(202, 211, 245)
+ inner_color=rgb(91, 96, 120)
+ outer_color=rgb(24, 25, 38)
+ outline_thickness=5
+ placeholder_text=Password...
+ position=0, -80
+ shadow_passes=2
+}
diff --git a/tests/modules/programs/hyprlock/basic-configuration.nix b/tests/modules/programs/hyprlock/basic-configuration.nix
new file mode 100644
index 00000000..c4f6821e
--- /dev/null
+++ b/tests/modules/programs/hyprlock/basic-configuration.nix
@@ -0,0 +1,45 @@
+{ ... }:
+
+{
+ programs.hyprlock = {
+ enable = true;
+
+ settings = {
+ general = {
+ disable_loading_bar = true;
+ grace = 300;
+ hide_cursor = true;
+ no_fade_in = false;
+ };
+
+ background = [{
+ monitor = "";
+ path = "screenshot";
+ blur_passes = 3;
+ blur_size = 8;
+ }];
+
+ input-field = [{
+ size = "200, 50";
+ position = "0, -80";
+ monitor = "";
+ dots_center = true;
+ fade_on_empty = false;
+ font_color = "rgb(202, 211, 245)";
+ inner_color = "rgb(91, 96, 120)";
+ outer_color = "rgb(24, 25, 38)";
+ outline_thickness = 5;
+ placeholder_text = ''Password...'';
+ shadow_passes = 2;
+ }];
+ };
+ };
+
+ test.stubs.hyprlock = { };
+
+ nmt.script = ''
+ assertFileContent \
+ home-files/.config/hypr/hyprlock.conf \
+ ${./basic-configuration.conf}
+ '';
+}
diff --git a/tests/modules/programs/hyprlock/complex-configuration.conf b/tests/modules/programs/hyprlock/complex-configuration.conf
new file mode 100644
index 00000000..1936f43f
--- /dev/null
+++ b/tests/modules/programs/hyprlock/complex-configuration.conf
@@ -0,0 +1,167 @@
+background {
+ monitor=
+ blur_passes=3
+ blur_size=8
+ brightness=0.817200
+ color=rgba(25, 20, 20, 1.0)
+ contrast=0.891700
+ noise=0.011700
+ path=screenshot
+ vibrancy=0.168600
+ vibrancy_darkness=0.050000
+}
+
+general {
+ disable_loading_bar=true
+ grace=300
+ hide_cursor=true
+ ignore_empty_input=false
+ no_fade_in=false
+ no_fade_out=false
+}
+
+image {
+ monitor=
+ size=120
+ border_color=rgb(202, 211, 245)
+ border_size=5
+ halign=center
+ path=/home/$USER/.face
+ position=0, 45
+ reload_cmd=
+ reload_time=-1
+ rotate=0.000000
+ rounding=-1
+ shadow_passes=1
+ valign=center
+}
+
+input-field {
+ monitor=
+ size=200, 50
+ bothlock_color=-1
+ capslock_color=-1
+ check_color=rgb(204, 136, 34)
+ dots_center=true
+ dots_rounding=-1
+ dots_size=0.330000
+ dots_spacing=0.150000
+ fade_on_empty=false
+ fade_timeout=2000
+ fail_color=rgb(204, 34, 34)
+ fail_text=$FAIL
+ fail_transition=300
+ font_color=rgb(202, 211, 245)
+ halign=center
+ hide_input=false
+ inner_color=rgb(91, 96, 120)
+ invert_numlock=false
+ numlock_color=-1
+ outer_color=rgb(24, 25, 38)
+ outline_thickness=5
+ placeholder_text=Password...
+ position=0, -80
+ rounding=-1
+ shadow_boost=1.200000
+ shadow_color=rgba(0, 0, 0, 1.0)
+ shadow_passes=2
+ shadow_size=3
+ swap_font_color=false
+ valign=center
+}
+
+label {
+ monitor=
+ color=rgb(202, 211, 245)
+ font_family=MonaspiceNe Nerd Font
+ font_size=100
+ halign=center
+ position=0, 330
+ rotate=0.000000
+ shadow_boost=1.200000
+ shadow_color=rgba(0, 0, 0, 1.0)
+ shadow_passes=2
+ shadow_size=3
+ text=$TIME
+ valign=center
+}
+
+label {
+ monitor=
+ color=rgb(202, 211, 245)
+ font_family=MonaspiceNe Nerd Font
+ font_size=25
+ halign=left
+ position=10, 0
+ rotate=0.000000
+ shadow_boost=1.200000
+ shadow_color=rgba(0, 0, 0, 1.0)
+ shadow_passes=1
+ shadow_size=3
+ text= $USER
+ valign=top
+}
+
+label {
+ monitor=
+ color=rgb(202, 211, 245)
+ font_family=MonaspiceNe Nerd Font
+ font_size=50
+ halign=center
+ position=15, -350
+ rotate=0.000000
+ shadow_boost=1.200000
+ shadow_color=rgba(0, 0, 0, 1.0)
+ shadow_passes=1
+ shadow_size=3
+ text=
+ valign=center
+}
+
+label {
+ monitor=
+ color=rgb(202, 211, 245)
+ font_family=MonaspiceNe Nerd Font
+ font_size=25
+ halign=center
+ position=0, -430
+ rotate=0.000000
+ shadow_boost=1.200000
+ shadow_color=rgba(0, 0, 0, 1.0)
+ shadow_passes=1
+ shadow_size=3
+ text=Locked
+ valign=center
+}
+
+label {
+ monitor=
+ color=rgb(202, 211, 245)
+ font_family=MonaspiceNe Nerd Font
+ font_size=30
+ halign=center
+ position=0, 210
+ rotate=0.000000
+ shadow_boost=1.200000
+ shadow_color=rgba(0, 0, 0, 1.0)
+ shadow_passes=1
+ shadow_size=3
+ text=cmd[update:120000] echo "$(date +'%a %d %B')"
+ valign=center
+}
+
+label {
+ monitor=
+ color=rgb(202, 211, 245)
+ font_family=MonaspiceNe Nerd Font
+ font_size=25
+ halign=right
+ position=5, 8
+ rotate=0.000000
+ shadow_boost=1.200000
+ shadow_color=rgba(0, 0, 0, 1.0)
+ shadow_passes=1
+ shadow_size=3
+ text=
+ valign=bottom
+}
diff --git a/tests/modules/programs/hyprlock/complex-configuration.nix b/tests/modules/programs/hyprlock/complex-configuration.nix
new file mode 100644
index 00000000..8544a8c5
--- /dev/null
+++ b/tests/modules/programs/hyprlock/complex-configuration.nix
@@ -0,0 +1,183 @@
+{ ... }:
+
+{
+ programs.hyprlock = {
+ enable = true;
+
+ settings = {
+ general = {
+ disable_loading_bar = true;
+ hide_cursor = true;
+ ignore_empty_input = false;
+ grace = 300;
+ no_fade_in = false;
+ no_fade_out = false;
+ };
+
+ background = [{
+ monitor = "";
+ brightness = "0.817200";
+ color = "rgba(25, 20, 20, 1.0)";
+ path = "screenshot";
+ blur_passes = 3;
+ blur_size = 8;
+ contrast = "0.891700";
+ noise = "0.011700";
+ vibrancy = "0.168600";
+ vibrancy_darkness = "0.050000";
+ }];
+
+ input-field = [{
+ monitor = "";
+ size = "200, 50";
+ position = "0, -80";
+ outline_thickness = 5;
+ dots_center = true;
+ outer_color = "rgb(24, 25, 38)";
+ inner_color = "rgb(91, 96, 120)";
+ font_color = "rgb(202, 211, 245)";
+ fade_on_empty = false;
+ placeholder_text = ''Password...'';
+ shadow_passes = 2;
+ bothlock_color = -1;
+ capslock_color = "-1";
+ check_color = "rgb(204, 136, 34)";
+ dots_rounding = "-1";
+ dots_size = "0.330000";
+ dots_spacing = "0.150000";
+ fade_timeout = "2000";
+ fail_color = "rgb(204, 34, 34)";
+ fail_text = "$FAIL";
+ fail_transition = 300;
+ halign = "center";
+ hide_input = false;
+ invert_numlock = false;
+ numlock_color = -1;
+ rounding = -1;
+ shadow_boost = "1.200000";
+ shadow_color = "rgba(0, 0, 0, 1.0)";
+ shadow_size = 3;
+ swap_font_color = false;
+ valign = "center";
+ }];
+
+ image = [{
+ monitor = "";
+ size = 120;
+ position = "0, 45";
+ path = "/home/$USER/.face";
+ border_color = "rgb(202, 211, 245)";
+ border_size = 5;
+ halign = "center";
+ valign = "center";
+ shadow_passes = 1;
+ reload_cmd = "";
+ reload_time = -1;
+ rotate = "0.000000";
+ rounding = "-1";
+ }];
+
+ label = [
+ {
+ monitor = "";
+ text = ''$TIME'';
+ color = "rgb(202, 211, 245)";
+ font_size = 100;
+ font_family = "MonaspiceNe Nerd Font";
+ valign = "center";
+ halign = "center";
+ position = "0, 330";
+ shadow_passes = 2;
+ rotate = "0.000000";
+ shadow_boost = "1.200000";
+ shadow_color = "rgba(0, 0, 0, 1.0)";
+ shadow_size = 3;
+ }
+ {
+ monitor = "";
+ text = '' $USER'';
+ color = "rgb(202, 211, 245)";
+ font_size = 25;
+ font_family = "MonaspiceNe Nerd Font";
+ valign = "top";
+ halign = "left";
+ position = "10, 0";
+ rotate = "0.000000";
+ shadow_boost = "1.200000";
+ shadow_color = "rgba(0, 0, 0, 1.0)";
+ shadow_size = 3;
+ shadow_passes = 1;
+ }
+ {
+ monitor = "";
+ text = '' '';
+ color = "rgb(202, 211, 245)";
+ font_size = 50;
+ font_family = "MonaspiceNe Nerd Font";
+ valign = "center";
+ halign = "center";
+ position = "15, -350";
+ rotate = "0.000000";
+ shadow_boost = "1.200000";
+ shadow_color = "rgba(0, 0, 0, 1.0)";
+ shadow_size = 3;
+ shadow_passes = 1;
+ }
+ {
+ monitor = "";
+ text = ''Locked'';
+ color = "rgb(202, 211, 245)";
+ font_size = 25;
+ font_family = "MonaspiceNe Nerd Font";
+ valign = "center";
+ halign = "center";
+ position = "0, -430";
+ rotate = "0.000000";
+ shadow_boost = "1.200000";
+ shadow_color = "rgba(0, 0, 0, 1.0)";
+ shadow_size = 3;
+ shadow_passes = 1;
+ }
+ {
+ monitor = "";
+ text = ''
+ cmd[update:120000] echo "$(date +'%a %d %B')"'';
+ color = "rgb(202, 211, 245)";
+ font_size = 30;
+ font_family = "MonaspiceNe Nerd Font";
+ valign = "center";
+ halign = "center";
+ position = "0, 210";
+ rotate = "0.000000";
+ shadow_boost = "1.200000";
+ shadow_color = "rgba(0, 0, 0, 1.0)";
+ shadow_size = 3;
+ shadow_passes = 1;
+ }
+ {
+ monitor = "";
+ text = '' '';
+ color = "rgb(202, 211, 245)";
+ font_size = 25;
+ font_family = "MonaspiceNe Nerd Font";
+ valign = "bottom";
+ halign = "right";
+ position = "5, 8";
+ rotate = "0.000000";
+ shadow_boost = "1.200000";
+ shadow_color = "rgba(0, 0, 0, 1.0)";
+ shadow_size = 3;
+ shadow_passes = 1;
+ }
+ ];
+ };
+ };
+
+ test.stubs.hyprlock = { };
+
+ nmt.script = ''
+ assertFileContent \
+ home-files/.config/hypr/hyprlock.conf \
+ ${./complex-configuration.conf}
+ '';
+}
diff --git a/tests/modules/programs/hyprlock/default.nix b/tests/modules/programs/hyprlock/default.nix
new file mode 100644
index 00000000..3ea18c02
--- /dev/null
+++ b/tests/modules/programs/hyprlock/default.nix
@@ -0,0 +1,4 @@
+{
+ hyprlock-basic-configuration = ./basic-configuration.nix;
+ hyprlock-complex-configuration = ./complex-configuration.nix;
+}