From a17237b6b4e05280e422f60a5390555ea030bb10 Mon Sep 17 00:00:00 2001 From: 0xda157 Date: Thu, 4 Jun 2026 11:48:46 -0700 Subject: [PATCH] grub: migrate to mkTarget --- modules/grub/nixos.nix | 267 +++++++++++++++++++++++++---------------- 1 file changed, 164 insertions(+), 103 deletions(-) diff --git a/modules/grub/nixos.nix b/modules/grub/nixos.nix index 17b9a566d..93195cd76 100644 --- a/modules/grub/nixos.nix +++ b/modules/grub/nixos.nix @@ -1,45 +1,40 @@ { + mkTarget, pkgs, config, lib, ... }: let - cfg = config.stylix.targets.grub; - inherit (config.stylix) imageScalingMode fonts; - inherit (config.lib.stylix) mkEnableTarget mkEnableWallpaper pixel; - # Grub requires fonts to be converted to "PFF2 format" - # This function takes a font { name, package } and produces a .pf2 file - mkGrubFont = - font: - pkgs.runCommand "${font.package.name}.pf2" - { - FONTCONFIG_FILE = pkgs.makeFontsConf { fontDirectories = [ font.package ]; }; - } - '' - # Use fontconfig to select the correct .ttf or .otf file based on name - font=$( - ${lib.getExe' pkgs.fontconfig "fc-match"} \ - ${lib.escapeShellArg font.name} \ - --format=%{file} - ) - - # Convert to .pf2 - ${lib.getExe' pkgs.grub2 "grub-mkfont"} $font --output $out --size ${toString fonts.sizes.applications} - ''; - - image-scale = - if imageScalingMode == "fill" then - "crop" - else if imageScalingMode == "fit" then - "fitheight" - else if imageScalingMode == "center" then - "padding" - # Grub doesn't seem to support tile - else - "crop"; + inherit (config.lib.stylix) mkEnableWallpaper pixel; in -{ +mkTarget { + options = { + useWallpaper = mkEnableWallpaper "GRUB" false; + theme = { + main = lib.mkOption { + type = lib.types.str; + default = ""; + internal = true; + }; + progress_bar = lib.mkOption { + type = lib.types.str; + default = ""; + internal = true; + }; + boot_menu = lib.mkOption { + type = lib.types.str; + default = ""; + internal = true; + }; + extraBuildScript = lib.mkOption { + type = lib.types.str; + default = ""; + internal = true; + }; + }; + }; + imports = [ (lib.mkRenamedOptionModuleWith { from = [ @@ -57,77 +52,127 @@ in ]; }) ]; - options.stylix.targets.grub = { - enable = mkEnableTarget "GRUB" true; - useWallpaper = mkEnableWallpaper "GRUB" false; - }; - - config.boot.loader.grub = - with config.lib.stylix.colors.withHashtag; - lib.mkIf (config.stylix.enable && cfg.enable) { - backgroundColor = base00; - # Need to override the NixOS splash, this will match the background - splashImage = pixel "base00"; - - # This font will be used for the GRUB terminal - font = toString (mkGrubFont fonts.monospace); - - # TODO: Include OS icons - theme = - pkgs.runCommand "stylix-grub" - { - themeTxt = '' - desktop-image: "background.png" - desktop-image-scale-method: "${image-scale}" - desktop-color: "${base00}" - title-text: "" - - terminal-left: "10%" - terminal-top: "20%" - terminal-width: "80%" - terminal-height: "60%" - - + progress_bar { - left = 25% - top = 80%+20 # 20 pixels below boot menu - width = 50% - height = 30 - - id = "__timeout__" - show_text = true - font = "${fonts.sansSerif.name}" - text = "@TIMEOUT_NOTIFICATION_MIDDLE@" - - border_color = "${base00}" - bg_color = "${base00}" - fg_color = "${base0B}" - text_color = "${base05}" - } + config = [ + ( + { cfg }: + lib.mkIf + ( + cfg.theme.main != "" + || cfg.theme.progress_bar != "" + || cfg.theme.boot_menu != "" + ) + { - + boot_menu { - left = 25% - top = 20% - width = 50% - height = 60% - menu_pixmap_style = "background_*.png" + theme = + pkgs.runCommand "stylix-grub" + { + passAsFile = [ "themeTxt" ]; + themeTxt = '' + title-text: "" - item_height = 40 - item_icon_space = 8 - item_spacing = 0 - item_padding = 0 - item_font = "${fonts.sansSerif.name}" - item_color = "${base05}" + terminal-left: "10%" + terminal-top: "20%" + terminal-width: "80%" + terminal-height: "60%" - selected_item_color = "${base01}" - selected_item_pixmap_style = "selection_*.png" + ${cfg.theme.main} + '' + + lib.optionalString (cfg.theme.progress_bar != "") '' + + progress_bar { + left = 25% + top = 80%+20 # 20 pixels below boot menu + width = 50% + height = 30 + + id = "__timeout__" + show_text = true + text = "@TIMEOUT_NOTIFICATION_MIDDLE@" + ${cfg.theme.progress_bar} + } + '' + + lib.optionalString (cfg.theme.boot_menu != "") '' + + boot_menu { + left = 25% + top = 20% + width = 50% + height = 60% + menu_pixmap_style = "background_*.png" + + item_height = 40 + item_icon_space = 8 + item_spacing = 0 + item_padding = 0 + + selected_item_pixmap_style = "selection_*.png" + ${cfg.theme.boot_menu} + } + ''; } + ( + '' + mkdir $out + cp $themeTxtPath $out/theme.txt + '' + + cfg.theme.extraBuildScript + ); + } + ) + ( + { fonts }: + let + # Grub requires fonts to be converted to "PFF2 format" + # This function takes a font { name, package } and produces a .pf2 file + mkGrubFont = + font: + pkgs.runCommand "${font.package.name}.pf2" + { + FONTCONFIG_FILE = pkgs.makeFontsConf { fontDirectories = [ font.package ]; }; + } + '' + # Use fontconfig to select the correct .ttf or .otf file based on name + font=$( + ${lib.getExe' pkgs.fontconfig "fc-match"} \ + ${lib.escapeShellArg font.name} \ + --format=%{file} + ) + + # Convert to .pf2 + ${lib.getExe' pkgs.grub2 "grub-mkfont"} $font --output $out --size ${toString fonts.sizes.applications} ''; - passAsFile = [ "themeTxt" ]; - } - '' - mkdir $out - cp $themeTxtPath $out/theme.txt + in + { + boot.loader.grub.font = toString (mkGrubFont fonts.monospace); + stylix.targets.grub.theme.extraBuildScript = + "cp ${mkGrubFont fonts.sansSerif} $out/sans_serif.pf2"; + } + ) + ( + { + cfg, + image, + imageScalingMode, + }: + let + image-scale = + if imageScalingMode == "fill" then + "crop" + else if imageScalingMode == "fit" then + "fitheight" + else if imageScalingMode == "center" then + "padding" + # Grub doesn't seem to support tile + else + "crop"; + in + { + stylix.targets.grub.theme = { + main = '' + desktop-image: "background.png" + desktop-image-scale-method: "${image-scale}" + ''; + extraBuildScript = '' + ${ if @@ -136,7 +181,7 @@ in then '' ${lib.getExe' pkgs.imagemagick "convert"} \ - ${lib.escapeShellArg config.stylix.image} \ + ${lib.escapeShellArg image} \ "png32:$out/background.png" '' else @@ -145,8 +190,24 @@ in cp ${pixel "base01"} $out/background_c.png cp ${pixel "base0B"} $out/selection_c.png - - cp ${mkGrubFont fonts.sansSerif} $out/sans_serif.pf2 ''; - }; + }; + } + ) + ( + { colors }: + { + stylix.targets.grub.theme = { + main = '' + desktop-color: "${colors.withHashtag.base00}" + ''; + }; + + boot.loader.grub = { + backgroundColor = colors.withHashtag.base00; + splashImage = pixel "base00"; + }; + } + ) + ]; }