From aab910d3a63b031f61f180a3621ed3a62824da4e Mon Sep 17 00:00:00 2001 From: soraefir Date: Fri, 5 Jun 2026 01:16:39 +0200 Subject: [PATCH] fix theme --- modules/home/gui/theme/wallpaper-gen.nix | 159 +++++++++++++++++++---- modules/shared/syscfg/media.nix | 2 +- 2 files changed, 133 insertions(+), 28 deletions(-) diff --git a/modules/home/gui/theme/wallpaper-gen.nix b/modules/home/gui/theme/wallpaper-gen.nix index a48713c..a7d0516 100644 --- a/modules/home/gui/theme/wallpaper-gen.nix +++ b/modules/home/gui/theme/wallpaper-gen.nix @@ -1,40 +1,145 @@ -{ pkgs, config }: +{ pkgs, config, lib ? pkgs.lib }: let - scheme = config.colorScheme; - colors = scheme.palette; - dither = - "atkinson"; # none | floyd-steinberg | atkinson | jjn | burkes | sierra | sierra-lite -in pkgs.stdenv.mkDerivation rec { - pname = "generated-wallpaper"; - version = "a1676fc2a0e3dfb7bf95d8a89e592830"; - src = pkgs.fetchFromGitea { - domain = "git.helcel.net"; - owner = "sora"; - repo = "nixconfig-wallpaper"; - rev = version; - sha256 = "sha256-ZhBjTaKzoiEq1ptMmNWWRPCjLJsvy9My/HuzRaDjX1c="; + colors = config.colorScheme.palette; + mediaImages = config.syscfg.media.main; + mediaNames = map (image: builtins.baseNameOf (toString image)) mediaImages; + + dither = "atkinson"; # none | floyd-steinberg | atkinson | jjn | burkes | sierra | sierra-lite + paletteSize = 0; + + hexChars = "0123456789abcdef"; + hexMap = { + "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; }; - buildInputs = with pkgs; [ custom.repalette nodejs imagemagick gifsicle ]; + baseColors = [ + colors.base00 + colors.base01 + colors.base02 + colors.base03 + colors.base04 + colors.base05 + colors.base06 + colors.base07 + colors.base08 + colors.base09 + colors.base0A + colors.base0B + colors.base0C + colors.base0D + colors.base0E + colors.base0F + ]; - configurePhase = '' - echo "${colors.base00},${colors.base01},\ - ${colors.base02},${colors.base03},\ - ${colors.base04},${colors.base05},\ - ${colors.base06},${colors.base07},\ - ${colors.base08},${colors.base09},\ - ${colors.base0A},${colors.base0B},\ - ${colors.base0C},${colors.base0D},\ - ${colors.base0E},${colors.base0F}" > palette.in - ''; + round = x: builtins.floor (x + 0.5); + clamp = x: + if x < 0 then 0 else if x > 255 then 255 else x; + parseHexByte = byte: + let + hi = hexMap.${builtins.substring 0 1 byte}; + lo = hexMap.${builtins.substring 1 1 byte}; + in + hi * 16 + lo; + hexToRgb = hex: + let + clean = lib.toLower (lib.removePrefix "#" hex); + in + { + r = parseHexByte (builtins.substring 0 2 clean); + g = parseHexByte (builtins.substring 2 2 clean); + b = parseHexByte (builtins.substring 4 2 clean); + }; + componentToHex = value: + let + bounded = clamp value; + hi = builtins.div bounded 16; + lo = bounded - hi * 16; + in + "${builtins.substring hi 1 hexChars}${builtins.substring lo 1 hexChars}"; + rgbToHex = color: "${componentToHex color.r}${componentToHex color.g}${componentToHex color.b}"; + + getTint = c: weight: round (c + (255 - c) * weight); + getShade = c: weight: round (c * weight); + tint = color: weight: { + r = getTint color.r weight; + g = getTint color.g weight; + b = getTint color.b weight; + }; + shade = color: weight: { + r = getShade color.r weight; + g = getShade color.g weight; + b = getShade color.b weight; + }; + genPalette = color: + let + tints = + if paletteSize == 0 + then [ ] + else lib.genList (i: tint color ((i + 1.0) / paletteSize)) paletteSize; + shades = + if paletteSize == 0 + then [ ] + else lib.genList (i: shade color (i * 1.0 / paletteSize)) paletteSize; + in + lib.reverseList tints ++ [ color ] ++ lib.reverseList shades; + keepColor = color: + let + sum = color.r + color.g + color.b; + in + sum > 0 && sum < 765; + + paletteColors = lib.concatMap (hex: lib.filter keepColor (genPalette (hexToRgb hex))) baseColors; + paletteHex = lib.concatStringsSep "," (map rgbToHex paletteColors); + gifPaletteFile = pkgs.writeText "wallpaper-gifpalette.txt" ( + lib.concatMapStringsSep "\n" (color: "${toString color.r} ${toString color.g} ${toString color.b}") paletteColors + ); + + buildCommands = + lib.concatMapStringsSep "\n" (image: + let + source = toString image; + name = builtins.baseNameOf source; + target = "build/${name}"; + in + if lib.hasSuffix ".gif" (lib.toLower name) then '' + gifsicle --use-colormap ${lib.escapeShellArg (toString gifPaletteFile)} < ${lib.escapeShellArg source} > ${lib.escapeShellArg target} + '' else '' + repalette ${lib.escapeShellArg source} ${lib.escapeShellArg target} -p ${lib.escapeShellArg paletteHex} --dither ${lib.escapeShellArg dither} + '' + ) mediaImages; +in +assert lib.assertMsg + (builtins.length mediaNames == builtins.length (lib.unique mediaNames)) + "syscfg.media.main contains duplicate basenames, which would collide in generated wallpaper output."; +pkgs.stdenv.mkDerivation { + pname = "generated-wallpaper"; + version = "local"; + dontUnpack = true; + + nativeBuildInputs = with pkgs; [ + custom.repalette + gifsicle + ]; buildPhase = '' - make DITHER=${dither} PALETTE_SIZE=0 all + runHook preBuild + + mkdir -p build + ${buildCommands} + + runHook postBuild ''; installPhase = '' + runHook preInstall + mkdir -p $out/share/wallpaper - cp -r build/* $out/share/wallpaper/ + cp -r build/. $out/share/wallpaper/ + + runHook postInstall ''; } diff --git a/modules/shared/syscfg/media.nix b/modules/shared/syscfg/media.nix index 495cc47..8fa1560 100644 --- a/modules/shared/syscfg/media.nix +++ b/modules/shared/syscfg/media.nix @@ -46,6 +46,6 @@ with lib; { bg = mkOption { type = types.path; - default = let bg = maybePath "main/bg.png"; in if bg != null then bg else builtins.head mainImages; + default = let bg = maybePath "main/main.png"; in if bg != null then bg else builtins.head mainImages; }; }