From afb474061df5e2344d4afda0ccedc048f8754ed2 Mon Sep 17 00:00:00 2001 From: Ryan Schanzenbacher Date: Sat, 27 Jun 2026 01:41:02 -0400 Subject: "official" way to do the wallpapers --- hosts/RyanMac/configuration.nix | 2 +- modules/darwin/random-wallpaper/module.nix | 29 ++++++++++++ .../darwin/random-wallpaper/wallpaper-daemon.swift | 51 ++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 modules/darwin/random-wallpaper/module.nix create mode 100644 modules/darwin/random-wallpaper/wallpaper-daemon.swift diff --git a/hosts/RyanMac/configuration.nix b/hosts/RyanMac/configuration.nix index 5e87070..8bd7131 100644 --- a/hosts/RyanMac/configuration.nix +++ b/hosts/RyanMac/configuration.nix @@ -45,7 +45,7 @@ in { # Modules imports = [ inputs.nix-homebrew.darwinModules.nix-homebrew - ../../modules/darwin/random-wallpaper.nix + ../../modules/darwin/random-wallpaper/module.nix ]; # Define the system's user and home dir location diff --git a/modules/darwin/random-wallpaper/module.nix b/modules/darwin/random-wallpaper/module.nix new file mode 100644 index 0000000..b20ce88 --- /dev/null +++ b/modules/darwin/random-wallpaper/module.nix @@ -0,0 +1,29 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.local.randomWallpaper; + wallpaper-agent-src = ./wallpaper-daemon.swift; +in +{ + options.local.randomWallpaper = { + enable = lib.mkEnableOption "Random Rotating Wallpaper"; + directory = lib.mkOption { + type = lib.types.str; + description = "Folder containing images"; + }; + interval = lib.mkOption { + type = lib.types.int; + default = 1800; + description = "Seconds between wallpaper changes"; + }; + }; + + config = lib.mkIf cfg.enable { + launchd.user.agents.random-wallpaper.serviceConfig = { + Label = "org.rschanz.wallpaperDaemon"; + ProgramArguments = [ "/usr/bin/swift" "${wallpaper-agent-src}" "${cfg.directory}" "${builtins.toString cfg.interval}" ]; + RunAtLoad = true; + KeepAlive = true; + ProcessType = "Background"; + }; + }; +} diff --git a/modules/darwin/random-wallpaper/wallpaper-daemon.swift b/modules/darwin/random-wallpaper/wallpaper-daemon.swift new file mode 100644 index 0000000..72f52ef --- /dev/null +++ b/modules/darwin/random-wallpaper/wallpaper-daemon.swift @@ -0,0 +1,51 @@ +import AppKit +import Foundation + +if CommandLine.arguments.count != 3 { + print("Must have 2 args") + exit(1) +} + +let wallpaperDir = CommandLine.arguments[1] +let interval: TimeInterval = Double(CommandLine.arguments[2]) ?? 30.0 + +let workspace = NSWorkspace.shared +let imageExtensions: Set = ["jpg", "jpeg", "png", "heic", "tiff", "gif", "bmp"] + +func images() -> [URL] { + let dir = URL(fileURLWithPath: wallpaperDir, isDirectory: true) + let entries = (try? FileManager.default.contentsOfDirectory( + at: dir, includingPropertiesForKeys: nil)) ?? [] + return entries.filter { imageExtensions.contains($0.pathExtension.lowercased()) } +} + +var current: URL? + +// setDesktopImageURL only touches the current Space (all displays). +func apply(_ url: URL?) { + guard let url else { return } + for screen in NSScreen.screens { + try? workspace.setDesktopImageURL(url, for: screen, options: [:]) + } +} + +func advance() { + let imgs = images() + guard !imgs.isEmpty else { return } + let pool = imgs.count > 1 ? imgs.filter { $0 != current } : imgs + current = pool.randomElement() + apply(current) +} + +// Whenever you switch Space, repaint it to the current image. +workspace.notificationCenter.addObserver( + forName: NSWorkspace.activeSpaceDidChangeNotification, + object: nil, queue: .main +) { _ in apply(current) } + +advance() +Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { _ in advance() } + +let app = NSApplication.shared +app.setActivationPolicy(.accessory) // no Dock icon +app.run() -- cgit v1.3