Fiddling with com.apple.desktop.plist

This plist contains two keys: one of them is a real number, like “69671552”

You can read it like so:

tell application "System Events"
	current desktop --> desktop "69671552" of application "System Events"
end tell

I want to use System Events to modify this key’s value.
To do that I must use the key name as a record property.
Obviously, I can’t use the number as-is - it’s not a legal identifier.

The problem: I can’t coerce that reference to something else, i.e. string “69671552”
Is this doable, or is this a shortcoming of System Events’ AppleScript implementation?
(Yes, must add pipes before using “69671552” as an identifier)

I came up with this workaround:

set plist to do shell script "defaults read com.apple.desktop"
set theKey to word 1 of paragraph 3 of plist-->"69671552"

, which will break the minute Apple decides to change the format of the plist.

First, you don’t want to mess with that key. That key is the monitor ID of your screen. If you have 2 values then you’ve had 2 different monitors connected to your computer at one point and they each have a different ID, so each monitor has different settings. So you’d never want to change the monitor ID because that’s a fixed value. You would want to change the values inside a particular monitor’s settings.

For example, when I look at my plist there’s a value called “ChangeTime” which is a number. If I wanted to change that value I need to know the path to it. ChangeTime is inside “69670848” which is inside “Background”. So knowing that path I can then get the changetime value or set the changetime value like so…

set plistPath to (path to preferences folder from user domain as text) & "com.apple.desktop.plist"

tell application "System Events"
	set thePlist to property list file plistPath
	set value of property list item "ChangeTime" of property list item "69670848" of property list item "Background" of thePlist to 900
end tell

NOTE: regarding the monitor IDs I mentioned you can get the monitor IDs of your screens (so you know which desktop properties to change in that plist) using a command line tool of mine. You can find it on my website here.

Yes, that’s what I want to do.
There’s a key “Placement” that’s ‘controlled’ by a popup “Stretch to fill screen” in the Prefs panel Desktop & Screensaver (only present when you select a picture of your own).
It’s set to “Crop” by default, and I want “FillScreen”.

That snippet of code will do the trick - I wasn’t aware of this syntax.
And the bit about the monitor ID is completely new to me!

Thanks a bunch!

And here’s how it turned out:

-- path string for desired desktop
property desktopPic_path : (POSIX file "/" as text) & "path_to_desired_picture"

-- set the picture using System Events: change is immediate
-- this rewrites the entire plist
tell application "System Events" to set picture of current desktop to desktopPic_path

-- now go read & change the refreshed plist
set plistPath to (path to preferences folder from user domain as text) & "com.apple.desktop.plist"
tell application "System Events"
	set plist to property list file plistPath
	-- get the 2 keys that describe the desktop picture
	set theKeys to name of property list items of property list item "Background" of plist --> {"default", "69671552"}
	-- change one of their keys
	repeat with aKey in theKeys
		set value of property list item "Placement" of property list item aKey of property list item "Background" of plist to "FillScreen"
	end repeat
end tell

There’s a glitch…

When you never changed the desktop, this command

tell application "System Events" to set picture of current desktop to desktopPic_path

will create the plist file, but it will not have the ‘Placement’ key, and setting it with System Events will not work.

To create nonexistent keys you need to use ‘defaults’, or PlistBuddy.