From a125ce5c6c7e326ff5c8cf72edd2f3d4707bd5a0 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 21:06:03 -0500 Subject: [PATCH 01/12] adding support for bar.workspaces.workspaceIconMap --- nix/module.nix | 272 ++++++++++++++++++++++++++++--------------------- 1 file changed, 157 insertions(+), 115 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index efe052921..7faa559ba 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -1,81 +1,106 @@ -self: { lib, pkgs, config, ... }: -let +self: { + lib, + pkgs, + config, + ... +}: let inherit (lib) types mkIf mkOption mkEnableOption; cfg = config.programs.hyprpanel; - jsonFormat = pkgs.formats.json { }; - + jsonFormat = pkgs.formats.json {}; + # No package option - package = if pkgs ? hyprpanel then pkgs.hyprpanel - else abort '' + package = + if pkgs ? hyprpanel + then pkgs.hyprpanel + else + abort '' - ******************************************************************************** - * HyprPanel * - *------------------------------------------------------------------------------* - * You didn't add the overlay! * - * * - * Either set 'overlay.enable = true' or manually add it to 'nixpkgs.overlays'. * - * If you use the 'nixosModule' for Home Manager and have 'useGlobalPkgs' set, * - * you will need to add the overlay yourself. * - ******************************************************************************** - ''; + ******************************************************************************** + * HyprPanel * + *------------------------------------------------------------------------------* + * You didn't add the overlay! * + * * + * Either set 'overlay.enable = true' or manually add it to 'nixpkgs.overlays'. * + * If you use the 'nixosModule' for Home Manager and have 'useGlobalPkgs' set, * + * you will need to add the overlay yourself. * + ******************************************************************************** + ''; # Shorthand lambda for self-documenting options under settings - mkStrOption = default: mkOption { type = types.str; default = default; }; - mkIntOption = default: mkOption { type = types.int; default = default; }; - mkBoolOption = default: mkOption { type = types.bool; default = default; }; - mkStrListOption = default: mkOption { type = types.listOf types.str; default = default; }; - mkFloatOption = default: mkOption { type = types.float; default = default; }; + mkStrOption = default: + mkOption { + type = types.str; + default = default; + }; + mkIntOption = default: + mkOption { + type = types.int; + default = default; + }; + mkBoolOption = default: + mkOption { + type = types.bool; + default = default; + }; + mkStrListOption = default: + mkOption { + type = types.listOf types.str; + default = default; + }; + mkFloatOption = default: + mkOption { + type = types.float; + default = default; + }; # TODO: Please merge https://github.com/Jas-SinghFSU/HyprPanel/pull/497 # Do not ask what these do... - flattenAttrs = attrSet: prefix: - let - process = key: value: - if builtins.isAttrs value then - flattenAttrs value "${prefix}${key}." - else - { "${prefix}${key}" = value; }; - in - builtins.foldl' (acc: key: + flattenAttrs = attrSet: prefix: let + process = key: value: + if builtins.isAttrs value + then flattenAttrs value "${prefix}${key}." + else {"${prefix}${key}" = value;}; + in + builtins.foldl' ( + acc: key: acc // process key attrSet.${key} - ) {} (builtins.attrNames attrSet); + ) {} (builtins.attrNames attrSet); - toNestedValue = - let - escapeString = s: builtins.replaceStrings [ "\"" ] [ "\\\"" ] s; - in + toNestedValue = let + escapeString = s: builtins.replaceStrings ["\""] ["\\\""] s; + in value: - if builtins.isBool value then - if value then "true" else "false" - else if (builtins.isInt value || builtins.isFloat value) then - builtins.toString value - else if builtins.isString value then - "\"" + escapeString value + "\"" - else if builtins.isList value then - let - items = builtins.map toNestedValue value; - in - "[\n" + (builtins.concatStringsSep ", " items) + "\n]" - else if builtins.isAttrs value then - let - keys = builtins.attrNames value; - toKeyValue = k: "\"${k}\": ${toNestedValue value.${k}}"; - inner = builtins.concatStringsSep ", " (builtins.map toKeyValue keys); - in - "{\n" + inner + "\n}" - else - abort "Unexpected error! Please post a new issue and @benvonh..."; + if builtins.isBool value + then + if value + then "true" + else "false" + else if (builtins.isInt value || builtins.isFloat value) + then builtins.toString value + else if builtins.isString value + then "\"" + escapeString value + "\"" + else if builtins.isList value + then let + items = builtins.map toNestedValue value; + in + "[\n" + (builtins.concatStringsSep ", " items) + "\n]" + else if builtins.isAttrs value + then let + keys = builtins.attrNames value; + toKeyValue = k: "\"${k}\": ${toNestedValue value.${k}}"; + inner = builtins.concatStringsSep ", " (builtins.map toKeyValue keys); + in + "{\n" + inner + "\n}" + else abort "Unexpected error! Please post a new issue and @benvonh..."; - toNestedObject = attrSet: - let - keys = builtins.attrNames attrSet; - kvPairs = builtins.map (k: "\"${k}\": ${toNestedValue attrSet.${k}}") keys; - in - "{\n " + builtins.concatStringsSep ",\n " kvPairs + "\n}"; -in -{ + toNestedObject = attrSet: let + keys = builtins.attrNames attrSet; + kvPairs = builtins.map (k: "\"${k}\": ${toNestedValue attrSet.${k}}") keys; + in + "{\n " + builtins.concatStringsSep ",\n " kvPairs + "\n}"; +in { options.programs.hyprpanel = { enable = mkEnableOption "HyprPanel"; config.enable = mkBoolOption true; # Generate config @@ -83,7 +108,7 @@ in systemd.enable = mkEnableOption "systemd integration"; hyprland.enable = mkEnableOption "Hyprland integration"; overwrite.enable = mkEnableOption "overwrite config fix"; - + theme = mkOption { type = types.str; default = ""; @@ -156,7 +181,7 @@ in bar.customModules.cava.showIcon = mkBoolOption true; bar.customModules.cava.icon = mkStrOption ""; bar.customModules.cava.spaceCharacter = mkStrOption " "; - bar.customModules.cava.barCharacters = mkStrListOption [ "▁" "▂" "▃" "▄" "▅" "▆" "▇" "█" ]; + bar.customModules.cava.barCharacters = mkStrListOption ["▁" "▂" "▃" "▄" "▅" "▆" "▇" "█"]; bar.customModules.cava.showActiveOnly = mkBoolOption false; bar.customModules.cava.bars = mkIntOption 10; bar.customModules.cava.channels = mkIntOption 2; @@ -354,6 +379,18 @@ in bar.workspaces.spacing = mkIntOption 1; bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; + bar.workspaces.workspaceIconMap = mkOption { + type = jsonFormat.type; + default = {}; + example = '' + { + "1" = ""; + "2" = ""; + "3" = ""; + } + ''; + description = "Map of workspace number to icon"; + }; dummy = mkBoolOption true; hyprpanel.restartAgs = mkBoolOption true; # hyprpanel.restartCommand = mkStrOption "${pkgs.procps}/bin/pkill -u $USER -USR1 hyprpanel; ${package}/bin/hyprpanel"; @@ -584,7 +621,6 @@ in }; config = let - theme = if cfg.theme != "" then builtins.fromJSON (builtins.readFile ../themes/${cfg.theme}.json) @@ -594,12 +630,15 @@ in mergeSet = flatSet // (flattenAttrs cfg.override ""); - fullSet = if cfg.layout == null then mergeSet else mergeSet // cfg.layout; + fullSet = + if cfg.layout == null + then mergeSet + else mergeSet // cfg.layout; finalConfig = toNestedObject fullSet; hyprpanel-diff = pkgs.writeShellApplication { - runtimeInputs = [ pkgs.colordiff ]; + runtimeInputs = [pkgs.colordiff]; name = "hyprpanel-diff"; text = '' cd @@ -610,63 +649,66 @@ in ${config.xdg.configFile.hyprpanel-swap.target} ''; }; + in + mkIf cfg.enable { + # nixpkgs.overlays = if cfg.overlay.enable then [ self.overlay ] else null; + nixpkgs.overlays = lib.optionals cfg.overlay.enable [self.overlay]; - in mkIf cfg.enable { - - # nixpkgs.overlays = if cfg.overlay.enable then [ self.overlay ] else null; - nixpkgs.overlays = lib.optionals cfg.overlay.enable [ self.overlay ]; - - home.packages = [ - package - hyprpanel-diff - (if pkgs ? nerd-fonts.jetbrains-mono - then pkgs.nerd-fonts.jetbrains-mono - # NOTE:(benvonh) Remove after next release 25.05 - else pkgs.nerdfonts.override { fonts = [ "JetBrainsMono" ]; }) - ]; + home.packages = [ + package + hyprpanel-diff + ( + if pkgs ? nerd-fonts.jetbrains-mono + then pkgs.nerd-fonts.jetbrains-mono + # NOTE:(benvonh) Remove after next release 25.05 + else pkgs.nerdfonts.override {fonts = ["JetBrainsMono"];} + ) + ]; - home.activation = - let + home.activation = let path = "${config.xdg.configFile.hyprpanel.target}"; in mkIf cfg.overwrite.enable { - hyprpanel = lib.hm.dag.entryBefore [ "writeBoundary" ] '' + hyprpanel = lib.hm.dag.entryBefore ["writeBoundary"] '' [[ -L "${path}" ]] || rm -f "${path}" ''; }; - xdg.configFile.hyprpanel = mkIf cfg.config.enable { - target = "hyprpanel/config.json"; - text = finalConfig; - # onChange = "${pkgs.procps}/bin/pkill -u $USER -USR1 hyprpanel || true"; - onChange = "${package}/bin/hyprpanel r"; - }; + xdg.configFile.hyprpanel = mkIf cfg.config.enable { + target = "hyprpanel/config.json"; + text = finalConfig; + # onChange = "${pkgs.procps}/bin/pkill -u $USER -USR1 hyprpanel || true"; + onChange = "${package}/bin/hyprpanel r"; + }; - xdg.configFile.hyprpanel-swap = mkIf cfg.config.enable { - target = "hyprpanel/config.hm.json"; - text = finalConfig; - }; + xdg.configFile.hyprpanel-swap = mkIf cfg.config.enable { + target = "hyprpanel/config.hm.json"; + text = finalConfig; + }; - # NOTE: Deprecated - # systemd.user.services = mkIf cfg.systemd.enable { - # hyprpanel = { - # Unit = { - # Description = "A Bar/Panel for Hyprland with extensive customizability."; - # Documentation = "https://hyprpanel.com"; - # PartOf = [ "graphical-session.target" ]; - # After = [ "graphical-session-pre.target" ]; - # }; - # Service = { - # ExecStart = "${package}/bin/hyprpanel"; - # ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR1 $MAINPID"; - # Restart = "on-failure"; - # KillMode = "mixed"; - # }; - # Install = { WantedBy = [ "graphical-session.target" ]; }; - # }; - # }; - warnings = if cfg.systemd.enable then [ "The `systemd.enable` option is now obsolete." ] else []; + # NOTE: Deprecated + # systemd.user.services = mkIf cfg.systemd.enable { + # hyprpanel = { + # Unit = { + # Description = "A Bar/Panel for Hyprland with extensive customizability."; + # Documentation = "https://hyprpanel.com"; + # PartOf = [ "graphical-session.target" ]; + # After = [ "graphical-session-pre.target" ]; + # }; + # Service = { + # ExecStart = "${package}/bin/hyprpanel"; + # ExecReload = "${pkgs.coreutils}/bin/kill -SIGUSR1 $MAINPID"; + # Restart = "on-failure"; + # KillMode = "mixed"; + # }; + # Install = { WantedBy = [ "graphical-session.target" ]; }; + # }; + # }; + warnings = + if cfg.systemd.enable + then ["The `systemd.enable` option is now obsolete."] + else []; - wayland.windowManager.hyprland.settings.exec-once = mkIf cfg.hyprland.enable [ "${package}/bin/hyprpanel" ]; - }; + wayland.windowManager.hyprland.settings.exec-once = mkIf cfg.hyprland.enable ["${package}/bin/hyprpanel"]; + }; } From f4d5d04272b53b784f47083feecaa838df794c9f Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 21:10:01 -0500 Subject: [PATCH 02/12] trying the attrs field now, last one was close --- nix/module.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/module.nix b/nix/module.nix index 7faa559ba..2947da940 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -380,7 +380,7 @@ in { bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; bar.workspaces.workspaceIconMap = mkOption { - type = jsonFormat.type; + type = types.attrs; default = {}; example = '' { From 48262282cf816f709962c393aaf680dc3c6b017b Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 21:20:55 -0500 Subject: [PATCH 03/12] trying to explicitly unflatten the sructure --- nix/module.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/module.nix b/nix/module.nix index 2947da940..c4965e3ab 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -380,7 +380,7 @@ in { bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; bar.workspaces.workspaceIconMap = mkOption { - type = types.attrs; + type = types.attrsOf types.str; default = {}; example = '' { From 7883c9ab0c15e4b5903cf68022ce8ed188d79dae Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 21:24:24 -0500 Subject: [PATCH 04/12] testing the flake udpate on my local --- nix/module.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/module.nix b/nix/module.nix index c4965e3ab..a3c3023ab 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -380,7 +380,7 @@ in { bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; bar.workspaces.workspaceIconMap = mkOption { - type = types.attrsOf types.str; + type = types.str; default = {}; example = '' { From 8b8ed3c13a5a49dcbcbaf7f7da7624babbd6f431 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 21:41:05 -0500 Subject: [PATCH 05/12] explicitly removing workspaceIconMap from the flattening process --- nix/module.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index a3c3023ab..f275bd7cf 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -59,7 +59,9 @@ self: { # Do not ask what these do... flattenAttrs = attrSet: prefix: let process = key: value: - if builtins.isAttrs value + if key == "workspaceIconMap" + then {"${prefix}${key}" = value;} + else if builtins.isAttrs value then flattenAttrs value "${prefix}${key}." else {"${prefix}${key}" = value;}; in @@ -380,7 +382,7 @@ in { bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; bar.workspaces.workspaceIconMap = mkOption { - type = types.str; + type = jsonFormat.type; default = {}; example = '' { From 9be28b3b580d5690db8b7bb52478f74491d04a92 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 21:48:04 -0500 Subject: [PATCH 06/12] trying other type format --- nix/module.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/module.nix b/nix/module.nix index f275bd7cf..67f526c83 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -382,7 +382,7 @@ in { bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; bar.workspaces.workspaceIconMap = mkOption { - type = jsonFormat.type; + type = types.attrsOf types.str; default = {}; example = '' { From a6b23896f7a2861351212f10caeb0c991724a425 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 22:03:00 -0500 Subject: [PATCH 07/12] trying to pretty print the config --- nix/module.nix | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index 67f526c83..ad5ef37ff 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -89,12 +89,17 @@ self: { in "[\n" + (builtins.concatStringsSep ", " items) + "\n]" else if builtins.isAttrs value - then let - keys = builtins.attrNames value; - toKeyValue = k: "\"${k}\": ${toNestedValue value.${k}}"; - inner = builtins.concatStringsSep ", " (builtins.map toKeyValue keys); - in - "{\n" + inner + "\n}" + then + if value ? _type && value._type == "json" + then + #Pretty print JSON values from settings + lib.generators.toJSON {indent = 2;} value + else let + keys = builtins.attrNames value; + toKeyValue = k: "\"${k}\": ${toNestedValue value.${k}}"; + inner = builtins.concatStringsSep ", " (builtins.map toKeyValue keys); + in + "{\n" + inner + "\n}" else abort "Unexpected error! Please post a new issue and @benvonh..."; toNestedObject = attrSet: let @@ -382,7 +387,7 @@ in { bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; bar.workspaces.workspaceIconMap = mkOption { - type = types.attrsOf types.str; + type = jsonFormat.type; default = {}; example = '' { From 2d3d69383f856058715e0175a194e9fd71d45ef2 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 22:17:19 -0500 Subject: [PATCH 08/12] remove the code I think I was being dumb --- nix/module.nix | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index ad5ef37ff..f257ea3c8 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -89,17 +89,12 @@ self: { in "[\n" + (builtins.concatStringsSep ", " items) + "\n]" else if builtins.isAttrs value - then - if value ? _type && value._type == "json" - then - #Pretty print JSON values from settings - lib.generators.toJSON {indent = 2;} value - else let - keys = builtins.attrNames value; - toKeyValue = k: "\"${k}\": ${toNestedValue value.${k}}"; - inner = builtins.concatStringsSep ", " (builtins.map toKeyValue keys); - in - "{\n" + inner + "\n}" + then let + keys = builtins.attrNames value; + toKeyValue = k: "\"${k}\": ${toNestedValue value.${k}}"; + inner = builtins.concatStringsSep ", " (builtins.map toKeyValue keys); + in + "{\n" + inner + "\n}" else abort "Unexpected error! Please post a new issue and @benvonh..."; toNestedObject = attrSet: let @@ -387,7 +382,7 @@ in { bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; bar.workspaces.workspaceIconMap = mkOption { - type = jsonFormat.type; + type = types.attrs; default = {}; example = '' { From dfdb9d5afbb38f63ae1338ae53938da998f626b3 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 23:03:20 -0500 Subject: [PATCH 09/12] update the example to match the wiki --- nix/module.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index f257ea3c8..cca0105fa 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -386,9 +386,11 @@ in { default = {}; example = '' { - "1" = ""; - "2" = ""; - "3" = ""; + "1": "󰄛", + "2": "", + "3": "󰙯", + "4": "󰓇", + "5": "" } ''; description = "Map of workspace number to icon"; From 9ca2e6538864492b1967fb751d1f8efa9783e052 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 23:37:13 -0500 Subject: [PATCH 10/12] testing some other options for unflattening --- nix/module.nix | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/nix/module.nix b/nix/module.nix index cca0105fa..41679079f 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -54,12 +54,17 @@ self: { type = types.float; default = default; }; + mkJsonOption = default: + mkOption { + type = types.attrsOf types.str; + default = default; + }; # TODO: Please merge https://github.com/Jas-SinghFSU/HyprPanel/pull/497 # Do not ask what these do... flattenAttrs = attrSet: prefix: let process = key: value: - if key == "workspaceIconMap" + if key == "workspaceIconMap1" then {"${prefix}${key}" = value;} else if builtins.isAttrs value then flattenAttrs value "${prefix}${key}." @@ -381,20 +386,7 @@ in { bar.workspaces.spacing = mkIntOption 1; bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; - bar.workspaces.workspaceIconMap = mkOption { - type = types.attrs; - default = {}; - example = '' - { - "1": "󰄛", - "2": "", - "3": "󰙯", - "4": "󰓇", - "5": "" - } - ''; - description = "Map of workspace number to icon"; - }; + bar.workspaces.workspaceIconMap = mkJsonOption "{}"; dummy = mkBoolOption true; hyprpanel.restartAgs = mkBoolOption true; # hyprpanel.restartCommand = mkStrOption "${pkgs.procps}/bin/pkill -u $USER -USR1 hyprpanel; ${package}/bin/hyprpanel"; From 47f57918cfbbe631b1178ebaf555a983bd57a28e Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 23:40:18 -0500 Subject: [PATCH 11/12] that did not do it --- nix/module.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/module.nix b/nix/module.nix index 41679079f..b20d210c8 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -64,7 +64,7 @@ self: { # Do not ask what these do... flattenAttrs = attrSet: prefix: let process = key: value: - if key == "workspaceIconMap1" + if key == "workspaceIconMap" then {"${prefix}${key}" = value;} else if builtins.isAttrs value then flattenAttrs value "${prefix}${key}." From 0d15c80aac3efe2ceb47d0b6f1ea722eb3eec072 Mon Sep 17 00:00:00 2001 From: Andrew Gluck Date: Tue, 14 Jan 2025 23:53:58 -0500 Subject: [PATCH 12/12] making the code a little more configurable and hopefully less brittle --- nix/module.nix | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/nix/module.nix b/nix/module.nix index b20d210c8..cefc12efd 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -62,9 +62,12 @@ self: { # TODO: Please merge https://github.com/Jas-SinghFSU/HyprPanel/pull/497 # Do not ask what these do... + excludeKeys = [ + "workspaceIconMap" + ]; flattenAttrs = attrSet: prefix: let process = key: value: - if key == "workspaceIconMap" + if builtins.elem key excludeKeys then {"${prefix}${key}" = value;} else if builtins.isAttrs value then flattenAttrs value "${prefix}${key}."