This commit is contained in:
mjallen18
2026-03-26 12:51:27 -05:00
parent a060a84cf1
commit c15f0b0f0b
6 changed files with 262 additions and 179 deletions

View File

@@ -18,14 +18,16 @@ in
options.${namespace}.desktop.hyprland = {
enable = mkEnableOption "enable hyprland desktop environment";
# These options are convenience aliases that feed into mjallen.wallpaper.*
# when the hyprland wallpaper sub-module is active.
wallpaperSource = mkOpt (types.enum [
"bing"
"nasa"
]) "bing" "Source for the wallpaper (bing or nasa)";
wallpaper = mkOpt types.path "/var/lib/wallpapers/current.jpg" "Path to the wallpaper folder";
wallpaper = mkOpt types.path "/var/lib/wallpapers/current.jpg" "Path to the active wallpaper file";
wallpaperDir = mkOpt types.path "/var/lib/wallpapers" "Path to the wallpaper folder";
wallpaperDir = mkOpt types.path "/var/lib/wallpapers" "Path to the wallpaper directory";
defaultWallpaper = mkOpt types.path "${defaultWallpaper}/default.jpg" "Default wallpaper";
};

View File

@@ -7,176 +7,20 @@
}:
let
cfg = config.${namespace}.desktop.hyprland;
# The script to use based on the selected wallpaper source
wallpaper-command = if cfg.wallpaperSource == "nasa" then "nasa-wallpaper" else "bing-wallpaper";
# System activation script to ensure wallpaper is available early in boot
wallpaper-activation-script = ''
# Create wallpaper directory if it doesn't exist
mkdir -p ${cfg.wallpaperDir}
# Copy default wallpaper as fallback if it doesn't exist
if [ ! -f ${cfg.wallpaperDir}/fallback.jpg ]; then
cp ${cfg.defaultWallpaper} ${cfg.wallpaperDir}/fallback.jpg
fi
# If no current wallpaper exists, use the fallback
if [ ! -f ${cfg.wallpaperDir}/current.jpg ]; then
cp ${cfg.wallpaperDir}/fallback.jpg ${cfg.wallpaperDir}/current.jpg
fi
# Create symlink for Plymouth and SDDM
ln -sf ${cfg.wallpaperDir}/current.jpg /run/wallpaper.jpg
'';
bing-wallpaper = pkgs.writeScriptBin "bing-wallpaper" ''
# Directory to store wallpapers
WALLPAPER_DIR="${cfg.wallpaperDir}"
IMG_PATH="$WALLPAPER_DIR/current.jpg"
FALLBACK_PATH="$WALLPAPER_DIR/fallback.jpg"
# Ensure directory exists
mkdir -p "$WALLPAPER_DIR"
# Copy to the standard location for other services
ln -sf "$IMG_PATH" /run/wallpaper.jpg
# Try to download new wallpaper
if ${lib.getExe pkgs.curl} -s --connect-timeout 5 --max-time 10 "https://www.bing.com" > /dev/null; then
URL=$(${lib.getExe pkgs.curl} -s "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1" | \
${lib.getExe pkgs.jq} -r '.images[0].url')
FULL_URL="https://www.bing.com$URL"
if ${lib.getExe pkgs.curl} -s -o "$IMG_PATH.tmp" "$FULL_URL"; then
mv "$IMG_PATH.tmp" "$IMG_PATH"
echo "Downloaded $FULL_URL to $IMG_PATH successfully"
else
echo "Failed to download Bing wallpaper, using previous or fallback"
# If current doesn't exist, use fallback
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
else
echo "Network unavailable, using previous or fallback wallpaper"
# If current doesn't exist, use fallback
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
'';
nasa-wallpaper = pkgs.writeScriptBin "nasa-wallpaper" ''
# Directory to store wallpapers
WALLPAPER_DIR="${cfg.wallpaperDir}"
IMG_PATH="$WALLPAPER_DIR/current.jpg"
FALLBACK_PATH="$WALLPAPER_DIR/fallback.jpg"
# Ensure directory exists
mkdir -p "$WALLPAPER_DIR"
# Copy to the standard location for other services
ln -sf "$IMG_PATH" /run/wallpaper.jpg
# Try to download new wallpaper
if ${lib.getExe pkgs.curl} -s --connect-timeout 5 --max-time 10 "https://api.nasa.gov" > /dev/null; then
APOD_URL="https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"
IMAGE_URL=$(${lib.getExe pkgs.curl} -s "$APOD_URL" | ${lib.getExe pkgs.jq} -r '.hdurl // .url')
if ${lib.getExe pkgs.curl} -s -o "$IMG_PATH.tmp" "$IMAGE_URL"; then
mv "$IMG_PATH.tmp" "$IMG_PATH"
echo "Downloaded $IMAGE_URL to $IMG_PATH successfully"
else
echo "Failed to download NASA wallpaper, using previous or fallback"
# If current doesn't exist, use fallback
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
else
echo "Network unavailable, using previous or fallback wallpaper"
# If current doesn't exist, use fallback
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
'';
in
{
imports = [ ../options.nix ];
# Wire the hyprland wallpaper options through to the shared wallpaper module,
# and provide the hyprctl hot-reload command so hyprpaper picks up the new image.
config = lib.mkIf cfg.enable {
environment.systemPackages = [
bing-wallpaper
nasa-wallpaper
];
# Add system activation script to ensure wallpaper is available early
system.activationScripts.wallpaper = wallpaper-activation-script;
systemd = {
services = {
preload-wallpaper = {
enable = true;
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
# before = [ "display-manager.service" ];
# requiredBy = [
# "plymouth-quit-wait.service"
# "display-manager.service"
# ];
# wantedBy = [ "display-manager.service" ];
path = [
pkgs.bash
pkgs.jq
pkgs.curl
bing-wallpaper
nasa-wallpaper
];
script = ''
${wallpaper-command}
'';
serviceConfig = {
Type = "oneshot";
TimeoutSec = "10s"; # Limit how long we wait for network
};
};
};
user = {
services = {
reload-wallpaper = {
enable = true;
path = [
pkgs.bash
pkgs.jq
pkgs.curl
pkgs.hyprland
bing-wallpaper
nasa-wallpaper
];
script = ''
${wallpaper-command}
${lib.getExe' pkgs.hyprland "hyprctl"} hyprpaper wallpaper ,${cfg.wallpaper},
'';
serviceConfig = {
Type = "oneshot";
};
};
};
# Create a timer to run the service periodically
timers = {
reload-wallpaper = {
description = "Timer for reload-wallpaper";
wantedBy = [ "timers.target" ];
# Timer configuration
timerConfig = {
OnCalendar = "daily"; # Check every day
Persistent = true; # Run immediately if last run was missed
Unit = "reload-wallpaper.service";
};
};
};
};
${namespace}.wallpaper = {
enable = true;
source = cfg.wallpaperSource;
path = cfg.wallpaper;
dir = cfg.wallpaperDir;
defaultWallpaper = cfg.defaultWallpaper;
reloadCommand = "${lib.getExe' pkgs.hyprland "hyprctl"} hyprpaper wallpaper ,${cfg.wallpaper},";
};
};
}

View File

@@ -1,30 +1,55 @@
{
config,
lib,
pkgs,
namespace,
...
}:
let
inherit (lib.${namespace}) mkBoolOpt;
inherit (lib.${namespace}) mkBoolOpt mkOpt;
cfg = config.${namespace}.desktop.plasma;
wallpaperCfg = config.${namespace}.wallpaper;
in
{
options.${namespace}.desktop.plasma = {
enable = lib.mkEnableOption "KDE Plasma 6 desktop environment";
wayland.enable = mkBoolOpt true "Use the Wayland session (default) instead of X11";
};
config = lib.mkIf cfg.enable {
services = {
desktopManager.plasma6.enable = true;
wallpaper = {
enable = mkBoolOpt false "Enable automatic wallpaper management (Bing/NASA daily download)";
displayManager.sddm = {
enable = true;
wayland.enable = cfg.wayland.enable;
};
source = mkOpt (lib.types.enum [
"bing"
"nasa"
]) "bing" "Source for the wallpaper (bing or nasa)";
};
xdg.portal.extraPortals = [ ];
};
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
services = {
desktopManager.plasma6.enable = true;
displayManager.sddm = {
enable = true;
wayland.enable = cfg.wayland.enable;
};
};
xdg.portal.extraPortals = [ ];
}
# Wallpaper management: wire the shared wallpaper module in when requested.
# plasma-apply-wallpaperimage hot-reloads the wallpaper in the running session.
(lib.mkIf cfg.wallpaper.enable {
${namespace}.wallpaper = {
enable = true;
source = cfg.wallpaper.source;
reloadCommand = "${lib.getExe' pkgs.kdePackages.plasma-workspace "plasma-apply-wallpaperimage"} /run/wallpaper.jpg";
};
})
]
);
}

