nixpkgs/nixos/modules/config/gtk/gtk-icon-cache.nix
2020-03-06 00:45:48 -05:00

87 lines
3.2 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
{
options = {
gtk.iconCache.enable = mkOption {
type = types.bool;
default = config.services.xserver.enable;
description = ''
Whether to build icon theme caches for GTK applications.
'';
};
};
config = mkIf config.gtk.iconCache.enable {
# (Re)build icon theme caches
# ---------------------------
# Each icon theme has its own cache. The difficult is that many
# packages may contribute with icons to the same theme by installing
# some icons.
#
# For instance, on my current NixOS system, the following packages
# (among many others) have icons installed into the hicolor icon
# theme: hicolor-icon-theme, psensor, wpa_gui, caja, etc.
#
# As another example, the mate icon theme has icons installed by the
# packages mate-icon-theme, mate-settings-daemon, and libmateweather.
#
# The HighContrast icon theme also has icons from different packages,
# like gnome-theme-extras and meld.
# When the cache is built all of its icons has to be known. How to
# implement this?
#
# I think that most themes have all icons installed by only one
# package. On my system there are 71 themes installed. Only 3 of them
# have icons installed from more than one package.
#
# If the main package of the theme provides a cache, presumably most
# of its icons will be available to applications without running this
# module. But additional icons offered by other packages will not be
# available. Therefore I think that it is good that the main theme
# package installs a cache (although it does not completely fixes the
# situation for packages installed with nix-env).
#
# The module solution presented here keeps the cache when there is
# only one package contributing with icons to the theme. Otherwise it
# rebuilds the cache taking into account the icons provided all
# packages.
environment.extraSetup = ''
# For each icon theme directory ...
find $out/share/icons -mindepth 1 -maxdepth 1 -print0 | while read -d $'\0' themedir
do
# In order to build the cache, the theme dir should be
# writable. When the theme dir is a symbolic link to somewhere
# in the nix store it is not writable and it means that only
# one package is contributing to the theme. If it already has
# a cache, no rebuild is needed. Otherwise a cache has to be
# built, and to be able to do that we first remove the
# symbolic link and make a directory, and then make symbolic
# links from the original directory into the new one.
if [ ! -w "$themedir" -a -L "$themedir" -a ! -r "$themedir"/icon-theme.cache ]; then
name=$(basename "$themedir")
path=$(readlink -f "$themedir")
rm "$themedir"
mkdir -p "$themedir"
ln -s "$path"/* "$themedir"/
fi
# (Re)build the cache if the theme dir is writable, replacing any
# existing cache for the theme
if [ -w "$themedir" ]; then
rm -f "$themedir"/icon-theme.cache
${pkgs.buildPackages.gtk3.out}/bin/gtk-update-icon-cache --ignore-theme-index "$themedir"
fi
done
'';
};
}