refactor(themes): drop projects/themes, generate colorschemes purely

With the matugen IFD replaced by lib/material-you.nix, projects/themes only existed
to cache that IFD, so remove it:

- Move wallpapers/ to the repo root. Each wallpaper now carries its material-you
  source color (extracted once, committed in list.json) in passthru, so schemes
  generate with no image decoding at eval.
- Expose pkgs.wallpapers via the additions overlay, and a 'wallpapers'
  linkFarm package so Hydra builds+caches every image (imgur is upstream).
- Fold colorscheme generation into modules/home-manager/colors.nix: it now
  calls outputs.lib.material-you.generateColorscheme on the source color (the
  wallpaper's sourceColor or a hex) instead of the matugen derivation. No IFD,
  no generatedDrv.
- wallpaper option is now types.package (preserves the sourceColor passthru).
- Drop the themes flake input and its Hydra job; wallpapers ride the pkgs job.

Verified: atlas evaluates to a full toplevel; its colors match matugen 2.4.1
for the aenami-dawn seed (roles exact, one custom channel +-1 LSB).

Assisted-by: pi (opus-4.8)
This commit is contained in:
Gabriel Fontes
2026-07-04 18:39:47 -03:00
parent 0627287979
commit be533b7e49
23 changed files with 464 additions and 407 deletions
Generated
-34
View File
@@ -379,22 +379,6 @@
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1767313136,
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"pre-commit": {
"inputs": {
"flake-compat": "flake-compat",
@@ -432,7 +416,6 @@
"nixpkgs": "nixpkgs",
"sops-nix": "sops-nix",
"systems": "systems_2",
"themes": "themes",
"website": "website"
}
},
@@ -507,23 +490,6 @@
"type": "github"
}
},
"themes": {
"inputs": {
"nixpkgs": "nixpkgs_2",
"systems": [
"systems"
]
},
"locked": {
"path": "./projects/themes",
"type": "path"
},
"original": {
"path": "./projects/themes",
"type": "path"
},
"parent": []
},
"website": {
"inputs": {
"nixpkgs": [
+13 -6
View File
@@ -61,10 +61,6 @@
};
# My own programs, packaged with nix
themes = {
url = "path:./projects/themes";
inputs.systems.follows = "systems";
};
website = {
url = "path:./projects/website";
inputs.nixpkgs.follows = "nixpkgs";
@@ -83,7 +79,10 @@
lib = let
base = nixpkgs.lib // home-manager.lib;
in
base // {colors = import ./lib/colors.nix {lib = base;};};
base // {
colors = import ./lib/colors.nix {lib = base;};
material-you = import ./lib/material-you.nix {lib = base;};
};
forEachSystem = f: lib.genAttrs (import systems) (system: f pkgsFor.${system});
pkgsFor = lib.genAttrs (import systems) (
system:
@@ -100,7 +99,15 @@
overlays = import ./overlays {inherit inputs outputs;};
hydraJobs = import ./hydra.nix {inherit inputs outputs;};
packages = forEachSystem (pkgs: import ./pkgs {inherit pkgs;});
packages = forEachSystem (
pkgs:
import ./pkgs {inherit pkgs;}
// {
# All wallpapers as one derivation, so Hydra builds + caches them
# (imgur is the only upstream; this is our backup).
wallpapers = pkgs.linkFarmFromDrvs "wallpapers" (lib.attrValues (import ./wallpapers {inherit pkgs;}));
}
);
devShells = forEachSystem (pkgs: import ./shell.nix {inherit pkgs;});
formatter = forEachSystem (pkgs: pkgs.alejandra);
+1 -1
View File
@@ -1,5 +1,5 @@
{pkgs, ...}: {
imports = [./global];
# Yellow
wallpaper = pkgs.inputs.themes.wallpapers.lake-houses-sunset-gold;
wallpaper = pkgs.wallpapers.lake-houses-sunset-gold;
}
+1 -1
View File
@@ -15,7 +15,7 @@
];
# Red
wallpaper = pkgs.inputs.themes.wallpapers.aenami-dawn;
wallpaper = pkgs.wallpapers.aenami-dawn;
# ------ ----- ------
# | DP-3 | | DP-1| | DP-2 |
+1 -1
View File
@@ -1,5 +1,5 @@
{pkgs, ...}: {
imports = [./global];
# Salmon
wallpaper = pkgs.inputs.themes.wallpapers.abstract-salmon-blue;
wallpaper = pkgs.wallpapers.abstract-salmon-blue;
}
+1 -1
View File
@@ -10,7 +10,7 @@
];
# Purple
wallpaper = pkgs.inputs.themes.wallpapers.deer-lunar-fantasy;
wallpaper = pkgs.wallpapers.deer-lunar-fantasy;
monitors = [
{
+1 -1
View File
@@ -1,5 +1,5 @@
{pkgs, ...}: {
imports = [./global];
# Blue
wallpaper = pkgs.inputs.themes.wallpapers.towers-ice;
wallpaper = pkgs.wallpapers.towers-ice;
}
+1 -1
View File
@@ -1,5 +1,5 @@
{pkgs, ...}: {
imports = [./global];
# Green
wallpaper = pkgs.inputs.themes.wallpapers.plains-flowers-green-red;
wallpaper = pkgs.wallpapers.plains-flowers-green-red;
}
+1 -1
View File
@@ -1,5 +1,5 @@
{pkgs, ...}: {
imports = [./global];
# Cyan
wallpaper = pkgs.inputs.themes.wallpapers.nebula-cyan-yellow;
wallpaper = pkgs.wallpapers.nebula-cyan-yellow;
}
-1
View File
@@ -16,7 +16,6 @@
pkgs;
in {
pkgs = lib.mapAttrs filterValidPkgs outputs.packages;
themes = inputs.themes.hydraJobs;
hosts = lib.mapAttrs (_: cfg: cfg.config.system.build.toplevel) outputs.nixosConfigurations;
homes = lib.mapAttrs (_: cfg: cfg.activationPackage) outputs.homeConfigurations;
}
+21 -11
View File
@@ -1,7 +1,6 @@
{
lib,
config,
pkgs,
outputs,
...
}: let
@@ -11,29 +10,40 @@
hexColor = types.strMatching "#([0-9a-fA-F]{3}){1,2}";
in {
options.colorscheme = {
# Source color (hex). Defaults to the wallpaper's precomputed sourceColor
# (matugen's extracted seed, committed in wallpapers/list.json), so schemes
# are generated purely with no image decoding / IFD.
source = mkOption {
type = types.either types.path hexColor;
type = hexColor;
default =
if config.wallpaper != null
then config.wallpaper
then config.wallpaper.sourceColor
else "#2B3975";
};
mode = mkOption {
type = types.enum ["dark" "light"];
default = "dark";
};
type = mkOption {
type = types.str;
default = "rainbow";
# Extra named colors, harmonized toward the source (matugen custom_colors).
customColors = mkOption {
type = types.attrsOf hexColor;
default = {
red = "#dd0000";
orange = "#dd5522";
yellow = "#dddd00";
green = "#22dd22";
cyan = "#22dddd";
blue = "#2222dd";
magenta = "#dd22dd";
};
};
generatedDrv = mkOption {
type = types.package;
default = pkgs.inputs.themes.generateColorscheme (cfg.source.name or "default") cfg.source;
};
# Full pure-Nix material-you scheme ({ colors = { dark; light; }; }),
# generated by lib/material-you.nix (rainbow variant, standard contrast).
rawColorscheme = mkOption {
type = types.attrs;
default = cfg.generatedDrv.imported.${cfg.type};
default = outputs.lib.material-you.generateColorscheme cfg.source cfg.customColors;
};
colors = mkOption {
+4 -2
View File
@@ -2,10 +2,12 @@
inherit (lib) types mkOption;
in {
options.wallpaper = mkOption {
type = types.nullOr types.path;
# A package (image derivation), so its `sourceColor` passthru survives for
# the colorscheme. Coerces to its path in string context (e.g. hyprpaper).
type = types.nullOr types.package;
default = null;
description = ''
Wallpaper path
Wallpaper image (a package, typically `pkgs.wallpapers.<name>`).
'';
};
}
+1
View File
@@ -28,6 +28,7 @@ in {
additions = final: prev:
import ../pkgs {pkgs = final;}
// {
wallpapers = import ../wallpapers {pkgs = final;};
formats = (prev.formats or {}) // import ../pkgs/formats {pkgs = final;};
roundcubePlugins = (prev.roundcubePlugins or {}) // import ../pkgs/roundcube-plugins {pkgs = final;};
};
-14
View File
@@ -1,14 +0,0 @@
{
"main": {
"enabled": 1,
"type": 1,
"hidden": false,
"description": "Build main branch",
"flake": "git://m7.rs/themes?ref=main",
"checkinterval": 60,
"schedulingshares": 10,
"enableemail": false,
"emailoverride": "",
"keepnr": 1
}
}
-7
View File
@@ -1,7 +0,0 @@
{
pkgs,
wallpapers,
generateColorscheme,
...
}:
pkgs.lib.mapAttrs (_: v: generateColorscheme v.name v) wallpapers
@@ -1,42 +0,0 @@
{pkgs, ...}: let
inherit (pkgs) lib;
generateColorscheme = name: source: let
schemeTypes = ["content" "expressive" "fidelity" "fruit-salad" "monochrome" "neutral" "rainbow" "tonal-spot"];
isHexColor = c: lib.isString c && (builtins.match "#([0-9a-fA-F]{3}){1,2}" c) != null;
config = (pkgs.formats.toml {}).generate "config.toml" {
templates = {};
config = {
custom_colors = {
red = "#dd0000";
orange = "#dd5522";
yellow = "#dddd00";
green = "#22dd22";
cyan = "#22dddd";
blue = "#2222dd";
magenta = "#dd22dd";
};
};
};
in
pkgs.runCommand "colorscheme-${name}" {
# __contentAddressed = true;
passthru = let
drv = generateColorscheme name source;
in {
inherit schemeTypes;
# Incurs IFD
imported = lib.genAttrs schemeTypes (scheme: lib.importJSON "${drv}/${scheme}.json");
};
} ''
mkdir "$out" -p
for type in ${lib.concatStringsSep " " schemeTypes}; do
${pkgs.matugen}/bin/matugen ${
if (isHexColor source)
then "color hex"
else "image"
} --config ${config} -j hex -t "scheme-$type" "${source}" > "$out/$type.json"
done
'';
in
generateColorscheme
-43
View File
@@ -1,43 +0,0 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1767313136,
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
"type": "github"
},
"original": {
"owner": "nixos",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"systems": "systems"
}
},
"systems": {
"locked": {
"lastModified": 1689347949,
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
"owner": "nix-systems",
"repo": "default-linux",
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default-linux",
"type": "github"
}
}
},
"root": "root",
"version": 7
}
-30
View File
@@ -1,30 +0,0 @@
{
description = "Personal wallpapers and colorschemes";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
systems.url = "github:nix-systems/default-linux";
};
outputs = {
nixpkgs,
systems,
...
}: let
forEachSystem = nixpkgs.lib.genAttrs (import systems);
in rec {
packages = forEachSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
in rec {
# My wallpaper collection
wallpapers = import ./wallpapers {inherit pkgs;};
allWallpapers = pkgs.linkFarmFromDrvs "wallpapers" (pkgs.lib.attrValues wallpapers);
# And colorschemes based on it
generateColorscheme = import ./colorschemes/generator.nix {inherit pkgs;};
colorschemes = import ./colorschemes {inherit pkgs wallpapers generateColorscheme;};
allColorschemes = pkgs.linkFarmFromDrvs "colorschemes" (pkgs.lib.attrValues colorschemes);
});
hydraJobs = nixpkgs.lib.mapAttrs (_: nixpkgs.lib.filterAttrs (_: nixpkgs.lib.isDerivation)) packages;
};
}
-11
View File
@@ -1,11 +0,0 @@
{pkgs}:
pkgs.lib.listToAttrs (
map (wallpaper: {
inherit (wallpaper) name;
value = pkgs.fetchurl {
inherit (wallpaper) sha256;
name = "${wallpaper.name}.${wallpaper.ext}";
url = "https://i.imgur.com/${wallpaper.id}.${wallpaper.ext}";
};
}) (pkgs.lib.importJSON ./list.json)
)
+20
View File
@@ -0,0 +1,20 @@
# My wallpaper collection. Each wallpaper is fetched from imgur and carries a
# precomputed `sourceColor` (matugen's extracted seed) in passthru, so the
# colorscheme can be generated purely (no image decoding / IFD at eval time).
# Regenerate seeds with the helper in modules/home-manager/colors.nix notes.
{pkgs}: let
inherit (pkgs) lib;
mk = w:
(pkgs.fetchurl {
inherit (w) sha256;
name = "${w.name}.${w.ext}";
url = "https://i.imgur.com/${w.id}.${w.ext}";
})
.overrideAttrs (old: {
passthru = (old.passthru or {}) // {inherit (w) sourceColor;};
});
in
lib.listToAttrs (map (w: {
inherit (w) name;
value = mk w;
}) (lib.importJSON ./list.json))
File diff suppressed because it is too large Load Diff