Custom Screensavers in Sonoma

Rich_C
New Contributor III

Previously the script below from another message made it possible to have custom screensaver files (Photos) that would rotate.  This no longer works in macOS Sonoma.  Does anyone know a new method to have the screensaver call photos from a particular folder in somona via a script or another way.


#!/bin/sh

## get current user
user=`ls -l /dev/console | cut -d " " -f 4`

## get macOS version(s)
osMajor=$(/usr/bin/sw_vers -productVersion | /usr/bin/awk -F"." '{print $2}')
osMinor=$(/usr/bin/sw_vers -productVersion | /usr/bin/awk -F"." '{print $3}')

## set key items for screensaver
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.screensaver CleanExit -string "YES"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.screensaver PrefsVersion -int 100
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.screensaver showClock -string "NO"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.screensaver idleTime -int 60

## configure screensaver framework based on macOS version
if [[ $osMajor -eq 14 ]] && [[ $osMinor -ge 2 ]]; then
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex" type -int 0
else
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/Frameworks/ScreenSaver.framework/Resources/iLifeSlideshows.saver" type -int 0
fi

## additional configuration settings for screensaver framework
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.screensaver tokenRemovalAction -int 0
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.ScreenSaverPhotoChooser LastViewedPhotoPath -string ""
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath -string "/Users/Shared/Screensaver"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 3
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.ScreenSaverPhotoChooser ShufflesPhotos -bool "false"
/usr/bin/sudo -u $user /usr/bin/defaults -currentHost write com.apple.ScreenSaver.iLifeSlideShows styleKey -string "Classic"
/usr/bin/sudo /usr/bin/killall -hup cfprefsd
exit 0

1 ACCEPTED SOLUTION

howie_isaacks
Valued Contributor II

This one has been a real butt kicker. Using the scripts found here: https://github.com/itjimbo/macOS-Screen-Saver-and-Wallpaper I created a workflow that we have been able to use to set our screen saver to some images that run as a slideshow. We distribute the new screen saver assets using a package, which deploys the images to /Library/Screen Savers/Default Collections/ScreenSaver. The scripts from itjimbo work pretty well but I noticed that there was one key piece of information that appeared to be left out of the setup process. That was the path to the screen saver assets. Oddly, just using the script called "Set Screen Saver and Keep User's Wallpaper" after running the first script to get the base64 encoded in the plist file at ~/Library/Application Support/com.apple.wallpaper/Store/Index.plist and adding the base64 to the second script, it worked, but on some computers the screen saver would switch to just a series of colors. These colors are from the png files located at /System/Library/Screen Savers/Default Collections. It seems that macOS will just revert to this default location if it doesn't know where to look for images. I took our working script that we used with macOS Ventura and changed the path to the iLifeSlideshows component from /System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex to /System/Library/ExtensionKit/Extensions/iLifeSlideshows.appex. The old script also had steps to write the key preferences we needed including the path to the screen saver assets. So far, the combination of the "Set Screen Saver and Keep User's Wallpaper" running first then our original script modified to work with Sonoma appears to be working. I'm sure it won't be 100% glitch free but after some tweaking, I think we may have our solution.

View solution in original post

46 REPLIES 46

tkimpton
Valued Contributor II

Thanks Marc works great for setting both. Is there a way to only just set the screensaver? We have corporate marketing just wishing to change screensavers now and again and users go mental about faffing with their wallpaper.

howie_isaacks
Valued Contributor II

The solution from Mac Admins that @mattcherson posted has been working for me, but some of my test users have reported either no change in screen saver behavior, and I also noticed on my own MacBook Pro that the wallpaper was reset to the default for Sonoma. I used the version of the script that preserves the user's wallpaper setting. At my company the communications team creates several images that we deploy using a package to /Library/Screen Savers/Default Collections/FolderName (where "FolderName" is the name of the folder containing the images"). I keep thinking that Apple really doesn't want us to change screen saver behavior with a script and they keep mucking up our processes just for fun. I did also notice that our process we still use for macOS Ventura doesn't work either on occasion even though the policy log shows no errors, and simply re-running the policy solves the issue.

howie_isaacks
Valued Contributor II

