KISS

Keep It Simple Stupid

Disable desktop images usage in XScreenSaver on OSX

| comments

I have previously written about XScreenSaver and selecting a random screensaver among the dozens of the great ones in the package: “OS X: flexible random screensavers”.

Some of the screensavers can display images and the default there is to use the screenshot of the current desktop; it is a sensible default, however I don’t like this mini-leakage of information. Each screensaver has a settings dialog (at least, on OS X) and you can disable the “Grab desktop images” option, enable the “Choose random images” option instead and pick a directory, such as /Library/Desktop Pictures. The problem here is that there are more than a dozen of such screensavers, I don’t know which ones, and I don’t feel like going through a hundred settings dialogs manually at all. We’ll use the terminal instead!

Locating the screensaver’s config

I changed the settings of the DecayScreen screensaver to find where the config is stored:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ find Library .config .local -iname '*decayscreen*'
Library/Preferences/ByHost/org.jwz.xscreensaver.DecayScreen.11111111-B8B2-5C5A-93B1-ABCDABCDABCD.plist
Library/Screen Savers/DecayScreen.saver
Library/Screen Savers/DecayScreen.saver/Contents/MacOS/DecayScreen
Library/Screen Savers/DecayScreen.saver/Contents/Resources/decayscreen.xml

$ cd Library/Preferences/ByHost
$ plutil -convert xml1 -o - org.jwz.xscreensaver.DecayScreen.11111111-B8B2-5C5A-93B1-ABCDABCDABCD.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>chooseRandomImages</key>
        <true/>
        <key>grabDesktopImages</key>
        <false/>
        <key>imageDirectory</key>
        <string>~/Pictures</string>
</dict>
</plist>

Here are the keys!

Thinking of a plan

So we now know what to do: add those three keys to the screensavers’ preferences. What are the filenames? They consist of the screensaver’s bundle identifier and the host’s UUID:

1
2
$ ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ && gsub("\"", "") { print $3 }'
11111111-B8B2-5C5A-93B1-ABCDABCDABCD

We can get the bundle identifiers from the packages’ information files: ~/Library/Screen\ Savers/*.saver/Contents/Info.plist.

Not all the screensavers support these options, but the binaries of those that do not still have the keys, and I couldn’t find an easy way to distinguish them:

1
2
3
4
$ rg --binary grabDesktopImages ~/Library/Screen\ Savers/BSOD.saver/Contents/MacOS/BSOD
Binary file matches (found "\u{0}" byte around offset 5)
$ rg --binary grabDesktopImages ~/Library/Screen\ Savers/Braid.saver/Contents/MacOS/Braid
Binary file matches (found "\u{0}" byte around offset 5)

I suppose it should be fine to add them to all the configs.

Now there might be some settings already set, so adding the keys may fail — that’s fine because then the missing keys will still be added. I’ve tested that adding the keys to the screensavers which don’t support them doesn’t break them, new settings will be appended and saved in the config. Note: there is some delay between updating the config files and seeing the changes in the preferences dialog.

The command

Given all that, my final recipe to disable grabbing the desktop images is:

1
2
3
$ cd ~/Library/Preferences/ByHost
$ host_uuid="$( ioreg -rd1 -c IOPlatformExpertDevice | awk '/IOPlatformUUID/ && gsub("\"", "") { print $3 }' )"
$ for f in ~/Library/Screen\ Savers/*.saver; do /usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$f/Contents/Info.plist"; done | fgrep 'org.jwz.xscreensaver.' | xargs -n1 -I{} /usr/libexec/PlistBuddy -c 'Add :chooseRandomImages bool true' -c 'Add :imageDirectory string "/Library/Desktop Pictures"' -c 'Add :grabDesktopImages bool false' {}."$host_uuid".plist

It iterates over all the locally-installed screensavers in ~/Library/Screen\ Savers, retrieves their bundle identifiers, filters out those not related to XScreenSaver, for each one of those calls the PlistBuddy to add the three known keys. It may warn about missing files and already existing entries, but in the end you should have a bunch of new configs, each of which doing what we wanted from the beginning.

ps. When a new version of XScreenSaver brings new screensavers, it should be safe to rerun this command again to apply the settings to the new ones too.

Comments