Files
nix-config/modules/nixos/desktop/hyprland/default.nix
2025-08-26 20:28:55 -05:00

312 lines
9.0 KiB
Nix
Executable File

{
config,
pkgs,
lib,
namespace,
...
}:
let
cfg = config.${namespace}.desktop.hyprland;
# Create a persistent directory for wallpapers
wallpaperDir = "/var/lib/wallpapers";
# 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
'';
bing-wallpaper = pkgs.writeScriptBin "bing-wallpaper" ''
# Directory to store wallpapers
WALLPAPER_DIR="${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 curl -s --connect-timeout 5 --max-time 10 "https://www.bing.com" > /dev/null; then
URL=$(curl -s "https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1" | \
jq -r '.images[0].url')
FULL_URL="https://www.bing.com$URL"
if 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="${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 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=$(curl -s "$APOD_URL" | jq -r '.hdurl // .url')
if 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
'';
# Select the appropriate wallpaper script based on the configuration
sddmThemeName = "sddm-astronaut-theme";
sddmThemePkg = pkgs.sddm-astronaut.override {
embeddedTheme = "astronaut";
themeConfig = {
Background = "/run/wallpaper.jpg";
};
};
# 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 ${wallpaperDir}
# Copy default wallpaper as fallback if it doesn't exist
if [ ! -f ${wallpaperDir}/fallback.jpg ]; then
cp ${defaultWallpaper}/default.jpg ${wallpaperDir}/fallback.jpg
fi
# If no current wallpaper exists, use the fallback
if [ ! -f ${wallpaperDir}/current.jpg ]; then
cp ${wallpaperDir}/fallback.jpg ${wallpaperDir}/current.jpg
fi
# Create symlink for Plymouth and SDDM
ln -sf ${wallpaperDir}/current.jpg /run/wallpaper.jpg
'';
in
{
imports = [ ./options.nix ];
config = lib.mkIf cfg.enable {
environment.systemPackages = [
bing-wallpaper
nasa-wallpaper
pkgs.jq
];
# Add system activation script to ensure wallpaper is available early
system.activationScripts.wallpaper = wallpaper-activation-script;
# Configure Plymouth to use the same wallpaper
boot.plymouth = {
enable = true;
extraConfig = ''
ShowDelay=0
DeviceTimeout=5
DeviceScale=1
'';
};
services = {
displayManager = {
sddm = {
enable = true;
package = pkgs.kdePackages.sddm;
extraPackages = [ sddmThemePkg ];
theme = sddmThemeName;
wayland.enable = true;
settings = {
Theme = {
ThemeDir = "${sddmThemePkg}/share/sddm/themes";
};
};
};
# Disable gdm
gdm.enable = lib.mkForce false;
defaultSession = "hyprland";
};
# disable other desktops
desktopManager = {
plasma6.enable = lib.mkForce false;
gnome.enable = lib.mkForce false;
};
dbus.enable = true;
ddccontrol.enable = false;
blueman.enable = true;
};
programs = {
hyprland = {
enable = true;
xwayland.enable = true;
portalPackage = lib.mkDefault pkgs.xdg-desktop-portal-hyprland;
};
nm-applet.enable = true;
};
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
};
};
# Create a service that runs very early in boot to ensure wallpaper is available
early-wallpaper-setup = {
enable = true;
description = "Setup wallpaper early in boot process";
wantedBy = [
"multi-user.target"
"plymouth-start.service"
];
before = [ "plymouth-start.service" ];
script = ''
# Ensure wallpaper directory exists
mkdir -p ${wallpaperDir}
# If no current wallpaper exists, use the fallback
if [ ! -f ${wallpaperDir}/current.jpg ]; then
cp ${wallpaperDir}/fallback.jpg ${wallpaperDir}/current.jpg
fi
# Create symlink for Plymouth and SDDM
ln -sf ${wallpaperDir}/current.jpg /run/wallpaper.jpg
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
};
};
user = {
services = {
reload-wallpaper = {
enable = true;
path = [
pkgs.bash
pkgs.jq
pkgs.curl
pkgs.hyprland
bing-wallpaper
nasa-wallpaper
];
script = ''
${wallpaper-command}
${pkgs.hyprland}/bin/hyprctl hyprpaper reload ,/run/wallpaper.jpg
'';
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";
};
};
};
};
};
security = {
polkit.enable = true;
# configure sudo
sudo.extraRules = [
{
commands = [
{
command = "/run/current-system/sw/bin/waybar-weather";
options = [ "NOPASSWD" ];
}
{
command = "/run/current-system/sw/bin/waybar-updates";
options = [ "NOPASSWD" ];
}
];
groups = [ "wheel" ];
}
];
};
xdg.portal = {
enable = true;
wlr.enable = true;
xdgOpenUsePortal = true;
extraPortals = lib.mkDefault [
pkgs.xdg-desktop-portal-hyprland
pkgs.xdg-desktop-portal-gnome
pkgs.xdg-desktop-portal-gtk
];
};
};
}