The `pkgs.yabar` package is relatively old (2016-04) and contains several issues fixed on master. `yabar-unstable` containsa recent master build with several fixes and a lot of new features (I use `yabar-unstable` for some time now and had no issues with it). In the upstream bugtracker some bugs could be fixed on ArchLinux by simply installing `yabar-git` (an AUR package which builds a recent master). To stabilize the module, the option `programs.yabar.package` now defaults to `pkgs.yabar-unstable` and yields a warning with several linked issues that are known on `pkgs.yabar`. The test has been refactored as well to ensure that `yabar` actually starts (and avoid non-deterministic random success) and takes a screenshot of a very minimalistic configuration on IceWM. Fixes #46899
		
			
				
	
	
		
			163 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ lib, pkgs, config, ... }:
 | 
						|
 | 
						|
with lib;
 | 
						|
 | 
						|
let
 | 
						|
  cfg = config.programs.yabar;
 | 
						|
 | 
						|
  mapExtra = v: lib.concatStringsSep "\n" (mapAttrsToList (
 | 
						|
    key: val: "${key} = ${if (isString val) then "\"${val}\"" else "${builtins.toString val}"};"
 | 
						|
  ) v);
 | 
						|
 | 
						|
  listKeys = r: concatStringsSep "," (map (n: "\"${n}\"") (attrNames r));
 | 
						|
 | 
						|
  configFile = let
 | 
						|
    bars = mapAttrsToList (
 | 
						|
      name: cfg: ''
 | 
						|
        ${name}: {
 | 
						|
          font: "${cfg.font}";
 | 
						|
          position: "${cfg.position}";
 | 
						|
 | 
						|
          ${mapExtra cfg.extra}
 | 
						|
 | 
						|
          block-list: [${listKeys cfg.indicators}]
 | 
						|
 | 
						|
          ${concatStringsSep "\n" (mapAttrsToList (
 | 
						|
            name: cfg: ''
 | 
						|
              ${name}: {
 | 
						|
                exec: "${cfg.exec}";
 | 
						|
                align: "${cfg.align}";
 | 
						|
                ${mapExtra cfg.extra}
 | 
						|
              };
 | 
						|
            ''
 | 
						|
          ) cfg.indicators)}
 | 
						|
        };
 | 
						|
      ''
 | 
						|
    ) cfg.bars;
 | 
						|
  in pkgs.writeText "yabar.conf" ''
 | 
						|
    bar-list = [${listKeys cfg.bars}];
 | 
						|
    ${concatStringsSep "\n" bars}
 | 
						|
  '';
 | 
						|
in
 | 
						|
  {
 | 
						|
    options.programs.yabar = {
 | 
						|
      enable = mkEnableOption "yabar";
 | 
						|
 | 
						|
      package = mkOption {
 | 
						|
        default = pkgs.yabar-unstable;
 | 
						|
        example = literalExample "pkgs.yabar";
 | 
						|
        type = types.package;
 | 
						|
 | 
						|
        # `yabar-stable` segfaults under certain conditions.
 | 
						|
        apply = x: if x == pkgs.yabar-unstable then x else flip warn x ''
 | 
						|
          It's not recommended to use `yabar' with `programs.yabar', the (old) stable release
 | 
						|
          tends to segfault under certain circumstances:
 | 
						|
 | 
						|
          * https://github.com/geommer/yabar/issues/86
 | 
						|
          * https://github.com/geommer/yabar/issues/68
 | 
						|
          * https://github.com/geommer/yabar/issues/143
 | 
						|
 | 
						|
          Most of them don't occur on master anymore, until a new release is published, it's recommended
 | 
						|
          to use `yabar-unstable'.
 | 
						|
        '';
 | 
						|
 | 
						|
        description = ''
 | 
						|
          The package which contains the `yabar` binary.
 | 
						|
 | 
						|
          Nixpkgs provides the `yabar` and `yabar-unstable`
 | 
						|
          derivations since 18.03, so it's possible to choose.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      bars = mkOption {
 | 
						|
        default = {};
 | 
						|
        type = types.attrsOf(types.submodule {
 | 
						|
          options = {
 | 
						|
            font = mkOption {
 | 
						|
              default = "sans bold 9";
 | 
						|
              example = "Droid Sans, FontAwesome Bold 9";
 | 
						|
              type = types.string;
 | 
						|
 | 
						|
              description = ''
 | 
						|
                The font that will be used to draw the status bar.
 | 
						|
              '';
 | 
						|
            };
 | 
						|
 | 
						|
            position = mkOption {
 | 
						|
              default = "top";
 | 
						|
              example = "bottom";
 | 
						|
              type = types.enum [ "top" "bottom" ];
 | 
						|
 | 
						|
              description = ''
 | 
						|
                The position where the bar will be rendered.
 | 
						|
              '';
 | 
						|
            };
 | 
						|
 | 
						|
            extra = mkOption {
 | 
						|
              default = {};
 | 
						|
              type = types.attrsOf types.string;
 | 
						|
 | 
						|
              description = ''
 | 
						|
                An attribute set which contains further attributes of a bar.
 | 
						|
              '';
 | 
						|
            };
 | 
						|
 | 
						|
            indicators = mkOption {
 | 
						|
              default = {};
 | 
						|
              type = types.attrsOf(types.submodule {
 | 
						|
                options.exec = mkOption {
 | 
						|
                  example = "YABAR_DATE";
 | 
						|
                  type = types.string;
 | 
						|
                  description = ''
 | 
						|
                     The type of the indicator to be executed.
 | 
						|
                  '';
 | 
						|
                };
 | 
						|
 | 
						|
                options.align = mkOption {
 | 
						|
                  default = "left";
 | 
						|
                  example = "right";
 | 
						|
                  type = types.enum [ "left" "center" "right" ];
 | 
						|
 | 
						|
                  description = ''
 | 
						|
                    Whether to align the indicator at the left or right of the bar.
 | 
						|
                  '';
 | 
						|
                };
 | 
						|
 | 
						|
                options.extra = mkOption {
 | 
						|
                  default = {};
 | 
						|
                  type = types.attrsOf (types.either types.string types.int);
 | 
						|
 | 
						|
                  description = ''
 | 
						|
                    An attribute set which contains further attributes of a indicator.
 | 
						|
                  '';
 | 
						|
                };
 | 
						|
              });
 | 
						|
 | 
						|
              description = ''
 | 
						|
                Indicators that should be rendered by yabar.
 | 
						|
              '';
 | 
						|
            };
 | 
						|
          };
 | 
						|
        });
 | 
						|
 | 
						|
        description = ''
 | 
						|
          List of bars that should be rendered by yabar.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
    };
 | 
						|
 | 
						|
    config = mkIf cfg.enable {
 | 
						|
      systemd.user.services.yabar = {
 | 
						|
        description = "yabar service";
 | 
						|
        wantedBy = [ "graphical-session.target" ];
 | 
						|
        partOf = [ "graphical-session.target" ];
 | 
						|
 | 
						|
        script = ''
 | 
						|
          ${cfg.package}/bin/yabar -c ${configFile}
 | 
						|
        '';
 | 
						|
 | 
						|
        serviceConfig.Restart = "always";
 | 
						|
      };
 | 
						|
    };
 | 
						|
  }
 |