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()