Python Script to Change OS X Desktop Backgrounds

22:42 Mon 29 Jun 2009
[, , ]

OS X has built-in functionality to rotate between different desktop backgrounds, but if you have multiple monitors and want backgrounds that fit together (i.e. that have two halves, one on each monitor), you need to set that manually. I wanted a script to do this for me, selecting a pair of backgrounds for each day. I wrote one in AppleScript, but was so unimpressed by it that I decided I’d do it over in Python.

To do this, I needed the py-appscript module from the appscript project, which provides OS X bindings for Python, Ruby, and Objective-C.

Once that was installed, it wasn’t too tough to write the script I wanted:

#!/usr/bin/env python

#Relies on py-appscript from http://appscript.sourceforge.net/
from appscript import *

import datetime

weekday = datetime.date.today().weekday()

#Set the directory for the desktop backgrounds:
bg_dir = "/Users/tadhg/subversion/graphics/misc/re-echo_backgrounds/weekdays/"

#Set the images for each day of the week:
img_list = [
    {"l":"vico_road_summer_rock-left.jpg", "r":"vico_road_summer_rock-right.jpg"},
    {"l":"01852_dublindocklandsreflections_left.jpg", "r":"01852_dublindocklandsreflections_right.jpg"},
    #{"l":"mandolux-oldfs-l-1920.jpg", "r":"mandolux-oldfs-r-1440.jpg"},
    {"l":"point_lobos2_left.jpg", "r":"point_lobos2_right.jpg"},
    {"l":"mandolux-slowness-l-1920.jpg", "r":"mandolux-slowness-r-1440.jpg"},
    {"l":"foggygg-left.jpg", "r":"foggygg-right.jpg"},
    {"l":"muir_woods_river_left.jpg", "r":"muir_woods_river_right.jpg"},
    {"l":"vico_road_dart_left.jpg", "r":"vico_road_dart_right.jpg"}

#Convenience variables for left and right pictures:
l,r = "%s%s" % (bg_dir, img_list[weekday]["l"]), "%s%s" % (bg_dir, img_list[weekday]["r"])

#This is how to get the monitor display names:
#display_names = app("System Events").desktops.display_name.get()
#Left monitor:
app("System Events").desktops[its.display_name == "DELL 2407WFP"].picture.set(l)
#Right monitor:
app("System Events").desktops[its.display_name == "Color LCD"].picture.set(r)

The trickiest part of this was the last few lines. Getting the references to a specific desktop in the desktops array was far more difficult than I had expected—I thought first that app("System Events").desktops[0] would work, and then that app("System Events").desktops["DELL 2407WFP"] would. Neither did, and it took me quite some time, with some help from Seth, to find the bizarre its.display_name == syntax.

Leave a Reply