modules/darwin/random-wallpaper/wallpaper-daemon.swift
181f59e7219fa3cfed36c05773ac6a8dc40e5571
· 1.5 KB · 51 lines
raw
| 1 | import AppKit |
| 2 | import Foundation |
| 3 | |
| 4 | if CommandLine.arguments.count != 3 { |
| 5 | print("Must have 2 args") |
| 6 | exit(1) |
| 7 | } |
| 8 | |
| 9 | let wallpaperDir = CommandLine.arguments[1] |
| 10 | let interval: TimeInterval = Double(CommandLine.arguments[2]) ?? 30.0 |
| 11 | |
| 12 | let workspace = NSWorkspace.shared |
| 13 | let imageExtensions: Set<String> = ["jpg", "jpeg", "png", "heic", "tiff", "gif", "bmp"] |
| 14 | |
| 15 | func 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 | |
| 22 | var current: URL? |
| 23 | |
| 24 | // setDesktopImageURL only touches the current Space (all displays). |
| 25 | func 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 | |
| 32 | func 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. |
| 41 | workspace.notificationCenter.addObserver( |
| 42 | forName: NSWorkspace.activeSpaceDidChangeNotification, |
| 43 | object: nil, queue: .main |
| 44 | ) { _ in apply(current) } |
| 45 | |
| 46 | advance() |
| 47 | Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { _ in advance() } |
| 48 | |
| 49 | let app = NSApplication.shared |
| 50 | app.setActivationPolicy(.accessory) // no Dock icon |
| 51 | app.run() |