{ config, pkgs, lib, flakeRoot, ... }: let repoWallpaperDir = flakeRoot + "/assets/conf/desktop/wallpaper"; repoWallpaperConf = flakeRoot + "/assets/conf/desktop/wallpaper/wallpaper.conf"; userRelRoot = "nixos_conf/wallpaperstuff"; userAbsRoot = "${config.home.homeDirectory}/${userRelRoot}"; userConfPath = "${userAbsRoot}/wallpaper.conf"; userWsScriptPath = "${userAbsRoot}/wpaperd-workspace-1to9.sh"; # Exclude wallpaper.conf so HM does NOT manage it (avoids backup collisions) repoWallpapersOnly = lib.cleanSourceWith { src = repoWallpaperDir; filter = path: type: (builtins.baseNameOf path) != "wallpaper.conf"; }; wsScript = '' #!/usr/bin/env bash set -euo pipefail ROOT_DIR="''${1:?usage: wpaperd-workspace-1to9.sh /path/to/wallpaper-dir}" : "''${XDG_RUNTIME_DIR:?XDG_RUNTIME_DIR not set}" : "''${HYPRLAND_INSTANCE_SIGNATURE:?HYPRLAND_INSTANCE_SIGNATURE not set}" SOCK="''${XDG_RUNTIME_DIR}/hypr/''${HYPRLAND_INSTANCE_SIGNATURE}/.socket2.sock" [[ -S "$SOCK" ]] || { echo "Hyprland socket not found: $SOCK" >&2; exit 1; } set_for_ws() { local ws_raw="$1" # Hyprland workspace name may look like "1" or "1:foo" — take the numeric prefix local ws="''${ws_raw%%:*}" [[ "$ws" =~ ^[1-9]$ ]] || return 0 local img="$ROOT_DIR/wallpaper$ws.jpg" if [[ -f "$img" ]]; then ${pkgs.wpaperd}/bin/wpaperctl set "$img" >/dev/null 2>&1 || true fi } # Apply once at start (best effort): ask hyprctl for active workspace name if command -v ${pkgs.hyprland}/bin/hyprctl >/dev/null 2>&1; then cur="$(${pkgs.hyprland}/bin/hyprctl activeworkspace -j 2>/dev/null | ${pkgs.jq}/bin/jq -r '.name // empty' || true)" [[ -n "''${cur:-}" ]] && set_for_ws "$cur" || true fi exec ${pkgs.socat}/bin/socat -u "UNIX-CONNECT:$SOCK" - | while IFS= read -r line; do case "$line" in workspace\>\>*) ws="''${line#workspace>>}" set_for_ws "$ws" ;; esac done ''; in { home.packages = [ pkgs.wpaperd pkgs.socat pkgs.jq pkgs.hyprland ]; # Sync everything *except* wallpaper.conf into ~/nixos_conf/wallpaperstuff # Put wallpaper1.jpg .. wallpaper9.jpg in your repo wallpaper dir and they’ll be copied here. home.file."${userRelRoot}" = { source = repoWallpapersOnly; recursive = true; }; # Now safely overwrite the config every activation (no HM collision) home.activation.wallpaperConfForce = lib.hm.dag.entryAfter [ "writeBoundary" ] '' set -euo pipefail mkdir -p "${userAbsRoot}" install -m 0644 "${repoWallpaperConf}" "${userConfPath}" ''; # Install the listener script home.file."${userRelRoot}/wpaperd-workspace-1to9.sh" = { text = wsScript; executable = true; }; # wpaperd daemon systemd.user.services.wpaperd = { Unit = { Description = "wpaperd wallpaper daemon"; After = [ "default.target" ]; }; Service = { Type = "simple"; ExecStart = "${pkgs.wpaperd}/bin/wpaperd --config ${userConfPath}"; Restart = "on-failure"; RestartSec = 1; }; Install.WantedBy = [ "default.target" ]; }; # Workspace listener: switches wallpaper when workspace changes (1..9) systemd.user.services.wpaperd-workspace-1to9 = { Unit = { Description = "Set wallpaper1..9.jpg per Hyprland workspace (wpaperctl)"; After = [ "wpaperd.service" "graphical-session.target" ]; PartOf = [ "graphical-session.target" ]; }; Service = { Type = "simple"; ExecStart = "${pkgs.bash}/bin/bash ${userWsScriptPath} ${userAbsRoot}"; Restart = "on-failure"; RestartSec = 1; }; Install.WantedBy = [ "default.target" ]; }; }