View File

@@ -0,0 +1,173 @@
{
config,
lib,
pkgs,
namespace,
...
}:
let
cfg = config.${namespace}.wallpaper;
wallpaper-command = if cfg.source == "nasa" then "nasa-wallpaper" else "bing-wallpaper";
# System activation script to ensure wallpaper is available early in boot
wallpaper-activation-script = ''
# Create wallpaper directory if it doesn't exist
mkdir -p ${cfg.dir}
# Copy default wallpaper as fallback if it doesn't exist
if [ ! -f ${cfg.dir}/fallback.jpg ]; then
cp ${cfg.defaultWallpaper} ${cfg.dir}/fallback.jpg
fi
# If no current wallpaper exists, use the fallback
if [ ! -f ${cfg.dir}/current.jpg ]; then
cp ${cfg.dir}/fallback.jpg ${cfg.dir}/current.jpg
fi
# Create symlink for Plymouth and display manager
ln -sf ${cfg.dir}/current.jpg /run/wallpaper.jpg
'';
bing-wallpaper = pkgs.writeScriptBin "bing-wallpaper" ''
# Directory to store wallpapers
WALLPAPER_DIR="${cfg.dir}"
IMG_PATH="$WALLPAPER_DIR/current.jpg"
FALLBACK_PATH="$WALLPAPER_DIR/fallback.jpg"
# Ensure directory exists
mkdir -p "$WALLPAPER_DIR"
# Update symlink
ln -sf "$IMG_PATH" /run/wallpaper.jpg
# Try to download new wallpaper
if ${lib.getExe pkgs.curl} -s --connect-timeout 5 --max-time 10 "https://www.bing.com" > /dev/null; then
URL=$(${lib.getExe pkgs.curl} -s "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1" | \
${lib.getExe pkgs.jq} -r '.images[0].url')
FULL_URL="https://www.bing.com$URL"
if ${lib.getExe pkgs.curl} -s -o "$IMG_PATH.tmp" "$FULL_URL"; then
mv "$IMG_PATH.tmp" "$IMG_PATH"
echo "Downloaded $FULL_URL to $IMG_PATH successfully"
else
echo "Failed to download Bing wallpaper, using previous or fallback"
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
else
echo "Network unavailable, using previous or fallback wallpaper"
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
'';
nasa-wallpaper = pkgs.writeScriptBin "nasa-wallpaper" ''
# Directory to store wallpapers
WALLPAPER_DIR="${cfg.dir}"
IMG_PATH="$WALLPAPER_DIR/current.jpg"
FALLBACK_PATH="$WALLPAPER_DIR/fallback.jpg"
# Ensure directory exists
mkdir -p "$WALLPAPER_DIR"
# Update symlink
ln -sf "$IMG_PATH" /run/wallpaper.jpg
# Try to download new wallpaper
if ${lib.getExe pkgs.curl} -s --connect-timeout 5 --max-time 10 "https://api.nasa.gov" > /dev/null; then
APOD_URL="https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"
IMAGE_URL=$(${lib.getExe pkgs.curl} -s "$APOD_URL" | ${lib.getExe pkgs.jq} -r '.hdurl // .url')
if ${lib.getExe pkgs.curl} -s -o "$IMG_PATH.tmp" "$IMAGE_URL"; then
mv "$IMG_PATH.tmp" "$IMG_PATH"
echo "Downloaded $IMAGE_URL to $IMG_PATH successfully"
else
echo "Failed to download NASA wallpaper, using previous or fallback"
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
else
echo "Network unavailable, using previous or fallback wallpaper"
if [ ! -f "$IMG_PATH" ] && [ -f "$FALLBACK_PATH" ]; then
cp "$FALLBACK_PATH" "$IMG_PATH"
fi
fi
'';
reloadScript = lib.optionalString (cfg.reloadCommand != null) cfg.reloadCommand;
in
{
imports = [ ./options.nix ];
config = lib.mkIf cfg.enable {
environment.systemPackages = [
bing-wallpaper
nasa-wallpaper
];
# Ensure wallpaper directory and symlink exist before the display manager starts
system.activationScripts.wallpaper = wallpaper-activation-script;
systemd = {
services = {
# System-level: download on boot after network is available
preload-wallpaper = {
enable = true;
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
path = [
pkgs.bash
pkgs.jq
pkgs.curl
bing-wallpaper
nasa-wallpaper
];
script = ''
${wallpaper-command}
'';
serviceConfig = {
Type = "oneshot";
TimeoutSec = "10s";
};
};
};
user = {
services = {
# User-level: daily refresh + optional DE hot-reload
reload-wallpaper = {
enable = true;
path = [
pkgs.bash
pkgs.jq
pkgs.curl
bing-wallpaper
nasa-wallpaper
];
script = ''
${wallpaper-command}
${reloadScript}
'';
serviceConfig = {
Type = "oneshot";
};
};
};
timers = {
reload-wallpaper = {
description = "Timer for reload-wallpaper";
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
Unit = "reload-wallpaper.service";
};
};
};
};
};
};
}

