summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hosts/RyanMac/configuration.nix2
-rw-r--r--modules/darwin/random-wallpaper/module.nix29
-rw-r--r--modules/darwin/random-wallpaper/wallpaper-daemon.swift51
3 files changed, 81 insertions, 1 deletions
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 {
45 # Modules 45 # Modules
46 imports = [ 46 imports = [
47 inputs.nix-homebrew.darwinModules.nix-homebrew 47 inputs.nix-homebrew.darwinModules.nix-homebrew
48 ../../modules/darwin/random-wallpaper.nix 48 ../../modules/darwin/random-wallpaper/module.nix
49 ]; 49 ];
50 50
51 # Define the system's user and home dir location 51 # 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 @@
1{ config, lib, pkgs, ... }:
2let
3 cfg = config.local.randomWallpaper;
4 wallpaper-agent-src = ./wallpaper-daemon.swift;
5in
6{
7 options.local.randomWallpaper = {
8 enable = lib.mkEnableOption "Random Rotating Wallpaper";
9 directory = lib.mkOption {
10 type = lib.types.str;
11 description = "Folder containing images";
12 };
13 interval = lib.mkOption {
14 type = lib.types.int;
15 default = 1800;
16 description = "Seconds between wallpaper changes";
17 };
18 };
19
20 config = lib.mkIf cfg.enable {
21 launchd.user.agents.random-wallpaper.serviceConfig = {
22 Label = "org.rschanz.wallpaperDaemon";
23 ProgramArguments = [ "/usr/bin/swift" "${wallpaper-agent-src}" "${cfg.directory}" "${builtins.toString cfg.interval}" ];
24 RunAtLoad = true;
25 KeepAlive = true;
26 ProcessType = "Background";
27 };
28 };
29}
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 @@
1import AppKit
2import Foundation
3
4if CommandLine.arguments.count != 3 {
5 print("Must have 2 args")
6 exit(1)
7}
8
9let wallpaperDir = CommandLine.arguments[1]
10let interval: TimeInterval = Double(CommandLine.arguments[2]) ?? 30.0
11
12let workspace = NSWorkspace.shared
13let imageExtensions: Set<String> = ["jpg", "jpeg", "png", "heic", "tiff", "gif", "bmp"]
14
15func images() -> [URL] {
16 let dir = URL(fileURLWithPath: wallpaperDir, isDirectory: true)
17 let entries = (try? FileManager.default.contentsOfDirectory(
18 at: dir, includingPropertiesForKeys: nil)) ?? []
19 return entries.filter { imageExtensions.contains($0.pathExtension.lowercased()) }
20}
21
22var current: URL?
23
24// setDesktopImageURL only touches the current Space (all displays).
25func apply(_ url: URL?) {
26 guard let url else { return }
27 for screen in NSScreen.screens {
28 try? workspace.setDesktopImageURL(url, for: screen, options: [:])
29 }
30}
31
32func advance() {
33 let imgs = images()
34 guard !imgs.isEmpty else { return }
35 let pool = imgs.count > 1 ? imgs.filter { $0 != current } : imgs
36 current = pool.randomElement()
37 apply(current)
38}
39
40// Whenever you switch Space, repaint it to the current image.
41workspace.notificationCenter.addObserver(
42 forName: NSWorkspace.activeSpaceDidChangeNotification,
43 object: nil, queue: .main
44) { _ in apply(current) }
45
46advance()
47Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { _ in advance() }
48
49let app = NSApplication.shared
50app.setActivationPolicy(.accessory) // no Dock icon
51app.run()