diff --git a/modules/lib/maintainers.nix b/modules/lib/maintainers.nix index a794ae76c..34c88e614 100644 --- a/modules/lib/maintainers.nix +++ b/modules/lib/maintainers.nix @@ -517,6 +517,12 @@ github = "silmarp"; githubId = 67292496; }; + yarn = { + name = "yarncat"; + email = "30006414+yaaaarn@users.noreply.github.com"; + github = "yaaaarn"; + githubId = 30006414; + }; zorrobert = { name = "zorrobert"; email = "118135271+zorrobert@users.noreply.github.com"; diff --git a/modules/misc/news/2026/04/2026-04-12_17-36-05.nix b/modules/misc/news/2026/04/2026-04-12_17-36-05.nix new file mode 100644 index 000000000..a01756714 --- /dev/null +++ b/modules/misc/news/2026/04/2026-04-12_17-36-05.nix @@ -0,0 +1,10 @@ +{ pkgs, ... }: +{ + time = "2026-04-12T15:36:05+00:00"; + condition = pkgs.stdenv.hostPlatform.isLinux; + message = '' + A new module is available: `services.syshud`. + + A simple system status indicator for Wayland compositors. + ''; +} diff --git a/modules/services/syshud.nix b/modules/services/syshud.nix new file mode 100644 index 000000000..099243ced --- /dev/null +++ b/modules/services/syshud.nix @@ -0,0 +1,103 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + mkEnableOption + mkPackageOption + mkOption + mkIf + ; + cfg = config.services.syshud; + + iniFormat = pkgs.formats.ini { }; +in +{ + meta.maintainers = [ lib.maintainers.yarn ]; + + options.services.syshud = { + enable = mkEnableOption "syshud"; + + package = mkPackageOption pkgs "syshud" { }; + + settings = mkOption { + type = iniFormat.type.nestedTypes.elemType; + default = { }; + example = lib.literalExpression '' + { + position = "bottom"; + orientation = "h"; + width = 300; + height = 50; + icon-size = 26; + show-percentage = true; + margins = "0 0 0 0"; + timeout = 3; + transition-time = 250; + listeners = "audio_in,audio_out,backlight"; + backlight-path = "/sys/class/backlight/gmux_backlight"; + keyboard-path = "/dev/input/eventXX"; + } + ''; + description = '' + Configuration for syshud. + All available options can be found here: + + ''; + }; + + style = mkOption { + type = lib.types.nullOr (lib.types.either lib.types.path lib.types.lines); + default = null; + description = '' + Custom CSS style for syshud. + If the value is set to a path literal, then the path will be used as the css file. + Default style is available here: + + ''; + }; + }; + + config = mkIf cfg.enable { + assertions = [ + (lib.hm.assertions.assertPlatform "services.syshud" pkgs lib.platforms.linux) + ]; + + home.packages = [ cfg.package ]; + + systemd.user.services.syshud = { + Install = { + WantedBy = [ config.wayland.systemd.target ]; + }; + + Unit = { + ConditionEnvironment = "WAYLAND_DISPLAY"; + Description = "syshud"; + After = [ config.wayland.systemd.target ]; + PartOf = [ config.wayland.systemd.target ]; + }; + + Service = { + ExecStart = lib.getExe cfg.package; + Restart = "always"; + RestartSec = 10; + }; + }; + + xdg.configFile."sys64/hud/config.conf" = mkIf (cfg.settings != { }) { + source = iniFormat.generate "config.conf" { main = cfg.settings; }; + }; + + xdg.configFile."sys64/hud/style.css" = mkIf (cfg.style != null) { + source = + if builtins.isPath cfg.style || lib.isStorePath cfg.style then + cfg.style + else + pkgs.writeText "sys64/hud/style.css" cfg.style; + }; + }; +} diff --git a/tests/modules/services/syshud/default.nix b/tests/modules/services/syshud/default.nix new file mode 100644 index 000000000..4da4f4047 --- /dev/null +++ b/tests/modules/services/syshud/default.nix @@ -0,0 +1,5 @@ +{ lib, pkgs, ... }: +lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { + syshud-default = ./syshud-default.nix; + syshud-settings = ./syshud-settings.nix; +} diff --git a/tests/modules/services/syshud/syshud-default.nix b/tests/modules/services/syshud/syshud-default.nix new file mode 100644 index 000000000..c27702fa1 --- /dev/null +++ b/tests/modules/services/syshud/syshud-default.nix @@ -0,0 +1,18 @@ +{ config, ... }: +{ + services.syshud = { + enable = true; + package = config.lib.test.mkStubPackage { + name = "syshud"; + outPath = "@syshud@"; + }; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/sys64/hud/style.css + assertPathNotExists home-files/.config/sys64/hud/config.conf + + serviceFile=home-files/.config/systemd/user/syshud.service + assertFileContent $serviceFile ${./syshud-default.service} + ''; +} diff --git a/tests/modules/services/syshud/syshud-default.service b/tests/modules/services/syshud/syshud-default.service new file mode 100644 index 000000000..a63153b36 --- /dev/null +++ b/tests/modules/services/syshud/syshud-default.service @@ -0,0 +1,13 @@ +[Install] +WantedBy=graphical-session.target + +[Service] +ExecStart=@syshud@/bin/syshud +Restart=always +RestartSec=10 + +[Unit] +After=graphical-session.target +ConditionEnvironment=WAYLAND_DISPLAY +Description=syshud +PartOf=graphical-session.target diff --git a/tests/modules/services/syshud/syshud-settings.conf b/tests/modules/services/syshud/syshud-settings.conf new file mode 100644 index 000000000..d25885a0b --- /dev/null +++ b/tests/modules/services/syshud/syshud-settings.conf @@ -0,0 +1,13 @@ +[main] +backlight-path=/sys/class/backlight/gmux_backlight +height=67 +icon-size=26 +keyboard-path=/dev/input/event21 +listeners=audio_in,audio_out,backlight,keyboard +margins=0 0 10 0 +orientation=v +position=top +show-percentage=false +timeout=3 +transition-time=250 +width=200 diff --git a/tests/modules/services/syshud/syshud-settings.nix b/tests/modules/services/syshud/syshud-settings.nix new file mode 100644 index 000000000..0cd42aee2 --- /dev/null +++ b/tests/modules/services/syshud/syshud-settings.nix @@ -0,0 +1,37 @@ +{ + config, + ... +}: +{ + services.syshud = { + enable = true; + package = config.lib.test.mkStubPackage { + name = "syshud"; + outPath = "@syshud@"; + }; + settings = { + position = "top"; + orientation = "v"; + width = 200; + height = 67; + icon-size = 26; + show-percentage = false; + margins = "0 0 10 0"; + timeout = 3; + transition-time = 250; + listeners = "audio_in,audio_out,backlight,keyboard"; + backlight-path = "/sys/class/backlight/gmux_backlight"; + keyboard-path = "/dev/input/event21"; + }; + }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/syshud.service + assertFileExists $serviceFile + assertFileContent $serviceFile ${./syshud-default.service} + + configFile=home-files/.config/sys64/hud/config.conf + assertFileExists $configFile + assertFileContent $configFile ${./syshud-settings.conf} + ''; +} diff --git a/tests/modules/services/syshud/syshud-style.css b/tests/modules/services/syshud/syshud-style.css new file mode 100644 index 000000000..1e30d2166 --- /dev/null +++ b/tests/modules/services/syshud/syshud-style.css @@ -0,0 +1,3 @@ +* { + background-color: red; +} diff --git a/tests/modules/services/syshud/syshud-style.nix b/tests/modules/services/syshud/syshud-style.nix new file mode 100644 index 000000000..37ea04eeb --- /dev/null +++ b/tests/modules/services/syshud/syshud-style.nix @@ -0,0 +1,30 @@ +{ + config, + ... +}: +{ + services.syshud = { + enable = true; + package = config.lib.test.mkStubPackage { + name = "syshud"; + outPath = "@syshud@"; + }; + style = '' + * { + background-color: red; + } + ''; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/sys64/hud/config.conf + + serviceFile=home-files/.config/systemd/user/syshud.service + assertFileExists $serviceFile + assertFileContent $serviceFile ${./syshud-default.service} + + styleFile=home-files/.config/sys64/hud/style.css + assertFileExists $styleFile + assertFileContent $styleFile ${./syshud-style.css} + ''; +}