View File

@@ -0,0 +1,36 @@
{
lib,
pkgs,
namespace,
...
}:
with lib;
let
inherit (lib.${namespace}) mkOpt;
# Default fallback wallpaper (included in the system)
defaultWallpaper = pkgs.runCommand "default-wallpaper" { } ''
mkdir -p $out
cp ${pkgs.nixos-artwork.wallpapers.nineish-dark-gray}/share/backgrounds/nixos/nix-wallpaper-nineish-dark-gray.png $out/default.jpg
'';
in
{
options.${namespace}.wallpaper = {
enable = mkEnableOption "shared wallpaper management (download, symlink, and boot integration)";
source = mkOpt (types.enum [
"bing"
"nasa"
]) "bing" "Source for the wallpaper (bing or nasa)";
path = mkOpt types.path "/var/lib/wallpapers/current.jpg" "Path to the active wallpaper file";
dir = mkOpt types.path "/var/lib/wallpapers" "Directory where wallpapers are stored";
defaultWallpaper = mkOpt types.path "${defaultWallpaper}/default.jpg" "Default fallback wallpaper";
reloadCommand =
mkOpt (types.nullOr types.str) null
"Optional shell command run after downloading a new wallpaper to notify the desktop environment. If null, no reload command is run.";
};
}

View File

@@ -65,7 +65,10 @@
enable = false;
wallpaperSource = "bing";
};
plasma.enable = lib.mkForce true;
plasma = {
enable = lib.mkForce true;
wallpaper.enable = true;
};
};
hardware = {
battery = {