Wednesday, July 15, 2015

Photo slide show screensaver on Mac - network share and Yosemite's reversion to default. A workaround.

I have never been happy with how OS X handles anything to do with file shares, I think Windows does a much better job.

Which, if you know anything about Windows network services, must mean I’m a raving loon. How could OS X be worse than that?

I can’t explain it. My experience is that, for no good reason, when requesting a file or folder from an OS X server, things often fail. Disabling sleep and hard drive rest helps. [4]

So it’s not surprising that using a server based photo collection with the OS X Photo Slideshow screensaver has always been problematic. I’ve really only had good success with local stores, or using local Aperture or iPhoto as the source.  I assume something hangs and OS X switches to the default photo slideshow (national geographic) screensaver, losing all memory of the screensaver you want to use.

This isn’t new, but with Yosemite it’s seems to have gotten worse [1].  Every time I opened my brand new MacBook Air on 10.10.4 I was back to National Geographic. Which is pretty, but I’ve come to hate it.

Happily, this problem is aggravating enough that there’s now a fix, which is best described in an AskDifferent post by “Flavin” (he found bug in 10.10.1, he both asks questions and answers it. I love when people return to add their answers.) The process goes like this:

  1. Set up your screensaver as desired.
  2. Run a terminal command to see the preference file values:
    defaults -currentHost read com.apple.ScreenSaverPhotoChooser
  3. Copy values into a script to write them back, where script is of the form
    defaults -currentHost write com.apple.ScreenSaverPhotoChooser … 

This is what my script looked like based on Flavi (emphases mine):

#!/bin/bash
defaults -currentHost write com.apple.ScreenSaverPhotoChooser CustomFolderDict -dict identifier \"/Volumes/ss/ss\" name ss
defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath \"/Volumes/ss/ss\"
defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 4
defaults -currentHost write com.apple.ScreenSaverPhotoChooser ShufflesPhotos -bool true

My images are in a network share /ss/ss [2]. Note in a Bash script like this quotes are escaped with slashes, hence \” to contain the string.

At this point I had the fix, but I got stuck with following the usual practice of storing it in OS X’s hidden unix file structure. TextWrangler wouldn’t show them to me [3]. So instead I put the script into a standard OS X Folder (Documents\Bash is my name) and used my favorite tip of the year: How to run a Unix shell script from the Mac Finder | alvinalexander.com. I changed the .sh extension to .command and now it’s double-clickable. No need to wrap it in AppleScript or death with BSD Unix PATH, etc.

THEN I discovered my script only worked when the remote network share was mounted. If it wasn’t mounted OS X wouldn’t mount it for me; the script would run as above but OS would fail to find the volume (“ss”) and would return to the dreaded Nat Geo. So I revised the script to mount as needed (I had a devil of a time getting mount_afp working because I didn’t understand I had to create a directory first in Volumes to be the mount point/node), and I added code to set Screensaver to Photo Slideshow borrowed from another reference.

#!/bin/bash

## Mount remote volume if not already mounted
if [ ! -d /Volumes/ss ]; then
mkdir /Volumes/ss
mount_afp afp://Thunderpaws._afpovertcp._tcp.local/ss /Volumes/ss
fi

## Set Screensaver to Photo Slideshow
/usr/bin/defaults -currentHost write com.apple.screensaver 'CleanExit' -string "YES"
/usr/bin/defaults -currentHost write com.apple.screensaver 'PrefsVersion' -int "100"
/usr/bin/defaults -currentHost write com.apple.screensaver 'idleTime' -int "300"
/usr/bin/defaults -currentHost write com.apple.screensaver "moduleDict" -dict-add "path" -string "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver"
/usr/bin/defaults -currentHost write com.apple.screensaver "moduleDict" -dict-add "type" -int "0"
/usr/bin/defaults -currentHost write com.apple.screensaver 'ShowClock' -bool "false"
/usr/bin/defaults -currentHost write com.apple.screensaver 'tokenRemovalAction' -int "0"

## Set location of photos
defaults -currentHost write com.apple.ScreenSaverPhotoChooser CustomFolderDict -dict identifier \"/Volumes/ss/ss\" name ss
defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath \"/Volumes/ss/ss\"
defaults -currentHost write com.apple.ScreenSaverPhotoChooser LastViewedPhotoPath \"\"
defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 4
defaults -currentHost write com.apple.ScreenSaverPhotoChooser ShufflesPhotos -bool true

## Removes the .plist LaunchAgent from inside the User Launch Agent Folder.
## rm -f ~/Library/LaunchAgents/set-screensaver.plist
## killall cfprefsd

exit

Eventually I may take app.net@jws’s advice and use Watchman to fully automate a fix, but I kind of like firing this script off every time Yosemite zaps my slideshow of 100 years of family pictures.

- fn -

[1] Maybe related to this Mavericks change? It’s not the only thing that’s gotten worse over the past 1-2 years of course. My current explanation for the Hot Mess that is Apple software 2015 is that during the Jobs era and shortly thereafter Apple incurred massive technical debt and they are slowly and painfully trying to fix it, while shedding expertise like water off the proverbial duck’s back. An even more worrisome possibility is that Apple is now a typical corporation.

[2] Why the redundant ss? Historic reasons. The network share is a thumb drive sticking out of the back of a Time Capsule, so there’s no authentication needed.

To get the path of a folder just drag the finder icon into Terminal and the path will render.

[3] I’ve run into this before I think, but I can’t remember if there’s a setting I’ve missed or … what. Maybe it’s a BBEdit only feature, but it doesn’t show up in the TextWranger vs. Bbedit comparison page. Google was no help at all.

[4] I wonder if it’s because OS X often stores references to “mount points” (Volumes/…) but mount points have to be associated with network addresses, and those are not stored. Note my script should really check for the network access, not the existence of the Mount directory, but I don’t yet know how to do the former.

References

 

No comments: