diff --git a/modules/programs/hyprpanel/default.nix b/modules/programs/hyprpanel/default.nix new file mode 100644 index 000000000..a93f36685 --- /dev/null +++ b/modules/programs/hyprpanel/default.nix @@ -0,0 +1,121 @@ +{ + pkgs, + lib, + config, + ... +}: +let + cfg = config.programs.hyprpanel; + jsonFormat = pkgs.formats.json { }; +in +{ + meta.maintainers = [ lib.maintainers.perchun ]; + + options.programs.hyprpanel = { + enable = lib.mkEnableOption "HyprPanel"; + + package = lib.mkPackageOption pkgs "hyprpanel" { }; + + settings = lib.mkOption { + type = jsonFormat.type; + default = { }; + example = lib.literalExpression '' + bar.battery.label = true; + bar.bluetooth.label = false; + bar.clock.format = "%H:%M:%S"; + bar.layouts = { + "*" = { + left = [ + "dashboard" + "workspaces" + "media" + ]; + middle = [ "windowtitle" ]; + right = [ + "volume" + "network" + "bluetooth" + "notifications" + ]; + }; + }; + ''; + description = '' + Configuration written to + {file}`$XDG_CONFIG_HOME/hyprpanel/config.json`. + + See + for the full list of options. + ''; + }; + + systemd.enable = lib.mkEnableOption "HyprPanel systemd integration" // { + default = true; + }; + + dontAssertNotificationDaemons = lib.mkOption { + default = true; + example = false; + description = '' + Whether to check for other notification daemons. + + You might want to set this to false, because hyprpanel's notification + daemon is buggy and you may prefer something else. + ''; + type = lib.types.bool; + }; + }; + + config = lib.mkIf cfg.enable { + assertions = [ + { + assertion = cfg.dontAssertNotificationDaemons && !config.services.swaync.enable; + message = '' + Only one notification daemon can be enabled at once. You have enabled + swaync and hyprpanel at once. + + If you dont want to use hyprpanel's notification daemon, set + `programs.hyprpanel.dontAssertNotificationDaemons` to true. + ''; + } + ]; + + home.packages = [ cfg.package ]; + + programs.hyprpanel.settings = lib.mkIf config.services.hypridle.enable { + # fix hypridle module if user uses systemd service + bar.customModules.hypridle.startCommand = lib.mkDefault "systemctl --user start hypridle.service"; + bar.customModules.hypridle.stopCommand = lib.mkDefault "systemctl --user stop hypridle.service"; + bar.customModules.hypridle.isActiveCommand = lib.mkDefault "systemctl --user status hypridle.service | grep -q 'Active: active (running)' && echo 'yes' || echo 'no'"; + }; + + xdg.configFile.hyprpanel = lib.mkIf (cfg.settings != { }) { + target = "hyprpanel/config.json"; + source = jsonFormat.generate "hyprpanel-config" cfg.settings; + # hyprpanel replaces it with the same file, but without new line in the end + force = true; + }; + + systemd.user.services.hyprpanel = lib.mkIf cfg.systemd.enable { + Unit = { + Description = "Bar/Panel for Hyprland with extensive customizability"; + Documentation = "https://hyprpanel.com/getting_started/hyprpanel.html"; + PartOf = [ config.wayland.systemd.target ]; + After = [ config.wayland.systemd.target ]; + ConditionEnvironment = "WAYLAND_DISPLAY"; + X-Restart-Triggers = lib.optional (cfg.settings != { }) "${config.xdg.configFile.hyprpanel.source}"; + }; + + Service = { + ExecStart = "${cfg.package}/bin/hyprpanel"; + ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR2 $MAINPID"; + Restart = "on-failure"; + KillMode = "mixed"; + }; + + Install = { + WantedBy = [ config.wayland.systemd.target ]; + }; + }; + }; +} diff --git a/tests/modules/programs/hyprpanel/basic-config.json b/tests/modules/programs/hyprpanel/basic-config.json new file mode 100644 index 000000000..472ec0441 --- /dev/null +++ b/tests/modules/programs/hyprpanel/basic-config.json @@ -0,0 +1,31 @@ +{ + "bar": { + "battery": { + "label": true + }, + "bluetooth": { + "label": false + }, + "clock": { + "format": "%H:%M:%S" + }, + "layouts": { + "*": { + "left": [ + "dashboard", + "workspaces", + "media" + ], + "middle": [ + "windowtitle" + ], + "right": [ + "volume", + "network", + "bluetooth", + "notifications" + ] + } + } + } +} diff --git a/tests/modules/programs/hyprpanel/basic-config.nix b/tests/modules/programs/hyprpanel/basic-config.nix new file mode 100644 index 000000000..3aaa7f346 --- /dev/null +++ b/tests/modules/programs/hyprpanel/basic-config.nix @@ -0,0 +1,34 @@ +{ config, ... }: +{ + programs.hyprpanel = { + enable = true; + package = config.lib.test.mkStubPackage { name = "hyprpanel"; }; + settings = { + bar.battery.label = true; + bar.bluetooth.label = false; + bar.clock.format = "%H:%M:%S"; + bar.layouts = { + "*" = { + left = [ + "dashboard" + "workspaces" + "media" + ]; + middle = [ "windowtitle" ]; + right = [ + "volume" + "network" + "bluetooth" + "notifications" + ]; + }; + }; + }; + }; + + nmt.script = '' + assertFileContent \ + "home-files/.config/hyprpanel/config.json" \ + ${./basic-config.json} + ''; +} diff --git a/tests/modules/programs/hyprpanel/default.nix b/tests/modules/programs/hyprpanel/default.nix new file mode 100644 index 000000000..dd73495f9 --- /dev/null +++ b/tests/modules/programs/hyprpanel/default.nix @@ -0,0 +1,6 @@ +{ lib, pkgs, ... }: + +lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux { + hyprpanel-basic-config = ./basic-config.nix; + hyprpanel-with-hypridle = ./with-hypridle.nix; +} diff --git a/tests/modules/programs/hyprpanel/with-hypridle.json b/tests/modules/programs/hyprpanel/with-hypridle.json new file mode 100644 index 000000000..497f79cb3 --- /dev/null +++ b/tests/modules/programs/hyprpanel/with-hypridle.json @@ -0,0 +1,38 @@ +{ + "bar": { + "battery": { + "label": true + }, + "bluetooth": { + "label": false + }, + "clock": { + "format": "%H:%M:%S" + }, + "customModules": { + "hypridle": { + "isActiveCommand": "systemctl --user status hypridle.service | grep -q 'Active: active (running)' && echo 'yes' || echo 'no'", + "startCommand": "systemctl --user start hypridle.service", + "stopCommand": "systemctl --user stop hypridle.service" + } + }, + "layouts": { + "*": { + "left": [ + "dashboard", + "workspaces", + "media" + ], + "middle": [ + "windowtitle" + ], + "right": [ + "volume", + "network", + "bluetooth", + "notifications" + ] + } + } + } +} diff --git a/tests/modules/programs/hyprpanel/with-hypridle.nix b/tests/modules/programs/hyprpanel/with-hypridle.nix new file mode 100644 index 000000000..8ec81124d --- /dev/null +++ b/tests/modules/programs/hyprpanel/with-hypridle.nix @@ -0,0 +1,35 @@ +{ config, ... }: +{ + services.hypridle.enable = true; + programs.hyprpanel = { + enable = true; + package = config.lib.test.mkStubPackage { name = "hyprpanel"; }; + settings = { + bar.battery.label = true; + bar.bluetooth.label = false; + bar.clock.format = "%H:%M:%S"; + bar.layouts = { + "*" = { + left = [ + "dashboard" + "workspaces" + "media" + ]; + middle = [ "windowtitle" ]; + right = [ + "volume" + "network" + "bluetooth" + "notifications" + ]; + }; + }; + }; + }; + + nmt.script = '' + assertFileContent \ + "home-files/.config/hyprpanel/config.json" \ + ${./with-hypridle.json} + ''; +}