This commit is contained in:
ediblerope 2026-05-15 22:11:57 +01:00
parent 00e37be9db
commit ceebf1b3ee
3 changed files with 56 additions and 163 deletions

View file

@ -41,6 +41,54 @@
home-manager.users.fred = { config, lib, pkgs, ... }: let
c = config.lib.stylix.colors;
# Pure-Nix hex parsing for color distance calculation.
hexDigit = ch: {
"0"=0;"1"=1;"2"=2;"3"=3;"4"=4;"5"=5;"6"=6;"7"=7;
"8"=8;"9"=9;"a"=10;"b"=11;"c"=12;"d"=13;"e"=14;"f"=15;
}.${ch};
hexByte = s: hexDigit (builtins.substring 0 1 s) * 16
+ hexDigit (builtins.substring 1 1 s);
hexToRgb = hex: let h = lib.toLower hex; in {
r = hexByte (builtins.substring 0 2 h);
g = hexByte (builtins.substring 2 2 h);
b = hexByte (builtins.substring 4 2 h);
};
# papirus-folders named palette → representative hex values.
pfPalette = {
adwaita="3584e4"; black="000000"; bluegrey="607d8b"; breeze="1d99f3";
brown="795548"; cyan="00bcd4"; darkcyan="00838f"; deeporange="ff5722";
green="4caf50"; grey="9e9e9e"; indigo="3f51b5"; magenta="e91e63";
nordic="5e81ac"; orange="ff9800"; palebrown="a1887f"; palegreen="8bc34a";
pink="f06292"; red="f44336"; teal="009688"; violet="9c27b0";
white="ffffff"; yellow="ffeb3b";
};
# Closest papirus-folders color to stylix's accent (base0D), chosen at
# eval time via squared RGB distance — no runtime script needed.
closestPfColor =
let
sq = x: x * x;
dist = a: b: sq (a.r - b.r) + sq (a.g - b.g) + sq (a.b - b.b);
accent = hexToRgb c.base0D;
ranked = map (n: { name = n; d = dist accent (hexToRgb pfPalette.${n}); })
(builtins.attrNames pfPalette);
in (builtins.foldl' (best: x: if x.d < best.d then x else best)
(builtins.head ranked)
(builtins.tail ranked)).name;
# Papirus-Dark with folders recolored to the closest matching color.
# Built as a derivation so it lands in the nix store — no activation scripts.
papirusDark = pkgs.runCommand "papirus-dark-${closestPfColor}" {
nativeBuildInputs = [ pkgs.papirus-folders ];
} ''
mkdir -p $out/share/icons
cp -r ${pkgs.papirus-icon-theme}/share/icons/Papirus-Dark $out/share/icons/
chmod -R u+w $out/share/icons/Papirus-Dark
papirus-folders -C ${closestPfColor} --path $out/share/icons
'';
# 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
@ -84,165 +132,10 @@
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}"
CACHE_FILE="$ICON_DIR/.color-cache"
# Skip the SVG recolour pass if the palette colour hasn't changed.
if [ -f "$CACHE_FILE" ] && [ "$(cat "$CACHE_FILE" 2>/dev/null)" = "$PRIMARY" ] && [ -d "$ICON_DIR/scalable/places" ]; then
echo "recolorFolders: palette unchanged, skipping"
else
$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
$DRY_RUN_CMD sh -c "echo '$PRIMARY' > '$CACHE_FILE'"
fi # end palette-changed block
'';
gtk.iconTheme = {
package = papirusDark;
name = "Papirus-Dark";
};
};
};
}