See also http://live.gnome.org/SessionManagement/NewGnomeSession

Startup
-------

main() creates the CsmSession object representing the session (either
failsafe or normal). csm_session_new() reads the appropriate autostart
and session files to create a list of CsmApps to be started.
(CsmAppAutostart represents an autostarted app, and CsmAppResumed
represents an app resumed from the previous saved session.)

Startup is divided into 6 phases (CsmSessionPhase):

    * CSM_SESSION_PHASE_STARTUP covers cinnamon-session's internal
      startup, which also includes starting gconfd and dbus-daemon (if
      it's not already running). Gnome-session starts up those
      explicitly because it needs them for its own purposes.

    * CSM_SESSION_PHASE_INITIALIZATION is the first phase of "normal"
      startup (ie, startup controlled by .desktop files rather than
      hardcoding). It covers low-level stuff like
      gnome-settings-daemon and at-spi-registryd, that need to be
      running very early (before any windows are displayed).

      Apps in this phase can make use of a D-Bus interface
      (org.gnome.SessionManager.Setenv) to set environment variables
      in cinnamon-session's environment. This can be used for things like
      $GTK_MODULES, $GNOME_KEYRING_SOCKET, etc

    * CSM_SESSION_PHASE_WINDOW_MANAGER includes window managers and
      compositing managers, and anything else that has to be running
      before any windows are mapped

    * CSM_SESSION_PHASE_PANEL includes anything that permanently takes
      up screen real estate (via EWMH struts). This is the first phase
      where things actually appear on the screen.

    * CSM_SESSION_PHASE_DESKTOP includes anything that draws directly
      on the desktop (eg, nautilus).

    * CSM_SESSION_PHASE_APPLICATION is everything else (normal apps,
      tray icons, etc)

For each startup phase, CsmSession launches the appropriate CsmApps.
When apps connect to the XSMP or D-Bus servers, CsmClients are created
and added to the session. The session tries to map these clients to
CsmApps. CsmApps signal when they register (via XSMP or SN) or exit,
and CsmSession uses this to decide when the phase is complete.

FIXME: after starting the session, we need to run the DiscardCommands
of resumed apps.


Running/Shutdown
----------------

CSM_SESSION_PHASE_RUNNING is pretty similar to the old cinnamon-session;
mostly it just tracks XSMP clients, and watches for
SmRestartImmediately clients exiting (NOTE: THIS DOESN'T HAPPEN YET).

CsmClient is in theory not XSMP-specific, but it's very very
XSMP-like, and the shutdown procedure is also very XSMP-like. This is
just because there's no way to do XSMP shutdown correctly otherwise.
However, CsmClientDBus will still be able to present a more sane
protocol to its clients than CsmClient presents to it.
