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