diff --git a/modules/kde/hm.nix b/modules/kde/hm.nix index f1db5d8d..6226a76e 100644 --- a/modules/kde/hm.nix +++ b/modules/kde/hm.nix @@ -4,19 +4,17 @@ lib, ... }: - -with config.stylix.fonts; -with config.lib.stylix.colors; - let cfg = config.stylix.targets.kde; + inherit (config.lib.stylix) + colors + mkEnableTarget + ; + formatValue = value: - if builtins.isBool value then - if value then "true" else "false" - else - builtins.toString value; + if lib.isBool value then if value then "true" else "false" else toString value; formatSection = path: data: @@ -24,7 +22,7 @@ let header = lib.concatStrings (map (p: "[${p}]") path); formatChild = name: formatLines (path ++ [ name ]); children = lib.mapAttrsToList formatChild data; - partitioned = lib.partition builtins.isString children; + partitioned = lib.partition lib.isString children; directChildren = partitioned.right; indirectChildren = partitioned.wrong; in @@ -34,9 +32,9 @@ let formatLines = path: data: - if builtins.isAttrs data then + if lib.isAttrs data then if data ? _immutable then - if builtins.isAttrs data.value then + if lib.isAttrs data.value then formatSection (path ++ [ "$i" ]) data.value else "${lib.last path}[$i]=${formatValue data.value}" @@ -58,7 +56,7 @@ let # in kebab-case will load when selected manually, but don't work with a # look and feel package. colorschemeSlug = lib.concatStrings ( - builtins.filter builtins.isString (builtins.split "[^a-zA-Z]" scheme) + lib.filter lib.isString (builtins.split "[^a-zA-Z]" colors.scheme) ); colorEffect = { @@ -70,52 +68,76 @@ let IntensityAmount = 0; }; - colors = { - BackgroundNormal = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - BackgroundAlternate = "${base01-rgb-r},${base01-rgb-g},${base01-rgb-b}"; - DecorationFocus = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}"; - DecorationHover = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}"; - ForegroundNormal = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}"; - ForegroundActive = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}"; - ForegroundInactive = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}"; - ForegroundLink = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}"; - ForegroundVisited = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}"; - ForegroundNegative = "${base08-rgb-r},${base08-rgb-g},${base08-rgb-b}"; - ForegroundNeutral = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}"; - ForegroundPositive = "${base0B-rgb-r},${base0B-rgb-g},${base0B-rgb-b}"; + mkColorTriple = + name: + lib.concatStringsSep "," ( + map (color: colors."${name}-rgb-${color}") [ + "r" + "g" + "b" + ] + ); + + mkColorMapping = + num: + let + hex = "base0${lib.toHexString num}"; + in + { + name = hex; + value = mkColorTriple hex; + }; + + colors' = lib.listToAttrs (map mkColorMapping (lib.range 0 15)); + + kdecolors = with colors'; { + BackgroundNormal = base00; + BackgroundAlternate = base01; + DecorationFocus = base0D; + DecorationHover = base0D; + ForegroundNormal = base05; + ForegroundActive = base05; + ForegroundInactive = base05; + ForegroundLink = base05; + ForegroundVisited = base05; + ForegroundNegative = base08; + ForegroundNeutral = base0D; + ForegroundPositive = base0B; }; colorscheme = { General = { ColorScheme = colorschemeSlug; - Name = scheme; + Name = colors.scheme; }; "ColorEffects:Disabled" = colorEffect; "ColorEffects:Inactive" = colorEffect; - "Colors:Window" = colors; - "Colors:View" = colors; - "Colors:Button" = colors; - "Colors:Tooltip" = colors; - "Colors:Complementary" = colors; - "Colors:Selection" = colors // { - BackgroundNormal = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}"; - BackgroundAlternate = "${base0D-rgb-r},${base0D-rgb-g},${base0D-rgb-b}"; - ForegroundNormal = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - ForegroundActive = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - ForegroundInactive = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - ForegroundLink = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - ForegroundVisited = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - }; - - WM = { - activeBlend = "${base0A-rgb-r},${base0A-rgb-g},${base0A-rgb-b}"; - activeBackground = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - activeForeground = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}"; - inactiveBlend = "${base03-rgb-r},${base03-rgb-g},${base03-rgb-b}"; - inactiveBackground = "${base00-rgb-r},${base00-rgb-g},${base00-rgb-b}"; - inactiveForeground = "${base05-rgb-r},${base05-rgb-g},${base05-rgb-b}"; + "Colors:Window" = kdecolors; + "Colors:View" = kdecolors; + "Colors:Button" = kdecolors; + "Colors:Tooltip" = kdecolors; + "Colors:Complementary" = kdecolors; + "Colors:Selection" = + kdecolors + // (with colors'; { + BackgroundNormal = base0D; + BackgroundAlternate = base0D; + ForegroundNormal = base00; + ForegroundActive = base00; + ForegroundInactive = base00; + ForegroundLink = base00; + ForegroundVisited = base00; + }); + + WM = with colors'; { + activeBlend = base0A; + activeBackground = base00; + activeForeground = base05; + inactiveBlend = base03; + inactiveBackground = base00; + inactiveForeground = base05; }; }; @@ -138,7 +160,7 @@ let }; lookAndFeelDefaults = { - kwinrc."org.kde.kdecoration2".library = "org.kde.breeze"; + kwinrc."org.kde.kdecoration2".library = cfg.decorations; plasmarc.Theme.name = "default"; kdeglobals = { @@ -212,7 +234,7 @@ let kdeglobals = { KDE.LookAndFeelPackage = makeImmutable "stylix"; - General = rec { + General = with config.stylix.fonts; rec { font = makeImmutable "${sansSerif.name},${toString sizes.applications},-1,5,50,0,0,0,0,0"; fixed = makeImmutable "${monospace.name},${toString sizes.terminal},-1,5,50,0,0,0,0,0"; desktopFont = makeImmutable "${sansSerif.name},${toString sizes.desktop},-1,5,50,0,0,0,0,0"; @@ -251,36 +273,48 @@ let # might be installed, and look there. The ideal solution would require # changes to KDE to make it possible to update the wallpaper through # config files alone. - activator = pkgs.writeShellScriptBin "stylix-set-kde-wallpaper" '' + activator' = pkgs.writeShellScriptBin "stylix-activate-kde" '' set -eu - global_path() { + get_exe() { for directory in /run/current-system/sw/bin /usr/bin /bin; do if [[ -f "$directory/$1" ]]; then printf '%s\n' "$directory/$1" return 0 fi done - + echo "Skipping `$1`: command not found" return 1 } - if wallpaper_image="$(global_path plasma-apply-wallpaperimage)"; then + if wallpaper_image="$(get_exe plasma-apply-wallpaperimage)"; then "$wallpaper_image" "${themePackage}/share/wallpapers/stylix" - else - echo "Skipping plasma-apply-wallpaperimage: command not found" fi - if look_and_feel="$(global_path plasma-apply-lookandfeel)"; then + if look_and_feel="$(get_exe plasma-apply-lookandfeel)"; then "$look_and_feel" --apply stylix - else - echo "Skipping plasma-apply-lookandfeel: command not found" fi ''; - - activateDocs = "https://stylix.danth.me/options/hm.html#stylixtargetskdeservice"; + activator = lib.getExe activator'; in { - options.stylix.targets.kde.enable = config.lib.stylix.mkEnableTarget "KDE" true; + options.stylix.targets.kde = { + enable = mkEnableTarget "KDE" true; + + decorations = lib.mkOption { + type = lib.types.str; + default = "org.kde.breeze"; + description = '' + The library for the window decorations theme. + + Decorations other than default `org.kde.breeze` may not be compatible + with stylix. + + To list all available decorations, see the `library` key in the + `org.kde.kdecoration2` section of `$HOME/.config/kwinrc` after + imperatively applying the window decoration via the System Settings app. + ''; + }; + }; config = lib.mkIf @@ -290,10 +324,9 @@ in packages = [ themePackage ]; # This activation entry will run the theme activator when the homeConfiguration is activated - # Note: This only works in an already running Plasma session. activation.stylixLookAndFeel = lib.hm.dag.entryAfter [ "writeBoundary" ] '' - ${lib.getExe activator} || verboseEcho \ - "KDE theme setting failed. See `${activateDocs}`" + ${activator} || verboseEcho \ + "Stylix KDE theme setting failed. This only works in a running Plasma session." ''; }; @@ -305,7 +338,7 @@ in configFile."autostart/stylix-activator.desktop".text = '' [Desktop Entry] Type=Application - Exec=${lib.getExe activator} + Exec=${activator} Name=Stylix Activator X-KDE-AutostartScript=true '';