aboutsummaryrefslogtreecommitdiff
path: root/modules/services/polybar.nix
blob: 52ea7b4ec72e4bea43c2053e210f319f594863c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
{ config, lib, pkgs, ... }:

with lib;

let

  cfg = config.services.polybar;

  dag = config.lib.dag;

  toPolybarIni = generators.toINI {
    mkKeyValue = key: value:
    let
      value' =
        if isBool value then (if value then "true" else "false")
        else if (isString value && key != "include-file") then ''"${value}"''
        else toString value;
    in
      "${key}=${value'}";
  };

  configFile = pkgs.writeText "polybar.conf"
    (toPolybarIni cfg.config + "\n" + cfg.extraConfig);

  script = ''
    #!${pkgs.stdenv.shell}

    ${cfg.script}
  '';

in

{
  options = {
    services.polybar = {
      enable = mkEnableOption "Polybar status bar";

      package = mkOption {
        type = types.package;
        default = pkgs.polybar;
        defaultText = "pkgs.polybar";
        description = "Polybar package to install.";
        example =  literalExample ''
          pkgs.polybar.override {
            i3GapsSupport = true;
            alsaSupport = true;
            iwSupport = true;
            githubSupport = true;
          }
        '';
      };

      config = mkOption {
        type = types.coercedTo
          types.path
          (p: { "section/base" = { include-file = "${p}"; }; })
          (types.attrsOf types.attrs);
        description = ''
          Polybar configuration. Can be either path to a file, or set of attibutes
          that will be used to create the final configuration.
        '';
        default = {};
        example = literalExample ''
          {
            "bar/top" = {
              monitor = "\''${env:MONITOR:eDP1}";
              width = "100%";
              height = "3%";
              radius = 0;
              modules-center = "date";
            };

            "module/date" = {
              type = "internal/date";
              internal = 5;
              date = "%d.%m.%y";
              time = "%H:%M";
              label = "%time%  %date%";
            };
          }
        '';
      };

      extraConfig = mkOption {
        type = types.lines;
        description = "Additional configuration to add.";
        default = "";
        example = ''
          [module/date]
          type = internal/date
          interval = 5
          date = "%d.%m.%y"
          time = %H:%M
          format-prefix-foreground = \''${colors.foreground-alt}
          label = %time%  %date%
        '';
      };

      script = mkOption {
        type = types.lines;
        description = ''
          This script will be used to start the polybars.
          Set all necessary environment variables here and start all bars.
          It can be assumed that <command>polybar</command> executable is in the <envar>PATH</envar>.

          Note, this script must start all bars in the background and then terminate.
        '';
        example = "polybar bar &";
      };
    };
  };

  config = mkIf cfg.enable {
    home.packages = [ cfg.package ];
    xdg.configFile."polybar/config".source = configFile;

    systemd.user.services.polybar = {
      Unit = {
        Description = "Polybar status bar";
        After = [ "graphical-session-pre.target" ];
        PartOf = [ "graphical-session.target" ];
      };

      Service = {
        Type = "forking";
        Environment = "PATH=${cfg.package}/bin";
        ExecStart = ''${pkgs.writeScriptBin "polybar-start" script}/bin/polybar-start'';
      };

      Install = {
        WantedBy = [ "graphical-session.target" ];
      };
    };

    home.activation.checkPolybar = dag.entryBefore [ "linkGeneration" ] ''
      if ! cmp --quiet \
          "${configFile}" \
          "$HOME/.config/polybar/config"; then
        polybarChanged=1
      fi
    '';

    home.activation.applyPolybar = dag.entryAfter [ "reloadSystemD" ] ''
      if [[ -v polybarChanged && -v DISPLAY ]]; then
        echo "Restarting polybar"
        ${config.systemd.user.systemctlPath} --user restart polybar.service
      fi
    '';
  };

}