main
 1{lib, ...}: {
 2  den.aspects.desktop.aesthetic.cursor = {
 3    settings.host = {
 4      name = lib.mkOption {
 5        type = lib.types.nullOr lib.types.str;
 6        # default = null;
 7        default = "Bibata-Modern-Classic";
 8      };
 9      package = lib.mkOption {
10        type = lib.types.nullOr (lib.types.functionTo lib.types.package);
11        # default = null;
12        default = pkgs: pkgs.bibata-cursors;
13      };
14      size = lib.mkOption {
15        type = lib.types.ints.positive;
16        default = 24;
17      };
18    };
19
20    nixos = {host, ...}: let
21      cfg = host.settings.desktop.aesthetic.cursor;
22      allOrNothing = (cfg.name != null) == (cfg.package != null);
23    in {
24      assertions = [
25        {
26          assertion = allOrNothing;
27          message = "desktop.aesthetic.cursor: name/package/size must be set all or none.";
28        }
29      ];
30
31      environment.variables = {
32        XCURSOR_SIZE = toString cfg.size;
33      };
34    };
35
36    provides.to-users.hjem = {
37      host,
38      pkgs,
39      config,
40      ...
41    }: let
42      cfg = host.settings.desktop.aesthetic.cursor;
43
44      defaultIndexThemePackage = pkgs.writeTextFile {
45        name = "index.theme";
46        destination = "/share/icons/default/index.theme";
47        # `Name` is required for compatibility with AwesomeWM etc. See
48        # https://github.com/nix-community/home-manager/issues/2081
49        text = ''
50          [Icon Theme]
51          Name=Default
52          Comment=Default Cursor Theme
53          Inherits=${cfg.name}
54        '';
55      };
56    in
57      lib.optionalAttrs (cfg.package != null && cfg.name != null) {
58        packages = [
59          (cfg.package pkgs)
60          defaultIndexThemePackage
61        ];
62
63        environment.sessionVariables = {
64          XCURSOR_THEME = cfg.name;
65          XCURSOR_SIZE = toString cfg.size;
66          XCURSOR_PATH = "${config.xdg.data.directory}/icons";
67        };
68
69        xdg.data.files = {
70          "icons/default/index.theme".source = "${defaultIndexThemePackage}/share/icons/default/index.theme";
71          "icons/${cfg.name}".source = "${cfg.package pkgs}/share/icons/${cfg.name}";
72        };
73        files = {
74          ".icons/default/index.theme".source = "${defaultIndexThemePackage}/share/icons/default/index.theme";
75          ".icons/${cfg.name}".source = "${cfg.package pkgs}/share/icons/${cfg.name}";
76          ".Xresources".text = ''
77            Xcursor.size: ${toString cfg.size}
78            Xcursor.theme: ${cfg.name}
79          '';
80        };
81      };
82  };
83}