Migrate to hm managed theme switch
This commit is contained in:
@@ -199,7 +199,6 @@
|
|||||||
# Applications
|
# Applications
|
||||||
inputs.copyparty.nixosModules.default
|
inputs.copyparty.nixosModules.default
|
||||||
inputs.vscode-server.nixosModules.default
|
inputs.vscode-server.nixosModules.default
|
||||||
inputs.stylix.nixosModules.stylix
|
|
||||||
inputs.nix-ld.nixosModules.nix-ld
|
inputs.nix-ld.nixosModules.nix-ld
|
||||||
inputs.minegrub-theme.nixosModules.default
|
inputs.minegrub-theme.nixosModules.default
|
||||||
inputs.backlog.nixosModules.default
|
inputs.backlog.nixosModules.default
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, options, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
@@ -18,6 +18,35 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
# Generate all theme-variant combinations
|
||||||
|
themeVariants = concatMapAttrs (name: theme: {
|
||||||
|
"${name}-dark" = { scheme = theme.dark; polarity = "dark"; };
|
||||||
|
"${name}-light" = { scheme = theme.light; polarity = "light"; };
|
||||||
|
}) cfg.themes;
|
||||||
|
|
||||||
|
# Base is gruvbox-dark, everything else is a specialisation
|
||||||
|
baseVariant = "gruvbox-dark";
|
||||||
|
specialisationVariants = filterAttrs (name: _: name != baseVariant) themeVariants;
|
||||||
|
|
||||||
|
availableVariants = concatStringsSep " " (attrNames themeVariants);
|
||||||
|
|
||||||
|
# Userspace theme switcher: activates a pre-built Home Manager
|
||||||
|
# specialisation generation. No sudo, no OS rebuild — just runs the
|
||||||
|
# specialisation's activation script in the base HM generation.
|
||||||
|
#
|
||||||
|
# The script logic lives in ./theme-switch.sh (plain shell, no Nix
|
||||||
|
# escaping); we only inject the two config-derived values it needs.
|
||||||
|
theme-switch = pkgs.writeShellScriptBin "theme-switch" ''
|
||||||
|
baseVariant="${baseVariant}"
|
||||||
|
availableVariants="${availableVariants}"
|
||||||
|
${builtins.readFile ./theme-switch.sh}
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Stylix is only declared on hosts that import its Home Manager module
|
||||||
|
# (e.g. `fujin`). Servers (susano, izanagi, amaterasu, ...) don't, so
|
||||||
|
# `stylix` isn't declared there. We probe option *declarations* (not
|
||||||
|
# config values) to avoid an evaluation cycle.
|
||||||
|
hasStylix = options ? stylix;
|
||||||
in {
|
in {
|
||||||
options.dov.dynamic-theme = {
|
options.dov.dynamic-theme = {
|
||||||
enable = mkEnableOption "dynamic theme switching";
|
enable = mkEnableOption "dynamic theme switching";
|
||||||
@@ -40,12 +69,35 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable (
|
||||||
# HM-level stylix config inherits from NixOS level
|
{
|
||||||
# Specialisations are handled by NixOS module
|
home.packages = [ theme-switch ];
|
||||||
stylix = {
|
}
|
||||||
enable = true;
|
# Only reference the `stylix` option where it is actually declared.
|
||||||
autoEnable = true;
|
# `mkIf false` is NOT enough: the module system still rejects a
|
||||||
};
|
# definition (even a disabled one) for an option that does not exist,
|
||||||
};
|
# which breaks every host that doesn't import stylix. `optionalAttrs`
|
||||||
|
# removes the key structurally, so non-stylix hosts evaluate cleanly.
|
||||||
|
// optionalAttrs hasStylix {
|
||||||
|
stylix = {
|
||||||
|
enable = true;
|
||||||
|
autoEnable = true;
|
||||||
|
# Base scheme/polarity; overridable per specialisation below.
|
||||||
|
base16Scheme = mkDefault themeVariants.${baseVariant}.scheme;
|
||||||
|
polarity = mkDefault themeVariants.${baseVariant}.polarity;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Generate Home Manager specialisations for every non-base variant.
|
||||||
|
# Each is pre-built into the nix store during the single rebuild and
|
||||||
|
# activated userspace via `theme-switch` (no sudo, no OS rebuild).
|
||||||
|
specialisation = mapAttrs (name: variant: {
|
||||||
|
configuration = {
|
||||||
|
stylix = {
|
||||||
|
base16Scheme = mkForce variant.scheme;
|
||||||
|
polarity = mkForce variant.polarity;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}) specialisationVariants;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
# shellcheck shell=bash
|
||||||
|
# theme-switch — activate a pre-built Home Manager specialisation.
|
||||||
|
#
|
||||||
|
# Expects two variables to be injected by the Nix wrapper:
|
||||||
|
# baseVariant the variant that is the generation itself (not a
|
||||||
|
# specialisation), activated via `$gen/activate`.
|
||||||
|
# availableVariants space-separated list of all variant names (help text).
|
||||||
|
#
|
||||||
|
# Standalone usage for testing:
|
||||||
|
# baseVariant=gruvbox-dark \
|
||||||
|
# availableVariants="gruvbox-dark gruvbox-light catppuccin-dark catppuccin-light" \
|
||||||
|
# bash theme-switch.sh <variant>
|
||||||
|
|
||||||
|
: "${baseVariant:?theme-switch: baseVariant not set}"
|
||||||
|
: "${availableVariants:?theme-switch: availableVariants not set}"
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
variant="${1:-}"
|
||||||
|
|
||||||
|
if [ -z "$variant" ]; then
|
||||||
|
echo "Usage: theme-switch <variant>"
|
||||||
|
echo "Available: ${availableVariants}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Resolve the Home Manager *base* generation — the one built by NixOS that
|
||||||
|
# actually contains the `specialisation/` directory holding every variant's
|
||||||
|
# activation script.
|
||||||
|
#
|
||||||
|
# IMPORTANT: do NOT use `current-home` / the HM profile as the primary
|
||||||
|
# source. Activating a specialisation repoints those to the specialisation's
|
||||||
|
# *leaf* generation, which has no `specialisation/` of its own — so after
|
||||||
|
# switching once, every other variant (and the base) would become unfindable.
|
||||||
|
# The NixOS-managed `home-manager-«user».service` unit references the base
|
||||||
|
# generation and only changes on a rebuild.
|
||||||
|
user="${USER:-$(id -un)}"
|
||||||
|
gen=""
|
||||||
|
if unit="$(systemctl cat "home-manager-${user}.service" 2>/dev/null)"; then
|
||||||
|
gen="$(printf '%s\n' "$unit" | grep -oE '/nix/store/[0-9a-z]+-home-manager-generation' | head -n1)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fallbacks for standalone Home Manager, where the profile symlink / gcroot
|
||||||
|
# points at the base generation (not a specialisation leaf).
|
||||||
|
for candidate in \
|
||||||
|
"${HOME}/.local/state/home-manager/gcroots/current-home" \
|
||||||
|
"/nix/var/nix/profiles/per-user/${user}/home-manager" \
|
||||||
|
"${HOME}/.local/state/home-manager/home-manager-generation"
|
||||||
|
do
|
||||||
|
[ -n "$gen" ] && break
|
||||||
|
if [ -e "$candidate" ]; then
|
||||||
|
gen="$(readlink -e "$candidate")" || gen=""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$gen" ]; then
|
||||||
|
echo "error: could not resolve Home Manager base generation" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$variant" in
|
||||||
|
"${baseVariant}")
|
||||||
|
# Base variant is the generation itself, not a specialisation.
|
||||||
|
activate="$gen/activate"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
activate="$gen/specialisation/$variant/activate"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ ! -x "$activate" ]; then
|
||||||
|
echo "error: variant '$variant' not found at $activate" >&2
|
||||||
|
echo "Available: ${availableVariants}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Switching theme to $variant..."
|
||||||
|
exec "$activate"
|
||||||
@@ -121,8 +121,6 @@
|
|||||||
display-manager.ly.enable = true;
|
display-manager.ly.enable = true;
|
||||||
|
|
||||||
gaming.enable = true;
|
gaming.enable = true;
|
||||||
|
|
||||||
dynamic-theme.enable = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
###
|
###
|
||||||
@@ -133,37 +131,14 @@
|
|||||||
useUserPackages = true;
|
useUserPackages = true;
|
||||||
backupFileExtension = "backup";
|
backupFileExtension = "backup";
|
||||||
extraSpecialArgs = { inherit inputs username; };
|
extraSpecialArgs = { inherit inputs username; };
|
||||||
|
# Stylix is handled entirely at the Home Manager level (see
|
||||||
|
# hm-modules/theme). Load the stylix HM module here so the `stylix`
|
||||||
|
# option exists for fujin's home configuration.
|
||||||
|
sharedModules = [ inputs.stylix.homeModules.stylix ];
|
||||||
|
|
||||||
users."${username}" = { imports = [ ./home.nix ] ++ extraHomeModules; };
|
users."${username}" = { imports = [ ./home.nix ] ++ extraHomeModules; };
|
||||||
};
|
};
|
||||||
|
|
||||||
stylix = {
|
|
||||||
enable = true;
|
|
||||||
# base16Scheme managed by dov.dynamic-theme module
|
|
||||||
|
|
||||||
fonts = {
|
|
||||||
serif = {
|
|
||||||
package = pkgs.dejavu_fonts;
|
|
||||||
name = "DejaVu Serif";
|
|
||||||
};
|
|
||||||
|
|
||||||
sansSerif = {
|
|
||||||
package = pkgs.dejavu_fonts;
|
|
||||||
name = "DejaVu Sans";
|
|
||||||
};
|
|
||||||
|
|
||||||
monospace = {
|
|
||||||
package = pkgs.dejavu_fonts;
|
|
||||||
name = "DejaVu Sans Mono";
|
|
||||||
};
|
|
||||||
|
|
||||||
emoji = {
|
|
||||||
package = pkgs.noto-fonts-color-emoji;
|
|
||||||
name = "Noto Color Emoji";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
fonts.packages = with pkgs;
|
fonts.packages = with pkgs;
|
||||||
[
|
[
|
||||||
noto-fonts
|
noto-fonts
|
||||||
|
|||||||
@@ -163,12 +163,36 @@
|
|||||||
#mpc-cli
|
#mpc-cli
|
||||||
] ++ [ inputs.thefuck.packages.${pkgs.system}.default ];
|
] ++ [ inputs.thefuck.packages.${pkgs.system}.default ];
|
||||||
|
|
||||||
|
# Stylix theming is driven by `dov.dynamic-theme` (hm-modules/theme),
|
||||||
|
# which sets `enable`, `base16Scheme` and `polarity` + specialisations.
|
||||||
|
# Here we only keep target overrides and the font set (moved from the
|
||||||
|
# old NixOS-level stylix config).
|
||||||
stylix = {
|
stylix = {
|
||||||
enable = true;
|
|
||||||
autoEnable = true;
|
|
||||||
targets = {
|
targets = {
|
||||||
kde.enable = false;
|
kde.enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fonts = {
|
||||||
|
serif = {
|
||||||
|
package = pkgs.dejavu_fonts;
|
||||||
|
name = "DejaVu Serif";
|
||||||
|
};
|
||||||
|
|
||||||
|
sansSerif = {
|
||||||
|
package = pkgs.dejavu_fonts;
|
||||||
|
name = "DejaVu Sans";
|
||||||
|
};
|
||||||
|
|
||||||
|
monospace = {
|
||||||
|
package = pkgs.dejavu_fonts;
|
||||||
|
name = "DejaVu Sans Mono";
|
||||||
|
};
|
||||||
|
|
||||||
|
emoji = {
|
||||||
|
package = pkgs.noto-fonts-color-emoji;
|
||||||
|
name = "Noto Color Emoji";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# blutooth applet
|
# blutooth applet
|
||||||
|
|||||||
@@ -15,6 +15,5 @@
|
|||||||
./gitlab
|
./gitlab
|
||||||
./jenkins
|
./jenkins
|
||||||
./gaming
|
./gaming
|
||||||
./theme
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
{ config, lib, pkgs, username, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
let
|
|
||||||
# Access HM theme config
|
|
||||||
hmCfg = config.home-manager.users.${username}.dov.dynamic-theme;
|
|
||||||
|
|
||||||
allThemes = hmCfg.themes;
|
|
||||||
|
|
||||||
# Generate all theme-variant combinations
|
|
||||||
themeVariants = concatMapAttrs (name: theme: {
|
|
||||||
"${name}-dark" = { scheme = theme.dark; polarity = "dark"; };
|
|
||||||
"${name}-light" = { scheme = theme.light; polarity = "light"; };
|
|
||||||
}) allThemes;
|
|
||||||
|
|
||||||
# Base is gruvbox-dark, everything else is a specialisation
|
|
||||||
baseVariant = "gruvbox-dark";
|
|
||||||
specialisationVariants = filterAttrs (name: _: name != baseVariant) themeVariants;
|
|
||||||
|
|
||||||
availableVariants = concatStringsSep " " (attrNames themeVariants);
|
|
||||||
|
|
||||||
theme-switch = pkgs.writeShellScriptBin "theme-switch" ''
|
|
||||||
case "$1" in
|
|
||||||
${baseVariant})
|
|
||||||
echo "Switching to ${baseVariant}..."
|
|
||||||
sudo nixos-rebuild switch --flake ~/nixos#${username}
|
|
||||||
;;
|
|
||||||
${concatStringsSep "\n " (map (name: ''
|
|
||||||
${name})
|
|
||||||
echo "Switching to ${name}..."
|
|
||||||
sudo nixos-rebuild switch --flake ~/nixos#${username} --specialisation ${name}
|
|
||||||
;;'') (attrNames specialisationVariants))}
|
|
||||||
*)
|
|
||||||
echo "Usage: theme-switch <variant>"
|
|
||||||
echo "Available: ${availableVariants}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
'';
|
|
||||||
|
|
||||||
in {
|
|
||||||
options.dov.dynamic-theme.enable = mkEnableOption "NixOS dynamic theme specialisations";
|
|
||||||
|
|
||||||
config = mkIf (config.dov.dynamic-theme.enable && hmCfg.enable) {
|
|
||||||
# Add theme-switch script system-wide
|
|
||||||
environment.systemPackages = [ theme-switch ];
|
|
||||||
|
|
||||||
# Base theme: gruvbox-dark
|
|
||||||
stylix = {
|
|
||||||
base16Scheme = mkDefault themeVariants.${baseVariant}.scheme;
|
|
||||||
polarity = mkDefault themeVariants.${baseVariant}.polarity;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Generate NixOS specialisations for all other variants
|
|
||||||
specialisation = mapAttrs (name: variant: {
|
|
||||||
configuration = {
|
|
||||||
stylix = {
|
|
||||||
base16Scheme = mkForce variant.scheme;
|
|
||||||
polarity = mkForce variant.polarity;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}) specialisationVariants;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
let
|
let
|
||||||
colors = config.lib.stylix.colors;
|
|
||||||
cfg = config.dov.window-manager.hypr;
|
cfg = config.dov.window-manager.hypr;
|
||||||
hm-cfg = config.home-manager.users.${username}.dov;
|
hm-cfg = config.home-manager.users.${username}.dov;
|
||||||
in {
|
in {
|
||||||
@@ -249,31 +248,6 @@ in {
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Stylix base16 palette exported as hyprlang variables. No longer sourced
|
|
||||||
# from the main Lua config (Lua has no `source`); kept for reference and
|
|
||||||
# for any hyprlang consumer that wants to source it.
|
|
||||||
home.file.".config/hypr/colors".text = ''
|
|
||||||
$background = ${colors.base00}
|
|
||||||
$foreground = ${colors.base05}
|
|
||||||
|
|
||||||
$color0 = ${colors.base00}
|
|
||||||
$color1 = ${colors.base01}
|
|
||||||
$color2 = ${colors.base02}
|
|
||||||
$color3 = ${colors.base03}
|
|
||||||
$color4 = ${colors.base04}
|
|
||||||
$color5 = ${colors.base05}
|
|
||||||
$color6 = ${colors.base06}
|
|
||||||
$color7 = ${colors.base07}
|
|
||||||
$color8 = ${colors.base08}
|
|
||||||
$color9 = ${colors.base09}
|
|
||||||
$color10 = ${colors.base0A}
|
|
||||||
$color11 = ${colors.base0B}
|
|
||||||
$color12 = ${colors.base0C}
|
|
||||||
$color13 = ${colors.base0D}
|
|
||||||
$color14 = ${colors.base0E}
|
|
||||||
$color15 = ${colors.base0F}
|
|
||||||
'';
|
|
||||||
|
|
||||||
xdg.configFile."hypr/hyprlock.conf".source = ./hyprlock.conf;
|
xdg.configFile."hypr/hyprlock.conf".source = ./hyprlock.conf;
|
||||||
xdg.configFile."hypr/hypridle.conf".source = ./hypridle.conf;
|
xdg.configFile."hypr/hypridle.conf".source = ./hypridle.conf;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user