diff --git a/nix/module.nix b/nix/module.nix index 49ab7cd..48182a7 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -1,79 +1,72 @@ -self: { lib, pkgs, config, ... }: +self: +{ + lib, + pkgs, + config, + ... +}: let - inherit (lib) types mkIf mkOption mkEnableOption; + inherit (lib) + types + mkIf + mkOption + mkEnableOption + ; cfg = config.programs.hyprpanel; jsonFormat = pkgs.formats.json { }; - - # No package option - 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. * - ******************************************************************************** - ''; + # No package option + 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. * + ******************************************************************************** + ''; # 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: - acc // process key attrSet.${key} - ) {} (builtins.attrNames attrSet); - - 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..."; - - 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 = { @@ -83,17 +76,10 @@ in systemd.enable = mkEnableOption "systemd integration"; hyprland.enable = mkEnableOption "Hyprland integration"; overwrite.enable = mkEnableOption "overwrite config fix"; - - theme = mkOption { - type = types.str; - default = ""; - example = "catppuccin_mocha"; - description = "Theme to import (see ../themes/*.json)"; - }; override = mkOption { type = types.attrs; - default = {}; + default = { }; example = '' { theme.bar.menus.text = "#123ABC"; @@ -105,34 +91,33 @@ in ''; }; - layout = mkOption { - type = jsonFormat.type; - default = null; - example = '' - { - "bar.layouts" = { - "0" = { - left = [ "dashboard" "workspaces" "windowtitle" ]; - middle = [ "media" ]; - right = [ "volume" "network" "bluetooth" "battery" "systray" "clock" "notifications" ]; - }; - "1" = { - left = [ "dashboard" "workspaces" "windowtitle" ]; - middle = [ "media" ]; - right = [ "volume" "clock" "notifications" ]; - }; - "2" = { - left = [ "dashboard" "workspaces" "windowtitle" ]; - middle = [ "media" ]; - right = [ "volume" "clock" "notifications" ]; + settings = { + layout = mkOption { + type = jsonFormat.type; + default = null; + example = '' + { + "bar.layouts" = { + "0" = { + left = [ "dashboard" "workspaces" "windowtitle" ]; + middle = [ "media" ]; + right = [ "volume" "network" "bluetooth" "battery" "systray" "clock" "notifications" ]; + }; + "1" = { + left = [ "dashboard" "workspaces" "windowtitle" ]; + middle = [ "media" ]; + right = [ "volume" "clock" "notifications" ]; + }; + "2" = { + left = [ "dashboard" "workspaces" "windowtitle" ]; + middle = [ "media" ]; + right = [ "volume" "clock" "notifications" ]; + }; }; }; - }; - ''; - description = "https://hyprpanel.com/configuration/panel.html"; - }; - - settings = { + ''; + description = "https://hyprpanel.com/configuration/panel.html"; + }; bar.autoHide = mkStrOption "never"; bar.battery.hideLabelWhenFull = mkBoolOption false; bar.battery.label = mkBoolOption true; @@ -156,7 +141,16 @@ 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; @@ -363,6 +357,19 @@ in bar.workspaces.spacing = mkFloatOption 1.0; bar.workspaces.workspaceMask = mkBoolOption false; bar.workspaces.workspaces = mkIntOption 5; + bar.workspaces.workspaceIconMap = mkOption { + type = jsonFormat.type; + default = null; + example = '' + "1": "", + "2": "", + "3": "", + "4": "", + "5": "", + "6": " ", + "7": "" + ''; + }; dummy = mkBoolOption true; hyprpanel.restartAgs = mkBoolOption true; # hyprpanel.restartCommand = mkStrOption "${pkgs.procps}/bin/pkill -u $USER -USR1 hyprpanel; ${package}/bin/hyprpanel"; @@ -376,15 +383,20 @@ in menus.clock.weather.unit = mkStrOption "imperial"; menus.dashboard.controls.enabled = mkBoolOption true; menus.dashboard.directories.enabled = mkBoolOption true; - menus.dashboard.directories.left.directory1.command = mkStrOption "bash -c \"xdg-open $HOME/Downloads/\""; + menus.dashboard.directories.left.directory1.command = + mkStrOption "bash -c \"xdg-open $HOME/Downloads/\""; menus.dashboard.directories.left.directory1.label = mkStrOption "󰉍 Downloads"; - menus.dashboard.directories.left.directory2.command = mkStrOption "bash -c \"xdg-open $HOME/Videos/\""; + menus.dashboard.directories.left.directory2.command = + mkStrOption "bash -c \"xdg-open $HOME/Videos/\""; menus.dashboard.directories.left.directory2.label = mkStrOption "󰉏 Videos"; - menus.dashboard.directories.left.directory3.command = mkStrOption "bash -c \"xdg-open $HOME/Projects/\""; + menus.dashboard.directories.left.directory3.command = + mkStrOption "bash -c \"xdg-open $HOME/Projects/\""; menus.dashboard.directories.left.directory3.label = mkStrOption "󰚝 Projects"; - menus.dashboard.directories.right.directory1.command = mkStrOption "bash -c \"xdg-open $HOME/Documents/\""; + menus.dashboard.directories.right.directory1.command = + mkStrOption "bash -c \"xdg-open $HOME/Documents/\""; menus.dashboard.directories.right.directory1.label = mkStrOption "󱧶 Documents"; - menus.dashboard.directories.right.directory2.command = mkStrOption "bash -c \"xdg-open $HOME/Pictures/\""; + menus.dashboard.directories.right.directory2.command = + mkStrOption "bash -c \"xdg-open $HOME/Pictures/\""; menus.dashboard.directories.right.directory2.label = mkStrOption "󰉏 Pictures"; menus.dashboard.directories.right.directory3.command = mkStrOption "bash -c \"xdg-open $HOME/\""; menus.dashboard.directories.right.directory3.label = mkStrOption "󱂵 Home"; @@ -412,7 +424,8 @@ in menus.dashboard.shortcuts.right.shortcut1.command = mkStrOption "sleep 0.5 && hyprpicker -a"; menus.dashboard.shortcuts.right.shortcut1.icon = mkStrOption ""; menus.dashboard.shortcuts.right.shortcut1.tooltip = mkStrOption "Color Picker"; - menus.dashboard.shortcuts.right.shortcut3.command = mkStrOption "bash -c \"${../scripts/snapshot.sh}\""; + menus.dashboard.shortcuts.right.shortcut3.command = + mkStrOption "bash -c \"${../scripts/snapshot.sh}\""; menus.dashboard.shortcuts.right.shortcut3.icon = mkStrOption "󰄀"; menus.dashboard.shortcuts.right.shortcut3.tooltip = mkStrOption "Screenshot"; menus.dashboard.stats.enable_gpu = mkBoolOption false; @@ -443,7 +456,7 @@ in notifications.monitor = mkIntOption 0; notifications.position = mkStrOption "top right"; notifications.showActionsOnHover = mkBoolOption false; - notifications.ignore = mkStrListOption []; + notifications.ignore = mkStrListOption [ ]; notifications.timeout = mkIntOption 7000; scalingPriority = mkStrOption "gdk"; tear = mkBoolOption false; @@ -581,6 +594,12 @@ in theme.matugen_settings.mode = mkStrOption "dark"; theme.matugen_settings.scheme_type = mkStrOption "tonal-spot"; theme.matugen_settings.variation = mkStrOption "standard_1"; + theme.name = mkOption { + type = types.str; + default = ""; + example = "catppuccin_mocha"; + description = "Theme to import (see ../themes/*.json)"; + }; theme.notification.border_radius = mkStrOption "0.6em"; theme.notification.enableShadow = mkBoolOption false; theme.notification.opacity = mkIntOption 100; @@ -608,90 +627,98 @@ in }; }; - config = let + config = + let - theme = - if cfg.theme != "" - then builtins.fromJSON (builtins.readFile ../themes/${cfg.theme}.json) - else {}; + theme = + if cfg.settings.theme.name != "" then + builtins.fromJSON (builtins.readFile ../themes/${cfg.settings.theme.name}.json) + else + { }; - flatSet = flattenAttrs (lib.attrsets.recursiveUpdate cfg.settings theme) ""; + flatSet = lib.attrsets.recursiveUpdate cfg.settings theme; - mergeSet = flatSet // (flattenAttrs cfg.override ""); + mergeSet = flatSet // cfg.override; - fullSet = if cfg.layout == null then mergeSet else mergeSet // cfg.layout; + fullSet = if cfg.settings.layout == null then mergeSet else mergeSet // cfg.settings.layout; - finalConfig = toNestedObject fullSet; + finalConfig = builtins.toJSON fullSet; - hyprpanel-diff = pkgs.writeShellApplication { - runtimeInputs = [ pkgs.colordiff ]; - name = "hyprpanel-diff"; - text = '' - cd - echo '------------- HyprPanel -------------' - echo 'Please ignore the layout diff for now' - echo '-------------------------------------' - colordiff ${config.xdg.configFile.hyprpanel.target} \ - ${config.xdg.configFile.hyprpanel-swap.target} - ''; - }; + hyprpanel-diff = pkgs.writeShellApplication { + runtimeInputs = [ pkgs.colordiff ]; + name = "hyprpanel-diff"; + text = '' + cd + echo '------------- HyprPanel -------------' + echo 'Please ignore the layout diff for now' + echo '-------------------------------------' + colordiff ${config.xdg.configFile.hyprpanel.target} \ + ${config.xdg.configFile.hyprpanel-swap.target} + ''; + }; - in mkIf cfg.enable { + in + mkIf cfg.enable { - # nixpkgs.overlays = if cfg.overlay.enable then [ self.overlay ] else null; - nixpkgs.overlays = lib.mkIf cfg.overlay.enable [ self.overlay ]; + # nixpkgs.overlays = if cfg.overlay.enable then [ self.overlay ] else null; + nixpkgs.overlays = lib.mkIf 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 - path = "${config.xdg.configFile.hyprpanel.target}"; - in + home.activation = + let + path = "${config.xdg.configFile.hyprpanel.target}"; + in mkIf cfg.overwrite.enable { 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; + }; + + # 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" + ]; }; - - 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 []; - - wayland.windowManager.hyprland.settings.exec-once = mkIf cfg.hyprland.enable [ "${package}/bin/hyprpanel" ]; - }; }