diff --git a/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix b/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix index e9e0071..74e51fb 100755 --- a/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix +++ b/homes/aarch64-linux/matt@macbook-pro-nixos/default.nix @@ -2,10 +2,11 @@ pkgs, lib, namespace, + config, ... }: let - theme = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + theme = config.mjallen.theme.palette; shellAliases = { update-boot = "sudo nixos-rebuild boot --max-jobs 10 --build-host admin@10.0.1.3"; update-switch = "sudo nixos-rebuild switch --max-jobs 10 --build-host admin@10.0.1.3"; diff --git a/homes/x86_64-linux/matt@matt-nixos/default.nix b/homes/x86_64-linux/matt@matt-nixos/default.nix index 2160828..4c9e286 100755 --- a/homes/x86_64-linux/matt@matt-nixos/default.nix +++ b/homes/x86_64-linux/matt@matt-nixos/default.nix @@ -2,6 +2,7 @@ lib, pkgs, namespace, + config, ... }: let @@ -16,6 +17,7 @@ let resolution = "3840x2160"; refreshRate = "240.00000"; }; + theme = config.mjallen.theme.palette; in { home.username = "matt"; @@ -156,14 +158,14 @@ in extraModulesStyle = '' #custom-lights { - color: #88c0d0; - background-color: #2e3440; - opacity: 0.8; - border-left: 5px solid #88c0d0; + color: ${theme.frost.nord8}; + background-color: ${theme.polarNight.nord0}; + ${theme.defaultOpacity} + border-left: 5px solid ${theme.frost.nord8}; } #custom-lights:hover { - background: #4c566a; + background: ${theme.polarNight.nord3}; } ''; }; diff --git a/modules/home/desktop/theme/default.nix b/modules/home/desktop/theme/default.nix new file mode 100644 index 0000000..cd6594a --- /dev/null +++ b/modules/home/desktop/theme/default.nix @@ -0,0 +1,140 @@ +{ config, lib, ... }: +with lib; +let + cfg = config.mjallen.theme; + + mkPalettePath = name: + lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/${name}.nix"; + + cap = s: let + len = builtins.stringLength s; + in + (lib.toUpper (builtins.substring 0 1 s)) + + (builtins.substring 1 (len - 1) s); +in +{ + options.mjallen.theme = { + name = mkOption { + type = types.enum [ "nord" "dracula" "everforest" ]; + default = "nord"; + description = "Global theme palette name."; + }; + + # This is the palette file other modules should import. + # It exports a normalized schema with colors, tokens, and compat maps. + paletteFile = mkOption { + type = types.path; + default = mkPalettePath "nord"; + description = "Path to a palette nix file exporting a normalized schema (and compat maps)."; + }; + + # Exposed tokens (derived from paletteFile) + tokens = mkOption { + type = types.attrs; + default = { }; + description = "Derived tokens from the selected palette (set automatically)."; + }; + + # Expose the imported palette (actual colors + compat groups) + palette = mkOption { + type = types.attrs; + default = { }; + description = "Imported palette attrset from the selected paletteFile (set automatically)."; + }; + + gtk = { + enable = mkOption { + type = types.bool; + default = true; + description = "Manage GTK theme using global theme settings."; + }; + + # e.g. Colloid-Dark-Compact-* + color = mkOption { + type = types.enum [ "dark" "light" ]; + default = "dark"; + description = "GTK color variant."; + }; + + size = mkOption { + type = types.enum [ "standard" "compact" ]; + default = "compact"; + description = "GTK size variant."; + }; + + accent = mkOption { + type = types.enum [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ]; + default = "all"; + description = "GTK accent (Colloid themeVariants)."; + }; + + tweak = mkOption { + type = types.enum [ "normal" "rimless" "float" "black" ]; + default = "normal"; + description = "GTK tweak (Colloid tweaks)."; + }; + + themeName = mkOption { + type = types.nullOr types.str; + default = null; + description = "Explicit GTK theme name override. If null, computed from color/size/accent."; + }; + }; + + icons = { + # Colloid icon scheme usually supports several named schemes. Default follows palette name. + scheme = mkOption { + type = types.enum [ "default" "nord" "dracula" "gruvbox" "everforest" "catppuccin" ]; + default = cfg.name; + description = "Icon scheme to use (Colloid schemeVariants)."; + }; + + variant = mkOption { + type = types.enum [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ]; + default = "all"; + description = "Icon variant (Colloid colorVariants)."; + }; + + themeName = mkOption { + type = types.nullOr types.str; + default = null; + description = "Explicit icon theme name override. If null, computed from scheme/variant."; + }; + }; + }; + + # Wire derived defaults that depend on other options. + config = { + # Keep paletteFile following the chosen name unless user overrides it explicitly. + mjallen.theme.paletteFile = mkDefault (mkPalettePath cfg.name); + + # Pull tokens directly from the palette file for convenience + mjallen.theme.tokens = mkDefault ( + let pal = import cfg.paletteFile; in pal.tokens or { } + ); + + # Expose the imported palette for convenience + mjallen.theme.palette = mkDefault (import cfg.paletteFile); + + # Default per-program palette path (can still be overridden per program) + mjallen.programs.waybar.theme.file = mkDefault cfg.paletteFile; + mjallen.programs.kitty.theme.file = mkDefault cfg.paletteFile; + mjallen.programs.mako.theme.file = mkDefault cfg.paletteFile; + mjallen.programs.wofi.theme.file = mkDefault cfg.paletteFile; + mjallen.programs.btop.theme.file = mkDefault cfg.paletteFile; + mjallen.programs.nwg-dock.theme.file = mkDefault cfg.paletteFile; + mjallen.programs.nwg-drawer.theme.file = mkDefault cfg.paletteFile; + mjallen.programs.wlogout.theme.file = mkDefault cfg.paletteFile; + + # Computed GTK/Icon theme names if not overridden + _module.args.mjallenThemeComputed = { + gtkTheme = + if cfg.gtk.themeName != null then cfg.gtk.themeName + else "Colloid-${cap cfg.gtk.color}-${cap cfg.gtk.size}"; + + iconTheme = + if cfg.icons.themeName != null then cfg.icons.themeName + else "Colloid-${cap cfg.icons.scheme}-${cap cfg.gtk.color}"; + }; + }; +} diff --git a/modules/home/desktop/theme/palettes/dracula.nix b/modules/home/desktop/theme/palettes/dracula.nix new file mode 100644 index 0000000..357f69a --- /dev/null +++ b/modules/home/desktop/theme/palettes/dracula.nix @@ -0,0 +1,90 @@ +rec { + # Normalized semantic colors (theme-agnostic) - Dracula + colors = { + bg = "#282a36"; + bgAlt = "#343746"; + surface = "#343746"; + surfaceAlt = "#44475a"; + border = "#44475a"; + + text = "#f8f8f2"; + textMuted = "#e2e2dc"; + + primary = "#6272a4"; # dark blue + info = "#8be9fd"; # cyan + accent = "#bd93f9"; # purple + success = "#50fa7b"; # green + warning = "#f1fa8c"; # yellow + danger = "#ff5555"; # red + }; + + # Shared styling tokens for CSS consumers + tokens = { + opacity = "opacity: 0.90;"; + borderRadius = "border-radius: 0.8rem;"; + + centerOptions = '' + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + ''; + + borderRight = '' + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + border-radius: 0rem 0.8rem 0.8rem 0rem; + margin-right: 0.5rem; + ''; + + borderLeft = '' + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + border-radius: 0.8rem 0rem 0rem 0.8rem; + margin-left: 0.5rem; + ''; + }; + + # Legacy token aliases for back-compat + defaultOpacity = tokens.opacity; + defaultBorderRadius = tokens.borderRadius; + defaultCenterOptions = tokens.centerOptions; + borderRight = tokens.borderRight; + borderLeft = tokens.borderLeft; + + # Back-compat: Nord-shaped groups for existing modules (approximate mappings) + polarNight = { + nord0 = "#282a36"; + nord1 = "#343746"; + nord2 = "#3b3e4a"; + nord3 = "#44475a"; + }; + + snowStorm = { + nord4 = "#e2e2dc"; + nord5 = "#f1f1ea"; + nord6 = "#f8f8f2"; + }; + + frost = { + nord7 = "#50fa7b"; # using green as one of the frost group + nord8 = "#8be9fd"; # cyan + nord9 = "#6272a4"; # blue + nord10 = "#bd93f9"; # purple (as highlight) + }; + + aurora = { + nord11 = "#ff5555"; # red + nord12 = "#ffb86c"; # orange + nord13 = "#f1fa8c"; # yellow + nord14 = "#50fa7b"; # green + nord15 = "#bd93f9"; # magenta/purple + }; +} diff --git a/modules/home/desktop/theme/palettes/everforest.nix b/modules/home/desktop/theme/palettes/everforest.nix new file mode 100644 index 0000000..73e878b --- /dev/null +++ b/modules/home/desktop/theme/palettes/everforest.nix @@ -0,0 +1,90 @@ +rec { + # Normalized semantic colors (Everforest - Dark) + colors = { + bg = "#2b3339"; + bgAlt = "#323c41"; + surface = "#323c41"; + surfaceAlt = "#3a444a"; + border = "#414b51"; + + text = "#d3c6aa"; + textMuted = "#9da9a0"; + + primary = "#7fbbb3"; # blue/aqua + info = "#83c092"; # teal + accent = "#d699b6"; # magenta + success = "#a7c080"; # green + warning = "#dbbc7f"; # yellow + danger = "#e67e80"; # red + }; + + # Shared styling tokens for CSS consumers + tokens = { + opacity = "opacity: 0.85;"; + borderRadius = "border-radius: 1rem;"; + + centerOptions = '' + padding-top: 0.2rem; + padding-bottom: 0.2rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + ''; + + borderRight = '' + padding-top: 0.2rem; + padding-bottom: 0.2rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + border-radius: 0rem 1rem 1rem 0rem; + margin-right: 0.5rem; + ''; + + borderLeft = '' + padding-top: 0.2rem; + padding-bottom: 0.2rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + border-radius: 1rem 0rem 0rem 1rem; + margin-left: 0.5rem; + ''; + }; + + # Legacy token aliases for back-compat + defaultOpacity = tokens.opacity; + defaultBorderRadius = tokens.borderRadius; + defaultCenterOptions = tokens.centerOptions; + borderRight = tokens.borderRight; + borderLeft = tokens.borderLeft; + + # Back-compat: Nord-shaped groups for existing modules (approximate mappings) + polarNight = { + nord0 = "#2b3339"; + nord1 = "#323c41"; + nord2 = "#3a444a"; + nord3 = "#414b51"; + }; + + snowStorm = { + nord4 = "#c6d0b5"; + nord5 = "#e0dcc7"; + nord6 = "#d3c6aa"; + }; + + frost = { + nord7 = "#a7c080"; # green + nord8 = "#83c092"; # teal + nord9 = "#7fbbb3"; # aqua/blue + nord10 = "#7fbbb3"; # reuse + }; + + aurora = { + nord11 = "#e67e80"; # red + nord12 = "#e69875"; # orange + nord13 = "#dbbc7f"; # yellow + nord14 = "#a7c080"; # green + nord15 = "#d699b6"; # magenta + }; +} diff --git a/modules/home/desktop/theme/palettes/nord.nix b/modules/home/desktop/theme/palettes/nord.nix new file mode 100644 index 0000000..cb3590f --- /dev/null +++ b/modules/home/desktop/theme/palettes/nord.nix @@ -0,0 +1,90 @@ +rec { + # Normalized semantic colors (theme-agnostic) + colors = { + bg = "#2e3440"; + bgAlt = "#3b4252"; + surface = "#3b4252"; + surfaceAlt = "#434c5e"; + border = "#4c566a"; + + text = "#eceff4"; + textMuted = "#e5e9f0"; + + primary = "#5e81ac"; # blue + info = "#88c0d0"; # cyan/teal + accent = "#b48ead"; # purple + success = "#a3be8c"; # green + warning = "#ebcb8b"; # yellow + danger = "#bf616a"; # red + }; + + # Shared styling tokens for CSS consumers + tokens = { + opacity = "opacity: 0.85;"; + borderRadius = "border-radius: 1rem;"; + + centerOptions = '' + padding-top: 0.2rem; + padding-bottom: 0.2rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + ''; + + borderRight = '' + padding-top: 0.2rem; + padding-bottom: 0.2rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + border-radius: 0rem 1rem 1rem 0rem; + margin-right: 0.5rem; + ''; + + borderLeft = '' + padding-top: 0.2rem; + padding-bottom: 0.2rem; + padding-left: 0.5rem; + padding-right: 0.5rem; + margin: 3px 0; + border-radius: 1rem 0rem 0rem 1rem; + margin-left: 0.5rem; + ''; + }; + + # Legacy token aliases for back-compat + defaultOpacity = tokens.opacity; + defaultBorderRadius = tokens.borderRadius; + defaultCenterOptions = tokens.centerOptions; + borderRight = tokens.borderRight; + borderLeft = tokens.borderLeft; + + # Back-compat: Nord-shaped groups for existing modules + polarNight = { + nord0 = "#2e3440"; + nord1 = "#3b4252"; + nord2 = "#434c5e"; + nord3 = "#4c566a"; + }; + + snowStorm = { + nord4 = "#d8dee9"; + nord5 = "#e5e9f0"; + nord6 = "#eceff4"; + }; + + frost = { + nord7 = "#8fbcbb"; + nord8 = "#88c0d0"; + nord9 = "#81a1c1"; + nord10 = "#5e81ac"; + }; + + aurora = { + nord11 = "#bf616a"; + nord12 = "#d08770"; + nord13 = "#ebcb8b"; + nord14 = "#a3be8c"; + nord15 = "#b48ead"; + }; +} diff --git a/modules/home/programs/btop/default.nix b/modules/home/programs/btop/default.nix index f2104c1..2c998b6 100755 --- a/modules/home/programs/btop/default.nix +++ b/modules/home/programs/btop/default.nix @@ -2,7 +2,7 @@ with lib; let cfg = config.mjallen.programs.btop; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; in { imports = [ ./options.nix ]; @@ -10,7 +10,7 @@ in programs.btop = { enable = true; settings = { - color_theme = "nord"; # todo + color_theme = "global"; theme_background = true; truecolor = true; force_tty = false; @@ -76,49 +76,49 @@ in log_level = "WARNING"; }; themes = { - nord = '' - theme[main_bg]="${nord.polarNight.nord0}" - theme[main_fg]="${nord.snowStorm.nord6}" - theme[title]="${nord.snowStorm.nord6}" - theme[hi_fg]="${nord.frost.nord7}" - theme[selected_bg]="${nord.polarNight.nord1}" - theme[selected_fg]="${nord.frost.nord7}" - theme[inactive_fg]="${nord.polarNight.nord2}" - theme[graph_text]="${nord.snowStorm.nord6}" - theme[meter_bg]="${nord.polarNight.nord1}" - theme[proc_misc]="${nord.snowStorm.nord6}" - theme[cpu_box]="${nord.aurora.nord15}" - theme[mem_box]="${nord.aurora.nord14}" - theme[net_box]="${nord.aurora.nord12}" - theme[proc_box]="${nord.aurora.nord11}" - theme[div_line]="${nord.polarNight.nord1}" - theme[temp_start]="${nord.aurora.nord14}" - theme[temp_mid]="${nord.aurora.nord13}" - theme[temp_end]="${nord.aurora.nord11}" - theme[cpu_start]="${nord.aurora.nord15}" - theme[cpu_mid]="${nord.aurora.nord12}" - theme[cpu_end]="${nord.aurora.nord11}" - theme[free_start]="${nord.aurora.nord14}" - theme[free_mid]="${nord.aurora.nord13}" - theme[free_end]="${nord.aurora.nord12}" - theme[cached_start]="${nord.aurora.nord14}" - theme[cached_mid]="${nord.aurora.nord13}" - theme[cached_end]="${nord.aurora.nord12}" - theme[available_start]="${nord.snowStorm.nord6}" - theme[available_mid]="${nord.aurora.nord11}" - theme[available_end]="${nord.aurora.nord11}" - theme[used_start]="${nord.aurora.nord14}" - theme[used_mid]="${nord.aurora.nord13}" - theme[used_end]="${nord.aurora.nord11}" - theme[download_start]="${nord.frost.nord8}" - theme[download_mid]="${nord.frost.nord8}" - theme[download_end]="${nord.aurora.nord12}" - theme[upload_start]="${nord.frost.nord7}" - theme[upload_mid]="${nord.frost.nord7}" - theme[upload_end]="${nord.aurora.nord12}" - theme[process_start]="${nord.aurora.nord15}" - theme[process_mid]="${nord.aurora.nord12}" - theme[process_end]="${nord.aurora.nord11}" + global = '' + theme[main_bg]="${palette.colors.bg}" + theme[main_fg]="${palette.colors.text}" + theme[title]="${palette.colors.text}" + theme[hi_fg]="${palette.colors.info}" + theme[selected_bg]="${palette.colors.bgAlt}" + theme[selected_fg]="${palette.colors.info}" + theme[inactive_fg]="${palette.colors.surfaceAlt}" + theme[graph_text]="${palette.colors.text}" + theme[meter_bg]="${palette.colors.bgAlt}" + theme[proc_misc]="${palette.colors.text}" + theme[cpu_box]="${palette.colors.accent}" + theme[mem_box]="${palette.colors.success}" + theme[net_box]="${palette.colors.warning}" + theme[proc_box]="${palette.colors.danger}" + theme[div_line]="${palette.colors.bgAlt}" + theme[temp_start]="${palette.colors.success}" + theme[temp_mid]="${palette.colors.warning}" + theme[temp_end]="${palette.colors.danger}" + theme[cpu_start]="${palette.colors.accent}" + theme[cpu_mid]="${palette.colors.warning}" + theme[cpu_end]="${palette.colors.danger}" + theme[free_start]="${palette.colors.success}" + theme[free_mid]="${palette.colors.warning}" + theme[free_end]="${palette.colors.warning}" + theme[cached_start]="${palette.colors.success}" + theme[cached_mid]="${palette.colors.warning}" + theme[cached_end]="${palette.colors.warning}" + theme[available_start]="${palette.colors.text}" + theme[available_mid]="${palette.colors.danger}" + theme[available_end]="${palette.colors.danger}" + theme[used_start]="${palette.colors.success}" + theme[used_mid]="${palette.colors.warning}" + theme[used_end]="${palette.colors.danger}" + theme[download_start]="${palette.colors.info}" + theme[download_mid]="${palette.colors.info}" + theme[download_end]="${palette.colors.warning}" + theme[upload_start]="${palette.colors.info}" + theme[upload_mid]="${palette.colors.info}" + theme[upload_end]="${palette.colors.warning}" + theme[process_start]="${palette.colors.accent}" + theme[process_mid]="${palette.colors.warning}" + theme[process_end]="${palette.colors.danger}" ''; }; }; diff --git a/modules/home/programs/btop/options.nix b/modules/home/programs/btop/options.nix index c85c2e9..3917198 100644 --- a/modules/home/programs/btop/options.nix +++ b/modules/home/programs/btop/options.nix @@ -3,5 +3,19 @@ with lib; { options.mjallen.programs.btop = { enable = mkEnableOption "enable btop"; + + theme = mkOption { + type = types.submodule { + options = { + file = mkOption { + type = types.path; + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset."; + }; + }; + }; + default = { }; + description = "btop theme palette configuration."; + }; }; } diff --git a/modules/home/programs/code/default.nix b/modules/home/programs/code/default.nix index 69794cc..b488bc5 100644 --- a/modules/home/programs/code/default.nix +++ b/modules/home/programs/code/default.nix @@ -8,7 +8,7 @@ }: let isArm = ("aarch64-linux" == system) || ("aarch64-darwin" == system); - + x86_only = with pkgs; [ vscode-extensions.redhat.vscode-xml ]; diff --git a/modules/home/programs/hyprland/default.nix b/modules/home/programs/hyprland/default.nix index a9bd83d..cff4d0e 100644 --- a/modules/home/programs/hyprland/default.nix +++ b/modules/home/programs/hyprland/default.nix @@ -7,7 +7,7 @@ with lib; let cfg = config.mjallen.programs.hyprland; - drawer = "nwg-drawer -fm nautilus -term kitty -mb 10 -mt 10 -ml 10 -mr 10 -pbuseicontheme -i ${cfg.iconThemeName}"; + drawer = "nwg-drawer -fm nautilus -term kitty -mb 10 -mt 10 -ml 10 -mr 10 -pbuseicontheme -i ${config.gtk.iconTheme.name}"; in { imports = [ @@ -80,9 +80,9 @@ in CLUTTER_BACKEND = "wayland"; EDITOR = "${cfg.defaultApps.editor.pname}"; VISUAL = "${cfg.defaultApps.visual.pname}"; - ICON_THEME = cfg.iconThemeName; + ICON_THEME = config.gtk.iconTheme.name; GTK_CSD = "0"; - GTK_THEME = cfg.gtkThemeName; + GTK_THEME = config.gtk.theme.name; GTK_USE_PORTAL = "1"; HYPRCURSOR_THEME = config.home.pointerCursor.name; HYPRCURSOR_SIZE = config.home.pointerCursor.size; @@ -354,30 +354,31 @@ in ] ++ cfg.keybinds.bindl; - monitor = cfg.monitor; - monitorv2 = map ( - m: - if m.disabled then - "${m.name}, disable" - else if m.mirrorOf != null then - "${m.name}, mirror, ${m.mirrorOf}" - else - let - mode = if m.mode == null then "preferred" else m.mode; - position = if m.position == null then "auto" else m.position; - scale = if m.scale == null then "1" else (toString m.scale); - transform = if m.transform == null then "auto" else m.transform; - base = [ - m.name - mode - position - scale - transform - ]; - line = builtins.concatStringsSep ", " (base ++ m.extra); - in - line - ) cfg.monitorv2; + monitor = + cfg.monitor + ++ map ( + m: + if m.disabled then + "${m.name}, disable" + else if m.mirrorOf != null then + "${m.name}, mirror, ${m.mirrorOf}" + else + let + mode = if m.mode == null then "preferred" else m.mode; + position = if m.position == null then "0x0" else m.position; + scale = if m.scale == null then "1" else (toString m.scale); + parts = [ + m.name + mode + position + scale + ]; + # Append transform only when set, as "transform, " + transformTokens = if m.transform == null then [ ] else [ "transform" m.transform ]; + tokens = parts ++ transformTokens ++ m.extra; + in + builtins.concatStringsSep ", " tokens + ) cfg.monitorv2; render = { cm_fs_passthrough = 1; diff --git a/modules/home/programs/hyprland/theme.nix b/modules/home/programs/hyprland/theme.nix index b984383..6d6b3b7 100644 --- a/modules/home/programs/hyprland/theme.nix +++ b/modules/home/programs/hyprland/theme.nix @@ -2,18 +2,20 @@ config, lib, pkgs, + mjallenThemeComputed, ... }: with lib; let cfg = config.mjallen.programs.hyprland; - themeSize = "compact"; # [ "standard" "compact" ] - themeAccent = "all"; # [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ] - themeVariant = "nord"; # [ "nord" "dracula" "gruvbox" "everforest" "catppuccin" "all" "black" "rimless" "normal" "float" ] - themeColor = "dark"; # [ "standard" "light" "dark" ] - iconThemeVariant = "all"; # [ "default" "purple" "pink" "red" "orange" "yellow" "green" "teal" "grey" "all" ] - iconScheme = "nord"; # [ "default" "nord" "dracula" "gruvbox" "everforest" "catppuccin" "all" ] + # Pull from global theme options + themeSize = config.mjallen.theme.gtk.size; # "standard" | "compact" + themeAccent = config.mjallen.theme.gtk.accent; # "default" | ... | "all" + themeTweak = config.mjallen.theme.gtk.tweak; # "normal" | "rimless" | "float" | "black" + themeColor = config.mjallen.theme.gtk.color; # "light" | "dark" + iconThemeVariant = config.mjallen.theme.icons.variant; # "default" | ... | "all" + iconScheme = config.mjallen.theme.icons.scheme; # "default" | "nord" | "dracula" | ... # Cursor cursorTheme = "macOS"; @@ -21,16 +23,16 @@ let cursorSize = 24; # GTK - gtkTheme = "Colloid-Dark-Compact-Nord"; + gtkTheme = mjallenThemeComputed.gtkTheme; gtkThemePkg = pkgs.colloid-gtk-theme.override { sizeVariants = [ themeSize ]; colorVariants = [ themeColor ]; themeVariants = [ themeAccent ]; - tweaks = [ themeVariant ]; + tweaks = [ themeTweak ]; }; # Icons - iconTheme = "Colloid-Nord-Dark"; + iconTheme = mjallenThemeComputed.iconTheme; iconThemePkg = pkgs.colloid-icon-theme.override { schemeVariants = [ iconScheme ]; colorVariants = [ iconThemeVariant ]; diff --git a/modules/home/programs/kitty/default.nix b/modules/home/programs/kitty/default.nix index c0d13d3..f0e4678 100755 --- a/modules/home/programs/kitty/default.nix +++ b/modules/home/programs/kitty/default.nix @@ -2,7 +2,7 @@ with lib; let cfg = config.mjallen.programs.kitty; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; in { imports = [ ./options.nix ]; @@ -29,77 +29,77 @@ in background_opacity = "0.85"; # The basic colors - foreground = nord.snowStorm.nord6; - background = nord.polarNight.nord0; - selection_foreground = nord.polarNight.nord0; - selection_background = nord.aurora.nord15; + foreground = palette.colors.text; + background = palette.colors.bg; + selection_foreground = palette.colors.bg; + selection_background = palette.colors.accent; # Cursor colors - cursor = nord.aurora.nord15; - cursor_text_color = nord.polarNight.nord0; + cursor = palette.colors.accent; + cursor_text_color = palette.colors.bg; # URL underline color when hovering with mouse - url_color = nord.aurora.nord15; + url_color = palette.colors.accent; # Kitty window border colors - active_border_color = nord.frost.nord10; - inactive_border_color = nord.polarNight.nord1; - bell_border_color = nord.aurora.nord13; + active_border_color = palette.colors.primary; + inactive_border_color = palette.colors.bgAlt; + bell_border_color = palette.colors.warning; # OS Window titlebar colors - wayland_titlebar_color = nord.polarNight.nord0; - macos_titlebar_color = nord.polarNight.nord0; + wayland_titlebar_color = palette.colors.bg; + macos_titlebar_color = palette.colors.bg; # Tab bar colors - active_tab_foreground = nord.polarNight.nord3; - active_tab_background = nord.aurora.nord15; - inactive_tab_foreground = nord.snowStorm.nord6; - inactive_tab_background = nord.polarNight.nord1; - tab_bar_background = nord.polarNight.nord3; + active_tab_foreground = palette.colors.border; + active_tab_background = palette.colors.accent; + inactive_tab_foreground = palette.colors.text; + inactive_tab_background = palette.colors.bgAlt; + tab_bar_background = palette.colors.border; # Colors for marks (marked text in the terminal) - mark1_foreground = nord.polarNight.nord0; - mark1_background = nord.frost.nord10; - mark2_foreground = nord.polarNight.nord0; - mark2_background = nord.aurora.nord15; - mark3_foreground = nord.polarNight.nord0; - mark3_background = nord.frost.nord8; + mark1_foreground = palette.colors.bg; + mark1_background = palette.colors.primary; + mark2_foreground = palette.colors.bg; + mark2_background = palette.colors.accent; + mark3_foreground = palette.colors.bg; + mark3_background = palette.colors.info; # The 16 terminal colors # black - color0 = nord.polarNight.nord0; + color0 = palette.colors.bg; # Autosuggestion - color8 = nord.frost.nord10; + color8 = palette.colors.primary; # red - color1 = nord.aurora.nord11; - color9 = nord.aurora.nord11; + color1 = palette.colors.danger; + color9 = palette.colors.danger; # green - color2 = nord.aurora.nord14; - color10 = nord.aurora.nord14; + color2 = palette.colors.success; + color10 = palette.colors.success; # yellow - color3 = nord.aurora.nord13; - color11 = nord.aurora.nord13; + color3 = palette.colors.warning; + color11 = palette.colors.warning; # blue - color4 = nord.frost.nord10; - color12 = nord.frost.nord10; + color4 = palette.colors.primary; + color12 = palette.colors.primary; # magenta - color5 = nord.aurora.nord15; - color13 = nord.aurora.nord15; + color5 = palette.colors.accent; + color13 = palette.colors.accent; # cyan - color6 = nord.frost.nord8; - color14 = nord.frost.nord8; + color6 = palette.colors.info; + color14 = palette.colors.info; # white - color7 = nord.snowStorm.nord5; - color15 = nord.snowStorm.nord4; + color7 = palette.colors.textMuted; + color15 = palette.colors.text; }; }; }; diff --git a/modules/home/programs/kitty/options.nix b/modules/home/programs/kitty/options.nix index 2afd857..ee76467 100644 --- a/modules/home/programs/kitty/options.nix +++ b/modules/home/programs/kitty/options.nix @@ -22,8 +22,18 @@ in }; theme = mkOption { - type = types.attrs; - default = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + type = types.submodule { + options = { + file = mkOption { + type = types.path; + # Fallback default; global theme module sets this via mkDefault + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset."; + }; + }; + }; + default = { }; + description = "Kitty theme palette configuration."; }; }; } diff --git a/modules/home/programs/mako/default.nix b/modules/home/programs/mako/default.nix index df14f96..5d06360 100755 --- a/modules/home/programs/mako/default.nix +++ b/modules/home/programs/mako/default.nix @@ -2,7 +2,7 @@ with lib; let cfg = config.mjallen.programs.mako; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; in { imports = [ ./options.nix ]; @@ -22,10 +22,10 @@ in max-icon-size = 64; default-timeout = 5000; - background-color = nord.polarNight.nord0; - text-color = nord.snowStorm.nord6; - border-color = nord.frost.nord10; - progress-color = "over ${nord.frost.nord8}"; + background-color = palette.colors.bg; + text-color = palette.colors.text; + border-color = palette.colors.primary; + progress-color = "over ${palette.colors.info}"; }; }; }; diff --git a/modules/home/programs/mako/options.nix b/modules/home/programs/mako/options.nix index a920ab2..623a7fe 100644 --- a/modules/home/programs/mako/options.nix +++ b/modules/home/programs/mako/options.nix @@ -8,5 +8,19 @@ with lib; type = types.str; default = "DejaVu Sans"; }; + + theme = mkOption { + type = types.submodule { + options = { + file = mkOption { + type = types.path; + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset."; + }; + }; + }; + default = { }; + description = "Mako theme palette configuration."; + }; }; } diff --git a/modules/home/programs/nwg-dock/default.nix b/modules/home/programs/nwg-dock/default.nix index 7de746d..15fbf30 100644 --- a/modules/home/programs/nwg-dock/default.nix +++ b/modules/home/programs/nwg-dock/default.nix @@ -7,7 +7,7 @@ with lib; let cfg = config.mjallen.programs.nwg-dock; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; in { imports = [ ./options.nix ]; @@ -18,11 +18,11 @@ in home.file = { ".config/nwg-dock-hyprland/drawer.css".text = '' window { - background: ${nord.polarNight.nord0}; + background: ${palette.colors.bg}; border-radius: 10px; border-style: none; border-width: 1px; - border-color: ${nord.aurora.nord15}b0 + border-color: ${palette.colors.accent}b0 } #box { @@ -33,14 +33,14 @@ in active { /* This is to underline the button representing the currently active window */ border-bottom: solid 1px; - border-color: ${nord.aurora.nord14}1a + border-color: ${palette.colors.success}1a } button, image { background: none; border-style: none; box-shadow: none; - color: ${nord.frost.nord10} + color: ${palette.colors.primary} } button { @@ -52,7 +52,7 @@ in } button:hover { - background-color: ${nord.polarNight.nord0}1a; + background-color: ${palette.colors.bg}1a; border-radius: 2px; } diff --git a/modules/home/programs/nwg-dock/options.nix b/modules/home/programs/nwg-dock/options.nix index a37808f..47c63cb 100644 --- a/modules/home/programs/nwg-dock/options.nix +++ b/modules/home/programs/nwg-dock/options.nix @@ -3,5 +3,19 @@ with lib; { options.mjallen.programs.nwg-dock = { enable = mkEnableOption "enable nwg-dock"; + + theme = mkOption { + type = types.submodule { + options = { + file = mkOption { + type = types.path; + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset."; + }; + }; + }; + default = { }; + description = "nwg-dock theme palette configuration."; + }; }; } diff --git a/modules/home/programs/nwg-drawer/default.nix b/modules/home/programs/nwg-drawer/default.nix index 221a2fd..63efdfa 100644 --- a/modules/home/programs/nwg-drawer/default.nix +++ b/modules/home/programs/nwg-drawer/default.nix @@ -7,7 +7,7 @@ with lib; let cfg = config.mjallen.programs.nwg-drawer; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; in { imports = [ ./options.nix ]; @@ -18,13 +18,13 @@ in home.file = { ".config/nwg-drawer/drawer.css".text = '' window { - background-color: ${nord.polarNight.nord0}bf; - color: ${nord.snowStorm.nord5}00 + background-color: ${palette.colors.bg}bf; + color: ${palette.colors.textMuted}00 } /* search entry */ entry { - background-color: ${nord.polarNight.nord1}0f + background-color: ${palette.colors.bgAlt}0f } button, image { @@ -33,7 +33,7 @@ in } button:hover { - background-color: ${nord.frost.nord10}1a + background-color: ${palette.colors.primary}1a } /* in case you wanted to give category buttons a different look */ @@ -43,12 +43,12 @@ in #pinned-box { padding-bottom: 5px; - border-bottom: 1px dotted ${nord.polarNight.nord3} + border-bottom: 1px dotted ${palette.colors.border} } #files-box { padding: 5px; - border: 1px dotted ${nord.polarNight.nord3}; + border: 1px dotted ${palette.colors.border}; border-radius: 15px } ''; diff --git a/modules/home/programs/nwg-drawer/options.nix b/modules/home/programs/nwg-drawer/options.nix index a837354..aff37cd 100644 --- a/modules/home/programs/nwg-drawer/options.nix +++ b/modules/home/programs/nwg-drawer/options.nix @@ -3,5 +3,19 @@ with lib; { options.mjallen.programs.nwg-drawer = { enable = mkEnableOption "enable nwg-drawer"; + + theme = mkOption { + type = types.submodule { + options = { + file = mkOption { + type = types.path; + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset."; + }; + }; + }; + default = { }; + description = "nwg-drawer theme palette configuration."; + }; }; } diff --git a/modules/home/programs/waybar/default.nix b/modules/home/programs/waybar/default.nix index 514f52c..2d0f3ef 100755 --- a/modules/home/programs/waybar/default.nix +++ b/modules/home/programs/waybar/default.nix @@ -2,18 +2,29 @@ with lib; let cfg = config.mjallen.programs.waybar; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; - defaultOpacity = "opacity: 0.85;"; - defaultBorderRadius = "border-radius: 1rem;"; - defaultCenterOptions = '' + # Back-compat shims for deprecated options + rightModules = + if builtins.hasAttr "modules-right" cfg && (cfg."modules-right" != [ ]) + then cfg."modules-right" + else cfg.layout.right; + + netIf = + if (cfg ? networkInterface) && (cfg.networkInterface != "wlan0") + then cfg.networkInterface + else cfg.network.interface; + + defaultOpacity = palette.tokens.opacity or "opacity: 0.85;"; + defaultBorderRadius = palette.tokens.borderRadius or "border-radius: 1rem;"; + defaultCenterOptions = palette.tokens.centerOptions or '' padding-top: 0.2rem; padding-bottom: 0.2rem; padding-left: 0.5rem; padding-right: 0.5rem; margin: 3px 0; ''; - borderRight = '' + borderRight = palette.tokens.borderRight or '' padding-top: 0.2rem; padding-bottom: 0.2rem; padding-left: 0.5rem; @@ -22,7 +33,7 @@ let border-radius: 0rem 1rem 1rem 0rem; margin-right: 0.5rem; ''; - borderLeft = '' + borderLeft = palette.tokens.borderLeft or '' padding-top: 0.2rem; padding-bottom: 0.2rem; padding-left: 0.5rem; @@ -31,6 +42,259 @@ let border-radius: 1rem 0rem 0rem 1rem; margin-left: 0.5rem; ''; + + baseStyle = + if cfg.style.file != null then + builtins.readFile cfg.style.file + else + '' + .blink_me { + animation: blinker 1s linear infinite; + } + + @keyframes blinker { + 50% { + color: ${palette.colors.danger}; + } + } + + * { + font-family: + Jetbrains Mono Nerd Font, + monospace; + font-size: 14px; + min-height: 0; + } + + #waybar { + background: transparent; + color: ${palette.colors.text}; + margin: 5px 5px; + } + + #workspaces { + background-color: ${palette.colors.bg}; + ${defaultBorderRadius} + ${defaultOpacity} + ${defaultCenterOptions} + margin-left: 0.6rem; + } + + #workspaces button { + color: ${palette.colors.primary}; + ${defaultBorderRadius} + padding: 0.4rem; + } + + #workspaces button.active { + color: ${palette.colors.info}; + ${defaultBorderRadius} + } + + #workspaces button:hover { + color: ${palette.colors.info}; + ${defaultBorderRadius} + } + + #workspaces button.focused { + color: ${palette.colors.text}; + background: ${palette.colors.warning}; + ${defaultBorderRadius} + } + + #workspaces button.urgent { + color: ${palette.colors.bg}; + background: ${palette.colors.text}; + ${defaultBorderRadius} + } + + #tooltip { + background: ${palette.colors.bg}; + border-color: ${palette.colors.bg}; + ${defaultBorderRadius} + border-width: 1rem; + border-style: solid; + } + + #window { + color: ${palette.colors.accent}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultBorderRadius} + ${defaultCenterOptions} + margin-left: 4rem; + margin-right: ${toString cfg.windowOffset}rem; + } + + /* make window module transparent when no windows present */ + #window.empty { + background-color: transparent; + } + + #custom-weather { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #battery { + color: ${palette.colors.accent}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + min-width: 3rem; + } + + #clock { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + /* ------------- */ + + #idle_inhibitor { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + padding-right: 1rem; + } + + #idle_inhibitor:hover { + background: ${palette.colors.surfaceAlt}; + } + + #network { + color: ${palette.colors.accent}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + padding-right: 15px; + } + + #network:hover { + background: ${palette.colors.surfaceAlt}; + } + + #bluetooth { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #bluetooth:hover { + background: ${palette.colors.surfaceAlt}; + } + + #wireplumber.source { + color: ${palette.colors.info}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #wireplumber.source.muted { + animation-name: blinker; + animation-duration: 2s; + animation-timing-function: linear; + animation-iteration-count: infinite; + padding-right: 1rem; + } + + #wireplumber.source:hover { + background: ${palette.colors.surfaceAlt}; + } + + #wireplumber.sink { + color: ${palette.colors.info}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #wireplumber.sink.muted { + animation-name: blinker; + animation-duration: 5s; + animation-timing-function: linear; + animation-iteration-count: infinite; + } + + #wireplumber.sink:hover { + background: ${palette.colors.surfaceAlt}; + } + + #keyboard-state.numlock { + color: ${palette.colors.info}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #keyboard-state.capslock { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #temperature.gpu { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0; + } + + #temperature.gpu:hover { + background: ${palette.colors.surfaceAlt}; + } + + #temperature { + color: ${palette.colors.primary}; + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + border-radius: 0 + } + + /* ------------- */ + + #tray { + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${defaultCenterOptions} + ${defaultBorderRadius} + margin-right: 0.6rem; + } + + /* ------------- */ + + #custom-left-end { + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${borderLeft} + } + + #custom-right-end { + background-color: ${palette.colors.bg}; + ${defaultOpacity} + ${borderRight} + } + ''; in { imports = [ @@ -47,539 +311,290 @@ in programs.waybar = { enable = true; systemd.enable = true; - settings = { - mainBar = { - layer = cfg.layer; - position = "top"; - mod = "dock"; - exclusive = true; - passthrough = false; - gtk-layer-shell = true; - height = 0; - # Module Layout - modules-left = [ "hyprland/workspaces" ]; + settings = + ( + { + mainBar = + ( + (mkMerge [ + { + layer = cfg.layer; + position = "top"; + mod = "dock"; + exclusive = true; + passthrough = false; + gtk-layer-shell = true; + height = 0; - modules-center = [ "hyprland/window" ]; + # Module Layout + modules-left = cfg.layout.left; + modules-center = cfg.layout.center; + modules-right = rightModules; - modules-right = [ - "tray" - "custom/left-end" - "temperature" - "temperature#gpu" - "keyboard-state#capslock" - "keyboard-state#numlock" - "wireplumber#sink" - "bluetooth" - "network" - "idle_inhibitor" - "custom/right-end" - "custom/left-end" - "clock" - "battery" - "custom/weather" - "custom/right-end" - ]; + # Base module definitions always present unless individually gated + "hyprland/workspaces" = { + disable-scroll = true; + all-outputs = true; + on-click = "activate"; + persistent_workspaces = { + "*" = 1; + }; + }; - # modules-right = [ - # "tray" - # "custom/left-end" ] ++ - # cfg.modules-right ++ - # [ "custom/right-end" ]; + "hyprland/window" = { + separate-outputs = true; + format = { }; + }; - # Module Definitions - # Left - "hyprland/workspaces" = { - disable-scroll = true; - all-outputs = true; - on-click = "activate"; - persistent_workspaces = { - "*" = 1; - }; - }; + temperature = { + hwmon-path = cfg.temperature.cpu.hwmonPath; + critical-threshold = 110; + format-critical = "{temperatureC}°C "; + format = "{temperatureC}°C {icon}"; + format-icons = [ + "" + "" + "" + "" + "" + ]; + tooltip-format = "CPU: {temperatureC}°C"; + }; - # Center - "hyprland/window" = { - separate-outputs = true; - format = { }; - }; + network = { + interface = netIf; + on-click = "nm-connection-editor"; + format = "{icon}"; + tooltip-format = "{ifname} via {gwaddr} 󰊗"; + tooltip-format-wifi = '' + {essid} ({signalStrength}%) {icon} +  {bandwidthDownBits}  {bandwidthUpBits} + ''; + tooltip-format-ethernet = "{ifname} "; + tooltip-format-disconnected = "Disconnected"; + max-length = 50; + format-icons = { + wifi = [ + "󰤯" + "󰤟" + "󰤢" + "󰤥" + "󰤨" + ]; + ethernet = "󰈀"; + linked = "󰤫"; + disconnected = "󰤫"; + }; + }; - # Left - tray = { - icon-size = 16; - spacing = 10; - }; + "custom/left-end" = { + format = " "; + tooltip = false; + }; - temperature = { - hwmon-path = "/sys/class/hwmon/hwmon4/temp1_input"; - critical-threshold = 110; - format-critical = "{temperatureC}°C "; - format = "{temperatureC}°C {icon}"; - format-icons = [ - "" # fa-temperature-empty - "" # fa-temperature-quarter - "" # fa-temperature-half - "" # fa-temperature-three-quarters - "" # fa-temperature-full - ]; - tooltip-format = "CPU: {temperatureC}°C"; - }; + "custom/right-end" = { + format = " "; + tooltip = false; + }; + } - "temperature#gpu" = { - hwmon-path = "/sys/class/hwmon/hwmon0/temp1_input"; - critical-threshold = 110; - format-critical = "{temperatureC}°C "; - format = "{temperatureC}°C {icon}"; - format-icons = [ - "" # fa-temperature-empty - "" # fa-temperature-quarter - "" # fa-temperature-half - "" # fa-temperature-three-quarters - "" # fa-temperature-full - ]; - on-click = "lact"; - tooltip-format = "GPU: {temperatureC}°C"; - }; + (mkIf cfg.features.tray.enable { + tray = { + icon-size = 16; + spacing = 10; + }; + }) - "keyboard-state#capslock" = { - capslock = true; - format = "{icon}"; - tooltip-format = "Caps Lock {state}"; - format-icons = { - locked = "󰬶"; - unlocked = "󰬵"; - }; - }; + (mkIf cfg.features.keyboardIndicators.enable { + "keyboard-state#capslock" = { + capslock = true; + format = "{icon}"; + tooltip-format = "Caps Lock {state}"; + format-icons = { + locked = "󰬶"; + unlocked = "󰬵"; + }; + }; - "keyboard-state#numlock" = { - numlock = true; - format = "{icon}"; - tooltip-format = "Num Lock {state}"; - format-icons = { - locked = "󰎠"; - unlocked = "󱧓"; - }; - }; + "keyboard-state#numlock" = { + numlock = true; + format = "{icon}"; + tooltip-format = "Num Lock {state}"; + format-icons = { + locked = "󰎠"; + unlocked = "󱧓"; + }; + }; + }) - "wireplumber#sink" = { - format = "{icon} {volume}%"; - tooltip = false; - format-muted = "{icon} Muted"; - on-click = "wpctl set-mute @DEFAULT_SINK@ toggle"; - on-click-right = "pavucontrol -t 1"; - on-scroll-up = "wpctl set-volume @DEFAULT_SINK@ 5%+"; - on-scroll-down = "wpctl set-volume @DEFAULT_SINK@ 5%-"; - scroll-step = 5; - format-icons = { - headphone = "󰋋"; - headphone-muted = "󰟎"; - hands-free = "󰋋"; - headset = "󰋋"; - phone = ""; - portable = "󰋋"; - car = ""; - default = [ - "" - "" - "" - "" - ]; - }; - }; + (mkIf cfg.features.audio.sink.enable { + "wireplumber#sink" = { + format = "{icon} {volume}%"; + tooltip = false; + format-muted = "{icon} Muted"; + on-click = "wpctl set-mute @DEFAULT_SINK@ toggle"; + on-click-right = "pavucontrol -t 1"; + on-scroll-up = "wpctl set-volume @DEFAULT_SINK@ 5%+"; + on-scroll-down = "wpctl set-volume @DEFAULT_SINK@ 5%-"; + scroll-step = 5; + format-icons = { + headphone = "󰋋"; + headphone-muted = "󰟎"; + hands-free = "󰋋"; + headset = "󰋋"; + phone = ""; + portable = "󰋋"; + car = ""; + default = [ + "" + "" + "" + "" + ]; + }; + }; + }) - "wireplumber#source" = { - node-type = "Audio/Source"; - format = ""; - format-muted = ""; - tooltip = false; - # tooltip-format = "{source_desc} | {source_volume}%"; - on-click = "wpctl set-mute @DEFAULT_SOURCE@ toggle"; - on-click-right = "pavucontrol -t 2"; - on-scroll-up = "wpctl set-volume @DEFAULT_SOURCE@ 5%+"; - on-scroll-down = "wpctl set-volume @DEFAULT_SOURCE@ 5%-"; - scroll-step = 5; - }; + (mkIf cfg.features.audio.source.enable { + "wireplumber#source" = { + node-type = "Audio/Source"; + format = ""; + format-muted = ""; + tooltip = false; + on-click = "wpctl set-mute @DEFAULT_SOURCE@ toggle"; + on-click-right = "pavucontrol -t 2"; + on-scroll-up = "wpctl set-volume @DEFAULT_SOURCE@ 5%+"; + on-scroll-down = "wpctl set-volume @DEFAULT_SOURCE@ 5%-"; + scroll-step = 5; + }; + }) - "bluetooth" = { - on-click = "overskride"; - tooltip = true; - format = "{icon}"; - tooltip-format = "{status}"; - tooltip-format-disabled = "{status}"; - tooltip-format-off = "{status}"; - tooltip-format-on = "{status}"; - tooltip-format-connected = "{status}"; - tooltip-format-enumerate-connected = { }; - format-icons = { - disabled = "󰂲"; - off = "󰂲"; - on = "󰂯"; - connected = "󰂱"; - }; - }; + (mkIf cfg.features.bluetooth.enable { + bluetooth = { + on-click = "overskride"; + tooltip = true; + format = "{icon}"; + tooltip-format = "{status}"; + tooltip-format-disabled = "{status}"; + tooltip-format-off = "{status}"; + tooltip-format-on = "{status}"; + tooltip-format-connected = "{status}"; + tooltip-format-enumerate-connected = { }; + format-icons = { + disabled = "󰂲"; + off = "󰂲"; + on = "󰂯"; + connected = "󰂱"; + }; + }; + }) - network = { - interface = cfg.networkInterface; - on-click = "nm-connection-editor"; - format = "{icon}"; - tooltip-format = "{ifname} via {gwaddr} 󰊗"; - tooltip-format-wifi = '' - {essid} ({signalStrength}%) {icon} -  {bandwidthDownBits}  {bandwidthUpBits} - ''; - tooltip-format-ethernet = "{ifname} "; - tooltip-format-disconnected = "Disconnected"; - max-length = 50; - format-icons = { - wifi = [ - "󰤯" - "󰤟" - "󰤢" - "󰤥" - "󰤨" - ]; - ethernet = "󰈀"; - linked = "󰤫"; - disconnected = "󰤫"; - }; - }; + (mkIf cfg.features.idleInhibitor.enable { + idle_inhibitor = { + format = "{icon}"; + format-icons = { + activated = "󰐂"; + deactivated = "󱩜"; + }; + }; + }) - idle_inhibitor = { - format = "{icon}"; - format-icons = { - activated = "󰐂"; - deactivated = "󱩜"; - }; - }; + (mkIf cfg.features.clock.enable { + clock = { + format = "{:%I:%M %p}"; + tooltip-format = "{calendar}"; + calendar = { + mode = "month"; + format = { + months = "{}"; + days = "{}"; + weekdays = "{}"; + today = "{}"; + }; + }; + }; + }) - clock = { - format = "{:%I:%M %p}"; - tooltip-format = "{calendar}"; - calendar = { - mode = "month"; - format = { - months = "{}"; - days = "{}"; - weekdays = "{}"; - today = "{}"; - }; - }; - }; + (mkIf cfg.features.battery.enable { + battery = { + interval = 60; + states = { + warning = 30; + critical = 15; + }; + format = "{capacity}% {icon}"; + format-icons = { + default = [ + "󰂃" + "󰁺" + "󰁻" + "󰁼" + "󰁽" + "󰁾" + "󰁿" + "󰂀" + "󰂁" + "󰂂" + "󰁹" + ]; + charging = [ + "󰢟" + "󰢜" + "󰂆" + "󰂇" + "󰂈" + "󰢝" + "󰂉" + "󰢞" + "󰂊" + "󰂋" + "󰂅" + ]; + }; + max-length = 25; + }; + }) - battery = { - # bat = "macsmc-battery"; - interval = 60; - # statuses: 'Charging', 'Discharging' - states = { - warning = 30; - critical = 15; - }; - format = "{capacity}% {icon}"; - format-icons = { - default = [ - "󰂃" # critical - "󰁺" # 10% - "󰁻" # 20% - "󰁼" # 30% - "󰁽" # 40% - "󰁾" # 50% - "󰁿" # 60% - "󰂀" # 70% - "󰂁" # 80% - "󰂂" # 90% - "󰁹" # 100% - ]; - charging = [ - "󰢟" # critical - "󰢜" # 10% - "󰂆" # 20% - "󰂇" # 30% - "󰂈" # 40% - "󰢝" # 50% - "󰂉" # 60% - "󰢞" # 70% - "󰂊" # 80% - "󰂋" # 90% - "󰂅" # 100% - ]; - }; - max-length = 25; - }; + (mkIf cfg.temperature.gpu.enable { + "temperature#gpu" = { + hwmon-path = cfg.temperature.gpu.hwmonPath; + critical-threshold = 110; + format-critical = "{temperatureC}°C "; + format = "{temperatureC}°C {icon}"; + format-icons = [ + "" + "" + "" + "" + "" + ]; + on-click = "lact"; + tooltip-format = "GPU: {temperatureC}°C"; + }; + }) - "custom/weather" = { - tooltip = true; - format = { }; - interval = 30; - exec = "waybar-weather"; - return-type = "json"; - markup = "pango"; - }; - - "custom/left-end" = { - format = " "; - tooltip = false; - }; - - "custom/right-end" = { - format = " "; - tooltip = false; - }; - } - // cfg.extraModules; - }; - - # * { font-size: 13px; } - # window.eDP-1 * { font-size: 10px; } - - style = '' - .blink_me { - animation: blinker 1s linear infinite; - } - - @keyframes blinker { - 50% { - color: ${nord.aurora.nord11}; + (mkIf cfg.features.weather.enable { + "custom/weather" = { + tooltip = true; + format = { }; + interval = 30; + exec = "waybar-weather"; + return-type = "json"; + markup = "pango"; + }; + }) + ]) + // cfg.extra.settings + ); } - } + ) + // cfg.extraModules; # keep legacy top-level extra modules for compatibility - * { - font-family: - Jetbrains Mono Nerd Font, - monospace; - font-size: 14px; - min-height: 0; - } - - #waybar { - background: transparent; - color: ${nord.snowStorm.nord6}; - margin: 5px 5px; - } - - #workspaces { - background-color: ${nord.polarNight.nord0}; - ${defaultBorderRadius} - ${defaultOpacity} - ${defaultCenterOptions} - margin-left: 0.6rem; - } - - #workspaces button { - color: ${nord.frost.nord10}; - ${defaultBorderRadius} - padding: 0.4rem; - } - - #workspaces button.active { - color: ${nord.frost.nord8}; - ${defaultBorderRadius} - } - - #workspaces button:hover { - color: ${nord.frost.nord7}; - ${defaultBorderRadius} - } - - #workspaces button.focused { - color: ${nord.snowStorm.nord6}; - background: ${nord.aurora.nord13}; - ${defaultBorderRadius} - } - - #workspaces button.urgent { - color: ${nord.polarNight.nord0}; - background: ${nord.snowStorm.nord6}; - ${defaultBorderRadius} - } - - #tooltip { - background: ${nord.polarNight.nord0}; - border-color: ${nord.polarNight.nord0}; - ${defaultBorderRadius} - border-width: 1rem; - border-style: solid; - } - - #window { - color: ${nord.aurora.nord15}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultBorderRadius} - ${defaultCenterOptions} - margin-left: 4rem; - margin-right: ${toString cfg.windowOffset}rem; - } - - /* make window module transparent when no windows present */ - #window.empty { - background-color: transparent; - } - - #custom-weather { - color: ${nord.frost.nord10}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - #battery { - color: ${nord.aurora.nord15}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - min-width: 3rem; - } - - #clock { - color: ${nord.frost.nord9}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - /* ------------- */ - - #idle_inhibitor { - color: ${nord.frost.nord10}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - padding-right: 1rem; - } - - #idle_inhibitor:hover { - background: ${nord.polarNight.nord3}; - } - - #network { - color: ${nord.aurora.nord15}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - padding-right: 15px; - } - - #network:hover { - background: ${nord.polarNight.nord3}; - } - - #bluetooth { - color: ${nord.frost.nord9}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - #bluetooth:hover { - background: ${nord.polarNight.nord3}; - } - - #wireplumber.source { - color: ${nord.frost.nord8}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - #wireplumber.source.muted { - animation-name: blinker; - animation-duration: 2s; - animation-timing-function: linear; - animation-iteration-count: infinite; - padding-right: 1rem; - } - - #wireplumber.source:hover { - background: ${nord.polarNight.nord3}; - } - - #wireplumber.sink { - color: ${nord.frost.nord7}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - #wireplumber.sink.muted { - animation-name: blinker; - animation-duration: 5s; - animation-timing-function: linear; - animation-iteration-count: infinite; - } - - #wireplumber.sink:hover { - background: ${nord.polarNight.nord3}; - } - - #keyboard-state.numlock { - color: ${nord.frost.nord8}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - #keyboard-state.capslock { - color: ${nord.frost.nord9}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - #temperature.gpu { - color: ${nord.frost.nord10}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0; - } - - #temperature.gpu:hover { - background: ${nord.polarNight.nord3}; - } - - #temperature { - color: ${nord.frost.nord9}; - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - border-radius: 0 - } - - /* ------------- */ - - #tray { - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${defaultCenterOptions} - ${defaultBorderRadius} - margin-right: 0.6rem; - } - - /* ------------- */ - - #custom-left-end { - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${borderLeft} - } - - #custom-right-end { - background-color: ${nord.polarNight.nord0}; - ${defaultOpacity} - ${borderRight} - } - '' - + cfg.extraModulesStyle or ''''; + style = + baseStyle + + (cfg.extra.style or "") + + (cfg.extraModulesStyle or ""); }; }; } diff --git a/modules/home/programs/waybar/options.nix b/modules/home/programs/waybar/options.nix index 7d7b03e..b57da89 100644 --- a/modules/home/programs/waybar/options.nix +++ b/modules/home/programs/waybar/options.nix @@ -1,69 +1,264 @@ { lib, ... }: with lib; +let + inherit (types) str int bool listOf attrs path nullOr submodule; +in { options.mjallen.programs.waybar = { - enable = mkEnableOption "enable waybar"; + enable = mkEnableOption "Waybar status bar"; + # Legacy/compat options (kept for backwards compatibility) layer = mkOption { - type = types.str; + type = str; default = "top"; + description = "Waybar layer (compat). Prefer layout + feature flags."; }; modules-right = mkOption { - type = with types; listOf str; + type = listOf str; default = [ ]; + description = "DEPRECATED: use layout.right."; }; networkInterface = mkOption { - type = types.str; + type = str; default = "wlan0"; + description = "DEPRECATED: use network.interface."; }; extraModules = mkOption { - type = types.attrs; + type = attrs; default = { }; + description = "Extra settings bars at top-level (compat with older module)."; }; extraModulesStyle = mkOption { - type = types.str; + type = str; default = ""; + description = "Extra CSS appended (compat). Prefer extra.style."; }; windowOffset = mkOption { - type = types.int; + type = int; default = 4; + description = "Right margin offset for the hyprland/window module (in rem)."; }; - # Waybar modules config - # modules = mkOption { - # type = types.submodule { - # options = { - # # Modules - # window = mkOption { - # type = types.submodule { - # options = { - # # Waybar Module CSS - # margin-right = mkOption { - # type = types.str; - # default = "4"; - # }; - # }; - # }; - # }; - # temperature = mkOption { - # type = types.submodule { - # options = { - # # Waybar Module CSS - # margin-right = mkOption { - # type = types.str; - # default = "4"; - # }; - # }; - # }; - # }; - # }; - # }; - # default = { }; - # }; + # Theme + theme = mkOption { + type = submodule { + options = { + file = mkOption { + type = path; + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset (e.g., Nord)."; + }; + }; + }; + default = { }; + description = "Theme configuration."; + }; + + # Layout + layout = mkOption { + type = submodule { + options = { + left = mkOption { + type = listOf str; + default = [ "hyprland/workspaces" ]; + description = "Modules shown on the left."; + }; + center = mkOption { + type = listOf str; + default = [ "hyprland/window" ]; + description = "Modules shown in the center."; + }; + right = mkOption { + type = listOf str; + default = [ + "tray" + "custom/left-end" + "temperature" + "temperature#gpu" + "keyboard-state#capslock" + "keyboard-state#numlock" + "wireplumber#sink" + "bluetooth" + "network" + "idle_inhibitor" + "custom/right-end" + "custom/left-end" + "clock" + "battery" + "custom/weather" + "custom/right-end" + ]; + description = "Modules shown on the right."; + }; + }; + }; + default = { }; + description = "Waybar module layout."; + }; + + # Network + network = mkOption { + type = submodule { + options = { + interface = mkOption { + type = str; + default = "wlan0"; + description = "Primary network interface name."; + }; + }; + }; + default = { }; + description = "Network configuration."; + }; + + # Temperatures + temperature = mkOption { + type = submodule { + options = { + cpu = mkOption { + type = submodule { + options = { + hwmonPath = mkOption { + type = str; + default = "/sys/class/hwmon/hwmon4/temp1_input"; + description = "CPU temperature hwmon path."; + }; + }; + }; + default = { }; + }; + + gpu = mkOption { + type = submodule { + options = { + enable = mkOption { + type = bool; + default = true; + description = "Enable GPU temperature module."; + }; + hwmonPath = mkOption { + type = str; + default = "/sys/class/hwmon/hwmon0/temp1_input"; + description = "GPU temperature hwmon path."; + }; + }; + }; + default = { }; + }; + }; + }; + default = { }; + description = "Temperature module configuration."; + }; + + # Features + features = mkOption { + type = submodule { + options = { + tray = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + + bluetooth = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + + idleInhibitor = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + + keyboardIndicators = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + + audio = mkOption { + type = submodule { + options = { + sink = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + source = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = false; }; }; }; + default = { }; + }; + }; + }; + default = { }; + }; + + weather = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + + hass = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = false; }; }; }; + default = { }; + }; + + clock = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + + battery = mkOption { + type = submodule { options = { enable = mkOption { type = bool; default = true; }; }; }; + default = { }; + }; + }; + }; + default = { }; + description = "Toggle optional Waybar features."; + }; + + # Styling + style = mkOption { + type = submodule { + options = { + file = mkOption { + type = nullOr path; + default = null; + description = "Optional external CSS file to use instead of the inline style."; + }; + fragmentsDir = mkOption { + type = nullOr path; + default = null; + description = "Optional directory of CSS fragments to append."; + }; + }; + }; + default = { }; + description = "Styling configuration."; + }; + + # Extra overrides + extra = mkOption { + type = submodule { + options = { + settings = mkOption { + type = attrs; + default = { }; + description = "Extra settings merged into settings.mainBar."; + }; + style = mkOption { + type = str; + default = ""; + description = "Extra CSS appended to the computed style."; + }; + }; + }; + default = { }; + description = "Extra settings/style hooks."; + }; }; } diff --git a/modules/home/programs/wlogout/default.nix b/modules/home/programs/wlogout/default.nix index 7fcd609..f66e874 100644 --- a/modules/home/programs/wlogout/default.nix +++ b/modules/home/programs/wlogout/default.nix @@ -2,7 +2,7 @@ with lib; let cfg = config.mjallen.programs.wlogout; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; in { imports = [ ./options.nix ]; @@ -53,13 +53,13 @@ in } window { - background-color: ${nord.polarNight.nord0}f0 + background-color: ${palette.colors.bg}f0 } button { margin: 8px; - color: ${nord.frost.nord7}; - background-color: ${nord.polarNight.nord1}; + color: ${palette.colors.info}; + background-color: ${palette.colors.bgAlt}; border-style: solid; border-width: 2px; background-repeat: no-repeat; @@ -70,8 +70,8 @@ in button:active, button:focus, button:hover { - color: ${nord.frost.nord8}; - background-color: ${nord.polarNight.nord2}; + color: ${palette.colors.info}; + background-color: ${palette.colors.surfaceAlt}; outline-style: none; } diff --git a/modules/home/programs/wlogout/options.nix b/modules/home/programs/wlogout/options.nix index a019f74..d980170 100644 --- a/modules/home/programs/wlogout/options.nix +++ b/modules/home/programs/wlogout/options.nix @@ -8,5 +8,19 @@ with lib; type = types.str; default = "Deja Vu Sans"; }; + + theme = mkOption { + type = types.submodule { + options = { + file = mkOption { + type = types.path; + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset."; + }; + }; + }; + default = { }; + description = "wlogout theme palette configuration."; + }; }; } diff --git a/modules/home/programs/wofi/default.nix b/modules/home/programs/wofi/default.nix index 954b4ef..3cf93e8 100755 --- a/modules/home/programs/wofi/default.nix +++ b/modules/home/programs/wofi/default.nix @@ -2,7 +2,7 @@ with lib; let cfg = config.mjallen.programs.wofi; - nord = import (lib.snowfall.fs.get-file "modules/home/desktop/theme/nord.nix"); + palette = import cfg.theme.file; in { imports = [ ./options.nix ]; @@ -20,9 +20,9 @@ in window { margin: 0px; padding: 10px; - border: 0.16em solid ${nord.aurora.nord15}; + border: 0.16em solid ${palette.colors.accent}; border-radius: 0.1em; - background-color: ${nord.polarNight.nord0}; + background-color: ${palette.colors.bg}; } /* Inner Box */ @@ -30,7 +30,7 @@ in margin: 5px; padding: 10px; border: none; - background-color: ${nord.polarNight.nord0}; + background-color: ${palette.colors.bg}; } /* Outer Box */ @@ -38,7 +38,7 @@ in margin: 5px; padding: 10px; border: none; - background-color: ${nord.polarNight.nord0}; + background-color: ${palette.colors.bg}; } /* Scroll */ @@ -46,7 +46,7 @@ in margin: 0px; padding: 10px; border: none; - background-color: ${nord.polarNight.nord0}; + background-color: ${palette.colors.bg}; } /* Input */ @@ -55,46 +55,46 @@ in padding: 10px; border: none; border-radius: 0.1em; - color: ${nord.snowStorm.nord6}; - background-color: ${nord.polarNight.nord0}; + color: ${palette.colors.text}; + background-color: ${palette.colors.bg}; } #input image { border: none; - color: ${nord.aurora.nord11}; + color: ${palette.colors.danger}; } #input * { - outline: 4px solid ${nord.aurora.nord11}!important; + outline: 4px solid ${palette.colors.danger}!important; } /* Text */ #text { margin: 5px; border: none; - color: ${nord.snowStorm.nord6}; + color: ${palette.colors.text}; } #entry { - background-color: ${nord.polarNight.nord0}; + background-color: ${palette.colors.bg}; } #entry arrow { border: none; - color: ${nord.aurora.nord15}; + color: ${palette.colors.accent}; } /* Selected Entry */ #entry:selected { - border: 0.11em solid ${nord.aurora.nord15}; + border: 0.11em solid ${palette.colors.accent}; } #entry:selected #text { - color: ${nord.frost.nord7}; + color: ${palette.colors.info}; } #entry:drop(active) { - background-color: ${nord.aurora.nord15}!important; + background-color: ${palette.colors.accent}!important; } ''; }; diff --git a/modules/home/programs/wofi/options.nix b/modules/home/programs/wofi/options.nix index 8389599..f47e584 100644 --- a/modules/home/programs/wofi/options.nix +++ b/modules/home/programs/wofi/options.nix @@ -8,5 +8,19 @@ with lib; type = types.str; default = "Deja Vu Sans"; }; + + theme = mkOption { + type = types.submodule { + options = { + file = mkOption { + type = types.path; + default = lib.snowfall.fs.get-file "modules/home/desktop/theme/palettes/nord.nix"; + description = "Nix file exporting a palette attrset."; + }; + }; + }; + default = { }; + description = "Wofi theme palette configuration."; + }; }; } diff --git a/packages/steamdeck-bios-manager/default.nix b/packages/steamdeck-bios-manager/default.nix new file mode 100644 index 0000000..cf4215e --- /dev/null +++ b/packages/steamdeck-bios-manager/default.nix @@ -0,0 +1,42 @@ +{ lib +, stdenv +, fetchFromGitHub +, pciutils +, bash +}: + +stdenv.mkDerivation { + pname = "steamdeck-bios-manager"; + version = "871dfd9900d2e130fd0276d1dfc00feab7bf5cac"; + + src = fetchFromGitHub { + owner = "ryanrudolfoba"; + repo = "SteamDeck-BIOS-Manager"; + rev = "871dfd9900d2e130fd0276d1dfc00feab7bf5cac"; + sha256 = lib.fakeHash; + }; + + # shell scripts — no compilation + dontBuild = true; + + installPhase = '' + mkdir -p $out/bin + cp steamdeck-bios-manager.sh $out/bin/steamdeck-bios-manager + chmod +x $out/bin/steamdeck-bios-manager + ''; + + # runtime deps + propagatedBuildInputs = [ + pciutils + bash + ]; + + meta = with lib; { + description = "Manage BIOS for the Steam Deck (unlock, flash, backup, block updates)"; + homepage = "https://github.com/ryanrudolfoba/SteamDeck-BIOS-Manager"; + license = licenses.agpl3Only; + platforms = platforms.linux; + maintainers = []; + sourceProvenance = with sourceTypes; [ ]; + }; +}