1{ config, lib, pkgs, ... }:
2
3with lib;
4{
5 options = {
6 gtk.iconCache.enable = mkOption {
7 type = types.bool;
8 default = config.services.xserver.enable;
9 defaultText = literalExpression "config.services.xserver.enable";
10 description = lib.mdDoc ''
11 Whether to build icon theme caches for GTK applications.
12 '';
13 };
14 };
15
16 config = mkIf config.gtk.iconCache.enable {
17
18 # (Re)build icon theme caches
19 # ---------------------------
20 # Each icon theme has its own cache. The difficult is that many
21 # packages may contribute with icons to the same theme by installing
22 # some icons.
23 #
24 # For instance, on my current NixOS system, the following packages
25 # (among many others) have icons installed into the hicolor icon
26 # theme: hicolor-icon-theme, psensor, wpa_gui, caja, etc.
27 #
28 # As another example, the mate icon theme has icons installed by the
29 # packages mate-icon-theme, mate-settings-daemon, and libmateweather.
30 #
31 # The HighContrast icon theme also has icons from different packages,
32 # like gnome-theme-extras and meld.
33
34 # When the cache is built all of its icons has to be known. How to
35 # implement this?
36 #
37 # I think that most themes have all icons installed by only one
38 # package. On my system there are 71 themes installed. Only 3 of them
39 # have icons installed from more than one package.
40 #
41 # If the main package of the theme provides a cache, presumably most
42 # of its icons will be available to applications without running this
43 # module. But additional icons offered by other packages will not be
44 # available. Therefore I think that it is good that the main theme
45 # package installs a cache (although it does not completely fixes the
46 # situation for packages installed with nix-env).
47 #
48 # The module solution presented here keeps the cache when there is
49 # only one package contributing with icons to the theme. Otherwise it
50 # rebuilds the cache taking into account the icons provided all
51 # packages.
52
53 environment.extraSetup = ''
54 # For each icon theme directory ...
55 find $out/share/icons -exec test -d {} ';' -mindepth 1 -maxdepth 1 -print0 | while read -d $'\0' themedir
56 do
57 # In order to build the cache, the theme dir should be
58 # writable. When the theme dir is a symbolic link to somewhere
59 # in the nix store it is not writable and it means that only
60 # one package is contributing to the theme. If it already has
61 # a cache, no rebuild is needed. Otherwise a cache has to be
62 # built, and to be able to do that we first remove the
63 # symbolic link and make a directory, and then make symbolic
64 # links from the original directory into the new one.
65
66 if [ ! -w "$themedir" -a -L "$themedir" -a ! -r "$themedir"/icon-theme.cache ]; then
67 name=$(basename "$themedir")
68 path=$(readlink -f "$themedir")
69 rm "$themedir"
70 mkdir -p "$themedir"
71 ln -s "$path"/* "$themedir"/
72 fi
73
74 # (Re)build the cache if the theme dir is writable, replacing any
75 # existing cache for the theme
76
77 if [ -w "$themedir" ]; then
78 rm -f "$themedir"/icon-theme.cache
79 ${pkgs.buildPackages.gtk3.out}/bin/gtk-update-icon-cache --ignore-theme-index "$themedir"
80 fi
81 done
82 '';
83 };
84
85}