4

I would like to change the wallpaper on ALL desktops including spaces on Mac but without needing to call killall Dock each minute. (Dock restarting forces wallpaper refresh).

I have an AppleScript that changes the desktop wallpaper instantly:

tell application "System Events" to tell every desktop to set picture to wallpaperPath

but that only changes the wallpaper on the active space (meaning that if the main desktop is not active, its background will not change).

I found this question https://stackoverflow.com/questions/36185506/how-to-loop-through-all-mac-desktop-spaces which suggests updating wallpaper path values in the SQLite database located at ~/Library/Application Support/Dock/desktoppicture.db. This changes the wallpaper at every space which is great but it requires restart of the dock using killall Dock which is undesirable as it disrupts the workflow.

My question is - is there some way to combine these two approaches? Seamlessly change wallpapers on every desktop space?

Any suggestions would be appreciated. I have no preferred language, it can be in C, Swift, Python, Bash, AppleScript etc.

4
  • When you say "each minute" - does that mean you want to continually change the desktop at a set interval?
    – benwiggy
    Commented Dec 20, 2021 at 13:19
  • Do not cross post the same question on multiple Stack Exchange sites. You posted the the same question on Stack Overflow yesterday. stackoverflow.com/questions/70412058/… Commented Dec 20, 2021 at 13:21
  • I want to change the desktop wallpaper each whole minute. Commented Jan 7, 2022 at 14:17
  • Yes I asked the question on SO but I only got a downvote and no answer so I figured I will ask it here. Is that a problem? Commented Jan 7, 2022 at 14:18

2 Answers 2

2

I figured it out.

I am looping through all available screens and setting the wallpaper using setDesktopImageURL:forScreen:options:error: (based on Graham Miln's answer):

for screen in NSScreen.screens {
    try! NSWorkspace.shared.setDesktopImageURL(url, for: screen, options: [:])
}

This changes the wallpapers seamlessly, without the need for killall Dock on all the screens but only if the desktop is the active space.

To make sure the wallpaper is changed when I am on another space (usually a fullscreen app), I added an observer for NSWorkspace.activeSpaceDidChangeNotification on the NSWorkspace.shared.notificationCenter which sets the desktop images again (using the code above). So whenever I go back to the desktop, this notification is invoked and the wallpaper is seamlessly updated.

I even went one step further and added the same observer also for the NSWorkspace.didWakeNotification which updates the wallpaper as soon as the device wakes up which is cool!

1

Use NSWorkspace and the setDesktopImageURL:forScreen:options:error: method:

setDesktopImageURL:forScreen:options:error:

Sets the desktop image for the given screen to the image at the specified URL.

This API is accessible through Objective-C and Swift. I presume scripting bridges for python can also access these methods.

See the links below for other approaches using AppleScript:

1
  • Thank you for your suggestions however the above method does not work the way I wanted. It only changes the wallpaper on the screen if I am on the desktop (and not in a fullscreen app in another space). As for the links you provided below - the first one is very obtrusive since it switches between spaces (I want a seamless wallpaper change in the background). The second one is not exactly what you want since it's interval based and I want to be able to change it at any desired time, not necessarily in intervals. Commented Jan 7, 2022 at 14:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .