Commit 4ffc7f7

HPCesia <me@hpcesia.com>
2025-10-10 14:02:56
feat: dms' wallpaper option
1 parent 87eaad3
Changed files (1)
modules
desktop
shell
modules/desktop/shell/niri/options.nix
@@ -6,17 +6,145 @@
   }: let
     inherit (lib) types mkOption;
     format = pkgs.formats.json {};
-    cfg = config.programs.dankMaterialShell.settings;
+    cfg = config.programs.dankMaterialShell;
+
+    mergeConfigScript = config: target:
+      pkgs.writeShellApplication {
+        name = "dms-merge-config";
+        runtimeEnv = {
+          NEW_JSON = pkgs.writeText "config" (builtins.toJSON config);
+        };
+        runtimeInputs = with pkgs; [jq];
+        text = ''
+          set -eu
+
+          TARGET_FILE="${target}"
+          TARGET_DIR=$(dirname "$TARGET_FILE")
+
+          mkdir -p "$TARGET_DIR"
+
+          if [ -f "$TARGET_FILE" ]; then
+            echo "Merging config into existing file: $TARGET_FILE"
+            TEMP_FILE=$(mktemp)
+            jq --slurp '.[0] * .[1]' "$TARGET_FILE" "$NEW_JSON" > "$TEMP_FILE"
+            mv "$TEMP_FILE" "$TARGET_FILE"
+          else
+            echo "$TARGET_FILE not found. Creating new..."
+            echo "$NEW_JSON" > "$TARGET_FILE"
+          fi
+
+          echo "Config merge complete."
+        '';
+      };
   in {
-    options.programs.dankMaterialShell.settings = mkOption {
-      type = types.nullOr (types.submodule {
-        freeformType = format.type;
-      });
-      default = null;
+    options.programs.dankMaterialShell = {
+      settings = mkOption {
+        type = types.nullOr (types.submodule {
+          freeformType = format.type;
+        });
+        default = null;
+      };
+      wallpaper = {
+        enable = lib.mkEnableOption "Enable wallpaper.";
+        path = mkOption {
+          type = types.oneOf [types.str types.path];
+          default = "";
+          description = "Path of wallpaper, could be path or hex color string";
+        };
+        perMode = {
+          enable = lib.mkEnableOption "Enable per mode wallpaper.";
+          light = mkOption {
+            type = types.oneOf [types.str types.path];
+            default = cfg.wallpaper.path;
+          };
+          dark = mkOption {
+            type = types.oneOf [types.str types.path];
+            default = cfg.wallpaper.path;
+          };
+        };
+        perMonitor = {
+          enable = lib.mkEnableOption "Enable per mode wallpaper.";
+          monitors = mkOption {
+            type = types.attrsOf (types.oneOf [types.str types.path]);
+            default = {};
+          };
+        };
+        cycling = {
+          enable = lib.mkEnableOption "Enable wallpaper cycling.";
+          mode = mkOption {
+            type = types.enum ["interval" "time"];
+            default = "interval";
+          };
+          interval = mkOption {
+            type = types.ints.unsigned;
+            default = 300;
+          };
+          time = mkOption {
+            type = types.str;
+            default = "06:00";
+          };
+        };
+        transition = {
+          name = mkOption {
+            type = types.enum [
+              "random"
+              "none"
+              "fade"
+              "wipe"
+              "disc"
+              "stripes"
+              "iris bloom"
+              "pixelate"
+              "portal"
+            ];
+            default = "fade";
+          };
+          include = mkOption {
+            type = types.listOf (types.enum ["fade" "wipe" "disc" "stripes" "iris bloom" "pixelate" "portal"]);
+            default = ["fade" "wipe" "disc" "stripes" "iris bloom" "pixelate" "portal"];
+          };
+        };
+      };
     };
 
     config = {
-      systemd.user.services.dank-material-shell-setup = lib.mkIf (cfg != null) {
+      systemd.user.services.dank-material-shell-settings-setup = lib.mkIf (cfg.settings != null) {
+        Unit = {
+          Description = "DankMaterialShell Setup service";
+          After = ["graphical-session-pre.target"];
+          Wants = ["graphical-session-pre.target"];
+        };
+        Install.WantedBy = ["graphical-session.target"];
+        Service = {
+          Type = "oneshot";
+          UMask = "0022";
+          ExecStart = lib.getExe (
+            mergeConfigScript cfg.settings "${config.xdg.configHome}/DankMaterialShell/settings.json"
+          );
+        };
+      };
+
+      systemd.user.services.dank-material-shell-wallpaper-setup = let
+        wcfg = cfg.wallpaper;
+        mergedConfig = {
+          wallpaperPath = lib.optionalString wcfg.enable wcfg.path;
+
+          perMonitorWallpaper = wcfg.perMonitor.enable;
+          monitorWallpapers = wcfg.perMonitor.monitors;
+
+          perModeWallpaper = wcfg.perMode.enable;
+          wallpaperPathLight = wcfg.perMode.light;
+          wallpaperPathDark = wcfg.perMode.dark;
+
+          wallpaperCyclingEnabled = wcfg.cycling.enable;
+          wallpaperCyclingMode = wcfg.cycling.mode;
+          wallpaperCyclingInterval = wcfg.cycling.interval;
+          wallpaperCyclingTime = wcfg.cycling.time;
+
+          wallpaperTransition = wcfg.transition.name;
+          includedTransitions = wcfg.transition.include;
+        };
+      in {
         Unit = {
           Description = "DankMaterialShell Setup service";
           After = ["graphical-session-pre.target"];
@@ -26,33 +154,9 @@
         Service = {
           Type = "oneshot";
           UMask = "0022";
-          ExecStart = lib.getExe (pkgs.writeShellApplication {
-            name = "dms-setup";
-            runtimeInputs = with pkgs; [jq];
-            text = let
-              configPath = "${config.xdg.configHome}/DankMaterialShell/settings.json";
-            in ''
-              set -eu
-
-              TARGET_FILE="${configPath}"
-              TARGET_DIR=$(dirname "$TARGET_FILE")
-              NEW_JSON='${builtins.toJSON cfg}'
-
-              mkdir -p "$TARGET_DIR"
-
-              if [ -f "$TARGET_FILE" ]; then
-                echo "Merging config into existing file: $TARGET_FILE"
-                TEMP_FILE=$(mktemp)
-                jq --slurp '.[0] * .[1]' "$TARGET_FILE" <(echo "$NEW_JSON") > "$TEMP_FILE"
-                mv "$TEMP_FILE" "$TARGET_FILE"
-              else
-                echo "$TARGET_FILE not found. Creating new..."
-                echo "$NEW_JSON" > "$TARGET_FILE"
-              fi
-
-              echo "Config merge complete."
-            '';
-          });
+          ExecStart = lib.getExe (
+            mergeConfigScript mergedConfig "${config.xdg.stateHome}/DankMaterialShell/session.json"
+          );
         };
       };
     };