How would I go about programmatically changing the desktop background in Mac OS X? I’d like to use python, but I’m interested in any way possible. Could I hook up to Terminal and call a certain command?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
From python, if you have appscript installed (sudo easy_install appscript), you can simply do
from appscript import app, mactypes
app('Finder').desktop_picture.set(mactypes.File('/your/filename.jpg'))
Otherwise, this applescript will change the desktop background
tell application "Finder"
set desktop picture to POSIX file "/your/filename.jpg"
end tell
You can run it from the command line using osascript, or from Python using something like
import subprocess
SCRIPT = """/usr/bin/osascript<<END
tell application "Finder"
set desktop picture to POSIX file "%s"
end tell
END"""
def set_desktop_background(filename):
subprocess.Popen(SCRIPT%filename, shell=True)
Method 2
If you are doing this for the current user, you can run, from a shell:
defaults write com.apple.desktop Background '{default = {ImageFilePath = "/Library/Desktop Pictures/Black & White/Lightning.jpg"; };}'
Or, as root, for another user:
/usr/bin/defaults write /Users/joeuser/Library/Preferences/com.apple.desktop Background '{default = {ImageFilePath = "/Library/Desktop Pictures/Black & White/Lightning.jpg"; };}'
chown joeuser /Users/joeuser/Library/Preferences/com.apple.desktop.plist
You will of course want to replace the image filename and user name.
The new setting will take effect when the Dock starts up — either at login, or, when you
killall Dock
[Based on a posting elsewhere, and based on information from Matt Miller’s answer.]
Method 3
I had this same question, except that I wanted to change the wallpaper on all attached monitors. Here’s a Python script using appscript (mentioned above; sudo easy_install appscript) which does just that.
#!/usr/bin/python
from appscript import *
import argparse
def __main__():
parser = argparse.ArgumentParser(description='Set desktop wallpaper.')
parser.add_argument('file', type=file, help='File to use as wallpaper.')
args = parser.parse_args()
f = args.file
se = app('System Events')
desktops = se.desktops.display_name.get()
for d in desktops:
desk = se.desktops[its.display_name == d]
desk.picture.set(mactypes.File(f.name))
__main__()
Method 4
Building on dF.’s answer, you could do it with Apple Script without Finder and you can do it for multiple desktops.
To set the wallpaper for desktop i (desktop numbers start at 1):
tell application "System Events"
set currDesktop to item i of desktop
set currDesktop's picture to "image_path"
end tell
This is what I ended up doing (in Python):
SET_DESKTOP_IMAGE_WRAPPER = """/usr/bin/osascript<<END
tell application "System Events"
{}
end tell
END"""
SET_DESKTOP_IMAGE = """
set currDesktop to item {idx} of desktops
set currDesktop's picture to "{image_path}"
"""
def set_wallpapers(images):
""" images is an array of file paths of desktops """
script_contents = ""
for i, img in enumerate(images):
idx = i+1
script_contents += SET_DESKTOP_IMAGE.format(idx=idx, image_path=img)
script = SET_DESKTOP_IMAGE_WRAPPER.format(script_contents)
subprocess.check_call(script, shell=True)
Sometimes, the desktop images don’t appear immediately. I don’t know why this happens, but restarting the dock fixes it.
To do that from python:
subprocess.check_call("killall Dock", shell=True)
By the way, you can get the number of desktops on the system using this AppleScript code:
tell application "System Events"
get the number of desktops
end tell
you can use that with subprocess.check_output to get the output
Method 5
You can call “defaults write com.apple.Desktop Background …” as described in this article: http://thingsthatwork.net/index.php/2008/02/07/fun-with-os-x-defaults-and-launchd/
The article also goes into scripting this to run automatically, but the first little bit should get you started.
You might also be interested in the defaults man pages: http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/defaults.1.html
Method 6
The one-line solution for Mavericks is:
osascript -e 'tell application "Finder" to set desktop picture to POSIX file "/Library/Desktop Pictures/Earth Horizon.jpg"'
Method 7
Put the following in your ~/.bashrc
function wallpaper() {
wallpaper_script="tell application "Finder" to set desktop picture to POSIX file "$HOME/$1""
osascript -e $wallpaper_script
}
Use like so:
wallpaper /path/to/image.png
Method 8
To add to Matt Miller’s response: you can use subprocess.call() to execute a shell command as so:
import subprocess subprocess.call(["defaults", "write", "com.apple.Desktop", "background", ...])
Method 9
There are a default collection of quality images in:
/Library/Desktop Pictures/
To automate the selection of one of these across all desktops, without a 3rd party dependency:
osascript -e 'tell application "System Events" to set picture of every desktop to "/Library/Desktop Pictures/Solid Colors/Stone.png"'
Method 10
You can do this without killall Dock by running a Swift script from your Python script.
Create a chwall.swift file with the following code:
#!/usr/bin/env swift
import Cocoa
do {
// get the main (currently active) screen
if let screen = NSScreen.main {
// get path to wallpaper file from first command line argument
let url = URL(fileURLWithPath: CommandLine.arguments[1])
// set the desktop wallpaper
try NSWorkspace.shared.setDesktopImageURL(url, for: screen, options: [:])
}
} catch {
print(error)
}
Now run the above chwall.swift file with subprocess in Python.
import subprocess
subprocess.run(["./chwall.swift", "/path/to/your/wallpaper/file.png"])
Method 11
You could also use py-appscript instead of Popening osascript or use ScriptingBridge with pyobjc which is included in 10.5 but a bit more cumbersome to use.
Method 12
Another way to programmatically change the desktop wallpaper is to simply point the wallpaper setting at a file. Use your program to overwrite the file with the new design, then restart the dock: killall Dock.
The following depends on Xcode, lynx and wget, but here’s how I automatically download and install a monthly wallpaper on Mountain Lion (shamelessly stolen and adapted from http://ubuntuforums.org/showthread.php?t=1409827) :
#!/bin/bash PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/local/bin size=1440 dest="/usr/local/share/backgrounds/wallpaperEAA.jpg" read -r baseurl < <(lynx -nonumbers -listonly -dump 'http://www.eaa.org/en/eaa/aviation-education-and-resources/airplane-desktop-wallpaper' | grep $size) && wget -q "$baseurl" -O "$dest" killall Dock
Dump it into /etc/periodic/monthly/ and baby, you got a stew goin!
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0