This one has been a real butt kicker. Using the scripts found here: https://github.com/itjimbo/macOS-Screen-Saver-and-Wallpaper I created a workflow that we have been able to use to set our screen saver to some images that run as a slideshow. We distribute the new screen saver assets using a package, which deploys the images to /Library/Screen Savers/Default Collections/ScreenSaver. The scripts from itjimbo work pretty well but I noticed that there was one key piece of information that appeared to be left out of the setup process. That was the path to the screen saver assets. Oddly, just using the script called "Set Screen Saver and Keep User's Wallpaper" after running the first script to get the base64 encoded in the plist file at ~/Library/Application Support/com.apple.wallpaper/Store/Index.plist and adding the base64 to the second script, it worked, but on some computers the screen saver would switch to just a series of colors. These colors are from the png files located at /System/Library/Screen Savers/Default Collections. It seems that macOS will just revert to this default location if it doesn't know where to look for images. I took our working script that we used with macOS Ventura and changed the path to the iLifeSlideshows component from /System/Library/Frameworks/ScreenSaver.framework/PlugIns/iLifeSlideshows.appex to /System/Library/ExtensionKit/Extensions/iLifeSlideshows.appex. The old script also had steps to write the key preferences we needed including the path to the screen saver assets. So far, the combination of the "Set Screen Saver and Keep User's Wallpaper" running first then our original script modified to work with Sonoma appears to be working. I'm sure it won't be 100% glitch free but after some tweaking, I think we may have our solution.

Here's my "step 2" script in case anyone needs it. It's a modification of the script written by the person who held my position before I started my job last year. If you have suggestions for improvement I would love to hear them! I had to make changes to the defaults write commands to work better running them as the current user.

#!/bin/bash

###########################
# Configures key user preferences for screen savers - run as step 2 to
# https://github.com/itjimbo/macOS-Screen-Saver-and-Wallpaper/blob/main/Set%20Screen%20Saver%20and%20Keep%20User's%20Wallpaper.sh
# Screen saver asset path is defined on line 31 but you could probably make this a parameter.
# 2/9/24 | Howie Isaacks
###########################

## Get current user
current_user=$(/usr/sbin/scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }')
current_user_id=$(/usr/bin/id -u "$current_user")

echo "Current user is "$current_user""
echo "Current user ID is "$current_user_id""

## Set key values for screen saver
echo "Setting key values for screen saver"
sudo -u "$current_user" /usr/bin/defaults -currentHost write com.apple.screensaver CleanExit -string "YES"
sudo -u "$current_user" /usr/bin/defaults -currentHost write com.apple.screensaver PrefsVersion -int 100
sudo -u "$current_user" /usr/bin/defaults -currentHost write com.apple.screensaver showClock -string "NO"
sudo -u "$current_user" /usr/bin/defaults -currentHost write com.apple.screensaver idleTime -int 1200

## Configure screen saver framework
echo "configuring screen saver framework"
sudo -u "$current_user" /usr/bin/defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName -string "iLifeSlideshows" path -string "/System/Library/ExtensionKit/Extensions/iLifeSlideshows.appex" type -int 0

## Additional configuration settings for screen saver framework
echo "configuring screen saver settings"
sudo -u "$current_user" defaults -currentHost write com.apple.screensaver tokenRemovalAction -int 0
echo "setting asset path"
sudo -u "$current_user" defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedFolderPath -string "/Library/Screen Savers/Default Collections/ScreenSaver/"
sudo -u "$current_user" defaults -currentHost write com.apple.ScreenSaverPhotoChooser SelectedSource -int 3
sudo -u "$current_user" defaults -currentHost write com.apple.ScreenSaverPhotoChooser ShufflesPhotos -bool "true"
sudo -u "$current_user" defaults -currentHost write com.apple.ScreenSaver.iLifeSlideShows styleKey -string "Classic"

## Reset
echo "relaunching prefsd..."
/usr/bin/killall -hup cfprefsd

echo "$(date) - Restarting wallpaper agent..."
killall WallpaperAgent

 

In the script above, I added another "killall WallpaperAgent". This is done in the first script. I added it to the second because I was noticing some behavior that I thought another relaunch would fix. If you use this script, remove or comment out that step. I don't think it's actually needed.

ITMan
New Contributor II

I have the following problem. If a user manually changed the screensaver path to the images folder, for example. /Users/user/Pictures
After running the script, this path is not changed.
How to fix the situation so that the screensaver path is accepted?

howie_isaacks
Valued Contributor II

Which plist are you looking at? The settings are all in plists in ~/Library/Preferences/ByHost.

com.apple.ScreenSaverPhotoChooser is the plist where the path to the images would be.

On my test Mac, I went into System Settings - Screen Saver and selected my Documents folder as the folder for images. I checked the plist above and I saw that choice show up as the string for "SelectedFolderPath". I then ran my script that I posted above that contains the path we want to use for our images and it changed the string for "SelectedFolderPath" to the correct path. I used a hot corner to test the screen saver and it worked as intended. I need to know your whole process to understand why this isn't working right.