gBar/module.nix
Edvin Källström f7ff25f605
Nix: fix invalid default value and extend documentation (#24)
Previous default value of date creates null option in gBar config and
crashed the bar, removes null as accepted option in SNIIcon* options as
that also crashes the bar. I also felt like documentation lacked so
wrote this.
2023-07-23 12:15:37 +02:00

242 lines
11 KiB
Nix

# Based on Hyprland's home-manager and NixOS module
self:
{ config
, lib
, pkgs
, ...
}:
with lib;
let
cfg = config.programs.gBar;
defaultGBarPackage = self.defaultPackage.x86_64-linux;
in {
options.programs.gBar = {
enable = mkEnableOption "Wether to enable gBar, a blazingly fast statusbar written in c++";
package = mkOption {
type = types.nullOr types.package;
default = defaultGBarPackage;
defaultText = literalExpression "<gBar flake>.packages.<system>.default";
example = literalExpression "<gBar flake>.packages.<system>.default.override { }";
description = ''
gBar package to use.
'';
};
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 = "%a %D - %H:%M:%S %Z";
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.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.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 you want to use your own config then set this to null and home manager wont write anything, neither the config
'';
};
extraCSS = mkOption {
type = types.nullOr types.lines;
default = null;
description = ''
Configuration to write to ~/.config/gBar/style.css, if none nothing happens
'';
};
};
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);
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" = mkIf (cfg.extraCSS != null) {
text = cfg.extraCSS;
};
};
}