This one isn’t from me, but it’s something I had looked for in the past. I’m happy to see that someone got it.
Fast User Switching has a lot of benefits, but one of its downsides is that it is easy to end up with multiple users in the background wasting system resources and needlessly degrading performance. This hint shows how to implement a system to log out users automatically if they have been sent to the background for a specified period of time.
In order to keep the benefits of Fast User Switching while avoiding the situation where multiple users remain logged in unnecessarily, it is necessary to have a way to cause users to log out automatically after being in the background for a period of time. Unfortunately, Mac OS X does not provide a way to do this. (There is a setting in the Security preference pane for logging out automatically after a certain amount of idle time, but it logs out all users and only does so when no one uses the computer for the specified period of time; so long as anyone is using the computer, all background users stay logged in.)
My solution is to use launchd to make each user keep track of whether they are in the background or not, and to log out if they have been in the background for a while. To do this, save the following as a file namedcom.yourname.backgroundUserLogout.plist in the LauchAgents folder of each user’s Library folder:<?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>Label </key> <string>com.yourname.backgroundUserLogout </string> <key>ProgramArguments </key> <array> <string>/bin/bash </string> <string>-c </string> <string>if [ $(stat -f %u /dev/console) == $UID ]; then if [ -e /tmp/backgroundUserLogout.$UID ]; then rm /tmp/backgroundUserLogout.$UID; fi; elif [ ! -e /tmp/backgroundUserLogout.$UID ]; then touch /tmp/backgroundUserLogout.$UID; elif [ $(( `date +%s` - `stat -f %m /tmp/backgroundUserLogout.$UID || printf 0` )) -ge $(( 60 * 30 )) ]; then rm /tmp/backgroundUserLogout.$UID; osascript -e 'tell application "System Events" to log out'; fi </string> </array> <key>RunAtLoad </key> <true/> <key>StartInterval </key> <integer>60 </integer> </dict> </plist>
This launch agent first checks to see whether the user owns the console device (that is, whether it has control of the GUI), and if not it keeps track of how long this has been the case by using a temporary file. Once the user has been in the background for 30 minutes (in the example code above), the launch agent will automatically send the signal to log the user out. Of course, if the user has unsaved documents, the log out will be aborted.
To use a different number of minutes to wait, simply find the part in the launch agent’s code that says $(( 60 * 30 )) and replace the 30 with another number of your choosing. If you have any users that should never be automatically logged out (for example, a user whose job is to serve up the communal iTunes library), simply don’t create this launch agent in their Library.