Search code examples
macosapplescript

Seamlessly change all desktop spaces' wallpaper on Mac without killall Dock


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 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.


Solution

  • I figured it out.

    I am looping through all available screens and setting the wallpaper using setDesktopImageURL:forScreen:options:error::

    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!