First commit
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
../../modules/nixos/base.nix
|
||||
./hardware-configuration.nix
|
||||
./graphics-effects.nix
|
||||
./hardware.nix
|
||||
./disk.nix
|
||||
];
|
||||
|
||||
# Bootloader
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
|
||||
# Basic system identity / networking
|
||||
networking.hostName = "traveldroid";
|
||||
|
||||
# Keyboard (Xwayland / X11 apps)
|
||||
services.xserver.xkb = {
|
||||
layout = "us";
|
||||
variant = "";
|
||||
};
|
||||
|
||||
networking.networkmanager.enable = false;
|
||||
systemd.services."NetworkManager-wait-online".enable = false;
|
||||
|
||||
|
||||
# Enable flakes
|
||||
nix.settings.experimental-features = [ "nix-command" "flakes" ];
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{ ... }: { }
|
||||
@@ -0,0 +1,87 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
# ====================== WALLPAPER=========================
|
||||
|
||||
let
|
||||
# Source of wallpapers in your repo (as you specified)
|
||||
srcDir = "~/nixos/files/wallpapers/picture";
|
||||
# Note: this is interpreted as a shell-style KEY=VALUE file.
|
||||
confFile = "~/nixos/files/conf/wallpaper/wallpaper.conf";
|
||||
setWallpaperScript = pkgs.writeShellScript "set-hourly-wallpaper" ''
|
||||
set -euo pipefail
|
||||
|
||||
# --- Defaults (can be overridden by wallpaper.conf) ---
|
||||
TRANSITION_TYPE="fade" # e.g. fade, wipe, simple, any
|
||||
TRANSITION_DURATION="2" # seconds (can be decimals)
|
||||
TRANSITION_FPS="60" # frames per second
|
||||
SRC_DIR="${srcDir}"
|
||||
|
||||
# Load overrides (shell KEY=VALUE)
|
||||
if [ -f "${confFile}" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "${confFile}"
|
||||
fi
|
||||
|
||||
DEST_DIR="$HOME/Pictures/Wallpapers"
|
||||
mkdir -p "$DEST_DIR"
|
||||
|
||||
# Copy source wallpapers into user's Pictures/Wallpapers
|
||||
# -r recursive, -u update if newer
|
||||
# If the folder is empty or missing, don't crash the session.
|
||||
if [ -d "$SRC_DIR" ]; then
|
||||
cp -ru "$SRC_DIR"/. "$DEST_DIR"/ 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Pick a random image from DEST_DIR
|
||||
img="$(
|
||||
find "$DEST_DIR" -type f \
|
||||
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) \
|
||||
| shuf -n 1
|
||||
)"
|
||||
|
||||
[ -n "''${img:-}" ] || exit 0
|
||||
|
||||
# Ensure swww daemon is running (per-user)
|
||||
if ! ${pkgs.swww}/bin/swww query >/dev/null 2>&1; then
|
||||
${pkgs.swww}/bin/swww-daemon >/dev/null 2>&1 &
|
||||
sleep 0.4
|
||||
fi
|
||||
|
||||
# Smooth transition wallpaper set
|
||||
exec ${pkgs.swww}/bin/swww img "$img" \
|
||||
--transition-type "''${TRANSITION_TYPE}" \
|
||||
--transition-duration "''${TRANSITION_DURATION}" \
|
||||
--transition-fps "''${TRANSITION_FPS}"
|
||||
'';
|
||||
in
|
||||
{
|
||||
# Packages needed by the script + swww
|
||||
environment.systemPackages = with pkgs; [
|
||||
swww
|
||||
bash
|
||||
coreutils
|
||||
findutils
|
||||
util-linux
|
||||
];
|
||||
|
||||
# Run for ANY logged-in user via systemd user units
|
||||
# (each user session has its own systemd --user instance)
|
||||
systemd.user.services.wallpaper-rotate = {
|
||||
description = "Copy wallpapers to ~/Pictures/Wallpapers and set a random wallpaper with transition";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${setWallpaperScript}";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.timers.wallpaper-rotate = {
|
||||
description = "Hourly wallpaper rotation timer";
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnBootSec = "2min";
|
||||
OnUnitActiveSec = "1h";
|
||||
RandomizedDelaySec = "5min";
|
||||
Unit = "wallpaper-rotate.service";
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_usb_sdmmc" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/f08fc2a7-0b2b-4cbb-a65a-8b6e7ee4cec9";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@" ];
|
||||
};
|
||||
|
||||
fileSystems."/home" =
|
||||
{ device = "/dev/disk/by-uuid/f08fc2a7-0b2b-4cbb-a65a-8b6e7ee4cec9";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=@home" ];
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/25C1-E4F2";
|
||||
fsType = "vfat";
|
||||
options = [ "fmask=0077" "dmask=0077" ];
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/f771a317-26a2-4524-a458-42ba22b29e67"; }
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{ ... }: { }
|
||||
@@ -0,0 +1,226 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.dataPro.wallpaper; # custom namespace
|
||||
|
||||
# Where we keep a runtime-editable config for the user.
|
||||
runtimeConfDir = "${config.xdg.configHome}/wallpaper";
|
||||
runtimeConfPath = "${runtimeConfDir}/wallpaper.conf";
|
||||
|
||||
rotateScript = pkgs.writeShellScript "wallpaper-rotate" ''
|
||||
set -euo pipefail
|
||||
|
||||
export PATH=${lib.makeBinPath [
|
||||
pkgs.coreutils
|
||||
pkgs.findutils
|
||||
pkgs.gnugrep
|
||||
pkgs.gawk
|
||||
pkgs.util-linux
|
||||
pkgs.swww
|
||||
]}
|
||||
|
||||
# Defaults (can be overridden by wallpaper.conf)
|
||||
SOURCE_DIR="${cfg.sourceDir}"
|
||||
TARGET_DIR="${cfg.targetDir}"
|
||||
ROTATION_DIR="${cfg.rotationDir}"
|
||||
TRANSITION_TYPE="fade"
|
||||
TRANSITION_DURATION="2.5"
|
||||
TRANSITION_FPS="60"
|
||||
PICK_MODE="random" # random | sequential
|
||||
LAST_FILE="${config.xdg.stateHome}/wallpaper/last.txt"
|
||||
|
||||
# Load user config if present (KEY=VALUE lines; '#' comments allowed)
|
||||
if [ -f "${runtimeConfPath}" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "${runtimeConfPath}"
|
||||
fi
|
||||
|
||||
mkdir -p "$TARGET_DIR" "${config.xdg.stateHome}/wallpaper"
|
||||
|
||||
# Ensure swww-daemon is running
|
||||
if ! pgrep -x swww-daemon >/dev/null 2>&1; then
|
||||
swww-daemon >/dev/null 2>&1 &
|
||||
sleep 0.3
|
||||
fi
|
||||
|
||||
# Pick image
|
||||
if [ ! -d "$ROTATION_DIR" ]; then
|
||||
echo "Rotation directory does not exist: $ROTATION_DIR" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Build list once per run
|
||||
mapfile -d '' -t imgs < <(
|
||||
find "$ROTATION_DIR" -type f \
|
||||
\( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.webp' \) \
|
||||
-print0
|
||||
)
|
||||
|
||||
if [ "${#imgs[@]}" -eq 0 ]; then
|
||||
echo "No images found in: $ROTATION_DIR" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
img=""
|
||||
if [ "$PICK_MODE" = "sequential" ]; then
|
||||
last=""
|
||||
if [ -f "$LAST_FILE" ]; then
|
||||
last="$(cat "$LAST_FILE" || true)"
|
||||
fi
|
||||
|
||||
# Sort for stable order
|
||||
IFS=$'\n' sorted=($(printf '%s\n' "${imgs[@]}" | sort))
|
||||
unset IFS
|
||||
|
||||
# Find next after last
|
||||
next=""
|
||||
found_last=0
|
||||
for f in "${sorted[@]}"; do
|
||||
if [ "$found_last" -eq 1 ]; then
|
||||
next="$f"
|
||||
break
|
||||
fi
|
||||
if [ "$f" = "$last" ]; then
|
||||
found_last=1
|
||||
fi
|
||||
done
|
||||
if [ -z "$next" ]; then
|
||||
next="${sorted[0]}"
|
||||
fi
|
||||
img="$next"
|
||||
printf '%s' "$img" > "$LAST_FILE"
|
||||
else
|
||||
# random
|
||||
img="$(printf '%s\0' "${imgs[@]}" | shuf -z -n 1 | tr -d '\0')"
|
||||
fi
|
||||
|
||||
# Smooth transition wallpaper set
|
||||
swww img "$img" \
|
||||
--transition-type "$TRANSITION_TYPE" \
|
||||
--transition-duration "$TRANSITION_DURATION" \
|
||||
--transition-fps "$TRANSITION_FPS"
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.dataPro.wallpaper = {
|
||||
enable = lib.mkEnableOption "Hourly wallpaper rotation with swww (Hyprland/Wayland)";
|
||||
|
||||
# You asked to make this easy to change:
|
||||
sourceDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${config.home.homeDirectory}/nixos/files/wallpaper/picture";
|
||||
description = "Folder containing wallpapers to rotate (source of truth).";
|
||||
};
|
||||
|
||||
targetDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${config.home.homeDirectory}/wallpaper";
|
||||
description = "Folder in the user's home where wallpapers are copied to.";
|
||||
};
|
||||
|
||||
rotationDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "${config.home.homeDirectory}/wallpaper/picture";
|
||||
description = "Folder used by the rotator to pick wallpapers from (usually inside targetDir).";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = [
|
||||
pkgs.swww
|
||||
pkgs.coreutils
|
||||
pkgs.findutils
|
||||
pkgs.gnugrep
|
||||
pkgs.gawk
|
||||
pkgs.util-linux
|
||||
];
|
||||
|
||||
# Copy wallpapers from sourceDir into rotationDir (real copy) at activation.
|
||||
home.activation.wallpaperCopy = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
set -euo pipefail
|
||||
mkdir -p "${cfg.targetDir}" "${cfg.rotationDir}"
|
||||
|
||||
if [ -d "${cfg.sourceDir}" ]; then
|
||||
# Copy source into rotationDir (contents only).
|
||||
cp -a "${cfg.sourceDir}/." "${cfg.rotationDir}/"
|
||||
fi
|
||||
'';
|
||||
|
||||
# Install a runtime-editable config into ~/.config/wallpaper/wallpaper.conf
|
||||
# First-time copy from repo if present; then never overwrite if user edited it.
|
||||
home.activation.wallpaperConf = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
set -euo pipefail
|
||||
mkdir -p "${runtimeConfDir}"
|
||||
|
||||
if [ ! -f "${runtimeConfPath}" ]; then
|
||||
if [ -f "${config.home.homeDirectory}/nixos/files/conf/wallpaper/wallpaper.conf" ]; then
|
||||
cp -a "${config.home.homeDirectory}/nixos/files/conf/wallpaper/wallpaper.conf" "${runtimeConfPath}"
|
||||
else
|
||||
cat > "${runtimeConfPath}" <<'EOF'
|
||||
# wallpaper.conf — runtime settings for the wallpaper rotator (swww)
|
||||
# Lines are KEY=VALUE. '#' starts a comment.
|
||||
|
||||
# Folder to copy wallpapers from (source of truth)
|
||||
#SOURCE_DIR="$HOME/nixos/files/wallpaper/picture"
|
||||
|
||||
# Where wallpapers are copied to (a folder in your home)
|
||||
#TARGET_DIR="$HOME/wallpaper"
|
||||
|
||||
# Folder used for rotation (where images are selected from)
|
||||
#ROTATION_DIR="$HOME/wallpaper/picture"
|
||||
|
||||
# random | sequential
|
||||
#PICK_MODE="random"
|
||||
|
||||
# swww transition settings
|
||||
#TRANSITION_TYPE="fade"
|
||||
#TRANSITION_DURATION="2.5"
|
||||
#TRANSITION_FPS="60"
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
'';
|
||||
|
||||
# Start swww daemon on graphical session start
|
||||
systemd.user.services.swww-daemon = {
|
||||
Unit = {
|
||||
Description = "swww wallpaper daemon";
|
||||
After = [ "graphical-session.target" ];
|
||||
PartOf = [ "graphical-session.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = "${pkgs.swww}/bin/swww-daemon";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Rotate wallpaper hourly
|
||||
systemd.user.services.wallpaper-rotate = {
|
||||
Unit = {
|
||||
Description = "Rotate wallpaper (hourly)";
|
||||
After = [ "swww-daemon.service" ];
|
||||
};
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${rotateScript}";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.timers.wallpaper-rotate = {
|
||||
Unit = {
|
||||
Description = "Hourly wallpaper rotation timer";
|
||||
};
|
||||
Timer = {
|
||||
OnBootSec = "2m";
|
||||
OnUnitActiveSec = "1h";
|
||||
Unit = "wallpaper-rotate.service";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user