Is it possible to (programmatically) set wallpapers for each separate "space"/desktop in macOS?

1.7k views Asked by At

I'm making a small app for myself to change the desktop background image periodically.

My program contains this block of code:

let screen = NSScreen.main()!
let newWallpaperURL = URL(/* ... */)
// ...
try! NSWorkspace.shared().setDesktopImageURL(newWallpaperURL, for: screen, options: [:])

This works, but only for the current "space" the keyboard is focused on.

e.g. if I'm in a fullscreen app, only the background of the Space occupied fullscreen app will be changed (not the background of my normal desktop). If I have two Spaces/desktops, it only changes the background image of one of them.

Is it possible to individually set wallpapers for each space programmatically?

2

There are 2 answers

2
Tom E On

Use this in Xcode 8.x:

if let screens = NSScreen.screens() {
    let newWallpaperURL = URL(/* ... */))
    for screen in screens {
        try? NSWorkspace.shared().setDesktopImageURL(newWallpaperURL, for: screen, options: [:])
    }
}

Unlike other solutions posted here this one will work in the current Xcode 8. NSScreen.screens is a class var in Xcode 9 (currently beta) but a class func in Xcode 8 which is why you need to put .screens() instead of .screens. Also, screens returns an optional so you need to safely unwrap it before passing it to the for loop.

2
Papershine On

You can get all the screens and set all of them.

let screens = NSScreen.screens
let newWallpaperURL = URL(/* ... */)
for i in screens {
    try! NSWorkspace.shared().setDesktopImageURL(newWallpaperURL, for: i, options: [:])
}