nixos/settings/stylix.nix
ediblerope 5e479cc394 stylix: pull Papirus folder variants into the recoloured icon theme
Adwaita's scalable/places ships only the generic folder.svg, so
Downloads, Pictures, Music etc. all rendered as the same icon. Copy
Papirus' places at every size into WallpaperAdwaita and recolour the
Papirus blues to the stylix primary. Declare the sized places
directories in index.theme so GTK actually looks at them.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 09:44:48 +01:00

235 lines
7.2 KiB
Nix

{ config, pkgs, lib, inputs, ... }:
{
imports = [ inputs.stylix.nixosModules.stylix ];
config = lib.mkIf (lib.elem config.networking.hostName [ "FredOS-Gaming" "FredOS-Macbook" ]) {
stylix = {
enable = true;
image = "${inputs.self}/walls/wallpaper.png";
polarity = "dark";
# Let stylix theme every target it supports. Per-target opt-outs go
# under home-manager.users.fred.stylix.targets.<x>.enable = false.
autoEnable = true;
cursor = {
package = pkgs.adwaita-icon-theme;
name = "Adwaita";
size = 24;
};
fonts = {
monospace = {
package = pkgs.nerd-fonts.fira-mono;
name = "FiraMono Nerd Font";
};
sansSerif = {
package = pkgs.inter;
name = "Inter";
};
serif = {
package = pkgs.inter;
name = "Inter";
};
};
};
home-manager.users.fred = { config, lib, pkgs, ... }: let
c = config.lib.stylix.colors;
# Map matugen's Material You placeholders to the closest base16 slot
# in stylix's palette. The mapping is approximate (Material You has
# more semantic colours than base16), but covers the placeholders
# used in our Zen userChrome and Vesktop quickCss templates.
stylixize = builtins.replaceStrings
[
"{{colors.primary.default.hex}}"
"{{colors.primary_container.default.hex}}"
"{{colors.secondary_container.default.hex}}"
"{{colors.tertiary_container.default.hex}}"
"{{colors.surface.default.hex}}"
"{{colors.surface_container.default.hex}}"
"{{colors.surface_container_low.default.hex}}"
"{{colors.surface_container_high.default.hex}}"
"{{colors.on_surface.default.hex}}"
"{{colors.on_surface_variant.default.hex}}"
"{{colors.outline.default.hex}}"
"{{colors.outline_variant.default.hex}}"
]
[
"#${c.base0D}" # primary accent
"#${c.base02}" # primary container
"#${c.base0C}" # secondary container (cyan)
"#${c.base0E}" # tertiary container (purple)
"#${c.base00}" # surface (main bg)
"#${c.base01}" # surface container
"#${c.base00}" # surface container low
"#${c.base02}" # surface container high
"#${c.base05}" # on surface (fg)
"#${c.base04}" # on surface variant (muted fg)
"#${c.base03}" # outline
"#${c.base02}" # outline variant
];
in {
# Zen and Vesktop have no native stylix targets, so we keep the
# existing matugen CSS templates and substitute placeholders with
# stylix base16 colours at Nix-eval time.
home.file.".zen/fraudek5.Default Profile/chrome/userChrome.css".text =
stylixize (builtins.readFile "${inputs.self}/templates/zen-userChrome.css");
home.file.".config/vesktop/settings/quickCss.css".text =
stylixize (builtins.readFile "${inputs.self}/templates/vesktop-quickCss.css");
# Folder icon recolor — was a matugen post-hook, now driven by
# stylix's base16 palette. base0D is the conventional blue/accent
# slot, which is what we want for Adwaita-style folder icons.
home.activation.recolorFolders = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
ICON_DIR="$HOME/.local/share/icons/WallpaperAdwaita"
ADWAITA="/run/current-system/sw/share/icons/Adwaita"
PAPIRUS="/run/current-system/sw/share/icons/Papirus-Dark"
PRIMARY="#${config.lib.stylix.colors.base0D}"
$DRY_RUN_CMD mkdir -p "$ICON_DIR/scalable/places"
$DRY_RUN_CMD cat > "$ICON_DIR/index.theme" << 'THEME'
[Icon Theme]
Name=WallpaperAdwaita
Comment=Adwaita with stylix-coloured folders and Papirus mimetypes
Inherits=Adwaita,hicolor
DisplayDepth=32
[scalable/places]
Size=128
MinSize=16
MaxSize=512
Type=Scalable
Context=Places
[16x16/places]
Size=16
Type=Fixed
Context=Places
[22x22/places]
Size=22
Type=Fixed
Context=Places
[32x32/places]
Size=32
Type=Fixed
Context=Places
[48x48/places]
Size=48
Type=Fixed
Context=Places
[64x64/places]
Size=64
MinSize=32
MaxSize=128
Type=Scalable
Context=Places
[96x96/places]
Size=96
MinSize=64
MaxSize=256
Type=Scalable
Context=Places
[128x128/places]
Size=128
MinSize=64
MaxSize=512
Type=Scalable
Context=Places
[16x16/mimetypes]
Size=16
Type=Fixed
Context=MimeTypes
[22x22/mimetypes]
Size=22
Type=Fixed
Context=MimeTypes
[32x32/mimetypes]
Size=32
Type=Fixed
Context=MimeTypes
[48x48/mimetypes]
Size=48
Type=Fixed
Context=MimeTypes
[64x64/mimetypes]
Size=64
MinSize=32
MaxSize=128
Type=Scalable
Context=MimeTypes
[96x96/mimetypes]
Size=96
MinSize=64
MaxSize=256
Type=Scalable
Context=MimeTypes
[128x128/mimetypes]
Size=128
MinSize=64
MaxSize=512
Type=Scalable
Context=MimeTypes
THEME
if [ -d "$ADWAITA/scalable/places" ]; then
for svg in "$ADWAITA/scalable/places"/*.svg; do
name=$(basename "$svg")
$DRY_RUN_CMD sed \
-e "s/#438de6/$PRIMARY/gi" \
-e "s/#62a0ea/$PRIMARY/gi" \
-e "s/#a4caee/$PRIMARY/gi" \
-e "s/#afd4ff/$PRIMARY/gi" \
-e "s/#c0d5ea/$PRIMARY/gi" \
"$svg" > "$ICON_DIR/scalable/places/$name"
done
fi
# Papirus has proper distinct folder icons for Downloads, Pictures,
# Music, etc copy and recolour them with the wallpaper accent so
# we don't end up with a single generic folder everywhere.
for size in 16x16 22x22 32x32 48x48 64x64 96x96 128x128; do
if [ -d "$PAPIRUS/$size/places" ]; then
$DRY_RUN_CMD rm -rf "$ICON_DIR/$size/places"
$DRY_RUN_CMD mkdir -p "$ICON_DIR/$size/places"
for svg in "$PAPIRUS/$size/places"/*.svg; do
[ -f "$svg" ] || continue
name=$(basename "$svg")
$DRY_RUN_CMD sed \
-e "s/#5294e2/$PRIMARY/gi" \
-e "s/#4877b1/$PRIMARY/gi" \
-e "s/#729fcf/$PRIMARY/gi" \
-e "s/#689ad6/$PRIMARY/gi" \
"$svg" > "$ICON_DIR/$size/places/$name"
done
fi
done
for size in 16x16 22x22 32x32 48x48 64x64 96x96 128x128; do
if [ -d "$PAPIRUS/$size/mimetypes" ]; then
$DRY_RUN_CMD rm -rf "$ICON_DIR/$size/mimetypes"
$DRY_RUN_CMD mkdir -p "$ICON_DIR/$size/mimetypes"
$DRY_RUN_CMD cp -rL "$PAPIRUS/$size/mimetypes"/* "$ICON_DIR/$size/mimetypes/"
fi
done
$DRY_RUN_CMD ${pkgs.gtk3}/bin/gtk-update-icon-cache -f "$ICON_DIR" 2>/dev/null || true
'';
};
};
}