diff --git a/README.md b/README.md index a518e39..91d00e5 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ You can install it e.g.: with yay If you choose the Nix/NixOS installation there are a couple of ways to do it but they all require you to have flakes enabled. - Building it seperately and just running the binary, run nix build in the directory and use the binary from ./result/bin - Import the flake to inputs and then add `gBar.defaultPackage.x86_64-linux` to either environment.systemPackages or home.packages. -- Use the home manager module. This is done by, as in the previous way, importing the flake and then adding `gBar.homeManagerModules.x86_64-linux.default` into your home-manager imorts section. This exposes the option programs.gBar to home manager and you can look at the module file to see available options. +- Use the home manager module. This is done by, as in the previous way, importing the flake and then adding `gBar.homeManagerModules.x86_64-linux.default` into your home-manager imorts section. This exposes the option programs.gBar to home manager and you can look at the module file to see available options, but in short under `programs.gBar.config` you can put all options from the standard configs names (some exceptions) in there and it works like expected, some options have a refined configuration syntax. ## Running gBar *Open bar on monitor 0* diff --git a/flake.lock b/flake.lock index c668193..cbb701a 100644 --- a/flake.lock +++ b/flake.lock @@ -1,12 +1,15 @@ { "nodes": { "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1676283394, - "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", "owner": "numtide", "repo": "flake-utils", - "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", "type": "github" }, "original": { @@ -17,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1677262115, - "narHash": "sha256-DPkHiJw2QnKYAzQXBlwelwghxbcD5oigK2kLPHMpMQ8=", + "lastModified": 1689752456, + "narHash": "sha256-VOChdECcEI8ixz8QY+YC4JaNEFwQd1V8bA0G4B28Ki0=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "806075be2bdde71895359ed18cb530c4d323e6f6", + "rev": "7f256d7da238cb627ef189d56ed590739f42f13b", "type": "github" }, "original": { @@ -36,6 +39,21 @@ "flake-utils": "flake-utils", "nixpkgs": "nixpkgs" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/module.nix b/module.nix index 5ff1c0a..a265be8 100644 --- a/module.nix +++ b/module.nix @@ -5,49 +5,237 @@ self: , lib , pkgs , ... -}: let +}: + +with lib; + +let cfg = config.programs.gBar; defaultGBarPackage = self.defaultPackage.x86_64-linux; in { options.programs.gBar = { - enable = lib.mkEnableOption "Wether to enable gBar, a blazingly fast statusbar written in c++"; + enable = mkEnableOption "Wether to enable gBar, a blazingly fast statusbar written in c++"; - package = lib.mkOption { - type = lib.types.nullOr lib.types.package; + package = mkOption { + type = types.nullOr types.package; default = defaultGBarPackage; - defaultText = lib.literalExpression ".packages..default"; - example = lib.literalExpression ".packages..default.override { }"; + defaultText = literalExpression ".packages..default"; + example = literalExpression ".packages..default.override { }"; description = '' gBar package to use. ''; }; - extraConfig = lib.mkOption { - type = lib.types.nullOr lib.types.lines; - default = null; + config = mkOption { + default = {}; + description = "Options to write to gBar config file, named as standard options"; + type = types.submodule { + options = { + CPUThermalZone = mkOption { + type = types.nullOr types.str; + default = "/sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon2/temp1_input"; + description = "path to the cpu thermal sensor, probably something in /sys/device"; + }; + SuspendCommand = mkOption { + type = types.str; + default = "systemctl suspend"; + description = "The command to execute on suspend"; + }; + LockCommand = mkOption { + type = types.nullOr types.str; + default = "~/.config/scripts/sys.sh lock"; + description = "The command to execute on lock"; + }; + ExitCommand = mkOption { + type = types.str; + default = "killall Hyprland"; + description = "The command to execute on exit"; + }; + BatteryFolder = mkOption { + type = types.nullOr types.str; + default = "/sys/class/power_supply/BAT1"; + description = "The folder, where the battery sensors reside"; + }; + WorkspaceSymbols = mkOption { + type = types.nullOr (types.listOf types.str); + default = []; + description = "A list of strings where the position in the list is the icon to change, overrides the default symbol"; + }; + DefaultWorkspaceSymbol = mkOption { + type = types.str; + default = ""; + description = "The default symbol for the workspaces"; + }; + WorkspaceScrollOnMonitor = mkOption { + type = types.bool; + default = true; + description = "Scroll through the workspaces of the current monitor instead of all workspaces"; + }; + WorkspaceScrollInvert = mkOption { + type = types.bool; + default = false; + description = "When true: Scroll up -> Next workspace instead of previous workspace. Analogous with scroll down"; + }; + UseHyprlandIPC = mkOption { + type = types.bool; + default = false; + description = '' + Use Hyprland IPC instead of the ext_workspace protocol for workspace polling. + Hyprland IPC is *slightly* less performant (+0.1% one core), but way less bug prone, + since the protocol is not as feature complete as Hyprland IPC. + ''; + }; + Location = mkOption { + type = types.enum ["T" "B" "L" "R"]; + default = "T"; + description = "The location of the bar, enumerates to one capitalised letter as above"; + }; + CenterTime = mkOption { + type = types.bool; + default = true; + description = '' + Forces the time to be centered. + This can cause the right widget to clip outside, if there is not enough space on screen (e.g. when opening the text) + Setting this to false will definitely fix this issue, but it won't look very good, since it will be off-center. + So try to decrease "TimeSpace" first, before setting this configuration to false. + ''; + }; + TimeSpace = mkOption { + type = types.nullOr types.int; + default = 300; + description = '' + How much space should be reserved for the time widget. Setting this too high can cause the right widget to clip outside. + Therefore try to set it as low as possible if you experience clipping. + Although keep in mind, that a value that is too low can cause the widget to be be off-center, + which can also cause clipping. + If you can't find an optimal value, consider setting 'CenterTime' to false + ''; + }; + DateTimeStyle = mkOption { + type = types.nullOr types.str; + default = ""; + description = "Set datetime style"; + }; + AudioInput = mkOption { + type = types.bool; + default = false; + description = "Adds a microphone volume widget"; + }; + AudioRevealer = mkOption { + type = types.bool; + default = false; + description = "Sets the audio slider to be on reveal (Just like the sensors) when true. Only affects the bar."; + }; + AudioScrollSpeed = mkOption { + type = types.nullOr types.int; + default = 5; + description = "Sets the rate of change of the slider on each scroll. In Percent"; + }; + AudioMinVolume = mkOption { + type = types.nullOr types.int; + default = 0; + description = "Limits the range of the audio slider. Only works for audio output. Slider 'empty' is AudioMinVolume, Slider 'full' is AudioMaxVolume"; + }; + AudioMaxVolume = mkOption { + type = types.nullOr types.int; + default = 100; + description = ""; + }; + NetworkAdapter = mkOption { + type = types.nullOr types.str; + default = "eno1"; + description = "The network adapter to use. You can query /sys/class/net for all possible values"; + }; + NetworkWidget = mkOption { + type = types.bool; + default = true; + description = "Disables the network widget when set to false"; + }; + EnableSNI = mkOption { + type = types.bool; + default = true; + description = "Enable tray icons"; + }; + SNIIconSize = mkOption { + type = types.nullOr (types.attrsOf types.int); + default = {}; + description = "sets the icon size for a SNI icon, an attribute set where, for example you can put Discord = 23 as an attribute and thus make discord slightly smaller Set to * to apply to all"; + }; + SNIIconPaddingTop = mkOption { + type = types.nullOr (types.attrsOf types.int); + default = {}; + description = "Can be used to push the Icon down. Negative values are allowed same as IconSize with an attribute set"; + }; + # These set the range for the network widget. The widget changes colors at six intervals: + # - Below Min...Bytes ("under") + # - Between ]0%;25%]. 0% = Min...Bytes; 100% = Max...Bytes ("low") + # - Between ]25%;50%]. 0% = Min...Bytes; 100% = Max...Bytes ("mid-low") + # - Between ]50%;75%]. 0% = Min...Bytes; 100% = Max...Bytes ("mid-high") + # - Between ]75%;100%]. 0% = Min...Bytes; 100% = Max...Bytes ("high") + # - Above Max...Bytes ("over") + MinDownloadBytes = mkOption { + type = types.nullOr types.int; + default = 0; + description = ""; + }; + MaxDownloadBytes = mkOption { + type = types.nullOr types.int; + default = 10485760; + description = ""; + }; + MinUploadBytes = mkOption { + type = types.nullOr types.int; + default = 0; + description = ""; + }; + MaxUploadBytes = mkOption { + type = types.nullOr types.int; + default = 5242880; + description = ""; + }; + }; + }; + }; + + extraConfig = mkOption { + type = types.nullOr types.lines; + default = '' ''; description = '' - Configuration to write to ~/.config/gBar/config, if none nothing happens + Configuration to write to ~/.config/gBar/config, if you want to use your own config then set this to null and home manager wont write anything, neither the config ''; }; - extraCSS = lib.mkOption { - type = lib.types.nullOr lib.types.lines; + extraCSS = mkOption { + type = types.nullOr types.lines; default = null; description = '' - Configuration to write to ~/.config/gBar/config, if none nothing happens + Configuration to write to ~/.config/gBar/style.css, if none nothing happens ''; }; }; - config = lib.mkIf cfg.enable { - home.packages = lib.optional (cfg.package != null) cfg.package; + config = let + # Takes attributeset with an arbitrary value and returns it as an attrset of valid gBar options + applyVal = x: + let anyToString = a: if isBool a then boolToString a else toString a; + in attrsets.mapAttrs (name: value: + name + ": " + (anyToString value)) (filterAttrs (n2: v2: (isInt v2 || isString v2 || isBool v2))x); + extractLists = l: + (imap1 (i: v: "WorkspaceSymbol-${toString i}: " + v) l.WorkspaceSymbols) ++ + (mapAttrsToList (n: v: "SNIIconSize: ${n}, ${toString v}") l.SNIIconSize) ++ + (mapAttrsToList (n: v: "SNIIconPaddingTop: ${n}, ${toString v}") l.SNIIconPaddingTop); - xdg.configFile."gBar/config" = lib.mkIf (cfg.extraConfig != null) { - text = cfg.extraConfig; + gBarConfig = (concatMapStrings (x: x + "\n") (attrValues (applyVal cfg.config)))+(concatMapStrings (x: x+"\n") (extractLists cfg.config)); + + in mkIf cfg.enable { + home.packages = optional (cfg.package != null) cfg.package; + + xdg.configFile."gBar/config" = mkIf (cfg.extraConfig != null) { + text = "# Generated by Home Manager\n" + gBarConfig + cfg.extraConfig; }; - xdg.configFile."gBar/style.css" = lib.mkIf (cfg.extraCSS != null) { + xdg.configFile."gBar/style.css" = mkIf (cfg.extraCSS != null) { text = cfg.extraCSS; }; };