Session Management

The term session refers to a snapshot of the state of a user's desktop: what applications are open, where their windows are located, what windows each application has open, what size those windows are, what documents are open, current cursor position, and so on. Users should be able to save their session before logging out, and have it automatically restored as closely as possible next time they log in. For this to work, applications must cooperate by having the ability to record and restore those aspects of their state not controlled by the window manager.

A special program called the session manager notifies applications when they should save their state. The Gnome desktop environment comes with a session manager called gnome-session, but Gnome uses the X session management specification, which is several years old. CDE uses the same specification, and at press time, KDE was planning to adopt it as well; an application that implements session management via the Gnome interfaces should work on any session-managed desktop. Gnome does implement some extensions to the basic specification (notably, startup "priorities") but these should not break other session managers and will likely be implemented in KDE as well.

It's worthwhile to read the session management documentation that comes with X; it's a good introduction to what's going on "behind the scenes." The Gnome libraries also come with a useful document, called session-management.txt; have a look at it, and the heavily-commented gnome-client.h header file, for additional details not covered in this section.

Using the GnomeClient Object

Gnome shields you from the raw session management interface that comes with X. This is done via a GtkObject called GnomeClient. GnomeClient represents your application's connection to the session manager.

Gnome manages most of the details of session management. For most applications, you only have to respond to two requests.

When the session manager requests action from your application, a the GnomeClient object emits an appropriate signal. The two important signals are "save_yourself" and "die". "save_yourself" is emitted when an application should save its state, and "die" is emitted when an application should exit. A "save_yourself" callback is fairly complex and has quite a few arguments; a "die" callback is trivial.

GnomeHello obtains a pointer to the GnomeClient object and connects to its signals as follows:


  client = gnome_master_client ();
  gtk_signal_connect (GTK_OBJECT (client), "save_yourself",
                      GTK_SIGNAL_FUNC (save_session), argv[0]);
  gtk_signal_connect (GTK_OBJECT (client), "die",
                      GTK_SIGNAL_FUNC (session_die), NULL);


argv[0] will be used in the "save_yourself" callback.

First, here's the "die" callback from GnomeHello:


static void
session_die(GnomeClient* client, gpointer client_data)
{
  gtk_main_quit ();
}


Straightforward; the application just exits.

Now the "save_yourself" callback:


static gint
save_session (GnomeClient *client, gint phase, GnomeSaveStyle save_style,
              gint is_shutdown, GnomeInteractStyle interact_style,
              gint is_fast, gpointer client_data)
{
  gchar** argv;
  guint argc;

  /* allocate 0-filled, so it will be NULL-terminated */
  argv = g_malloc0(sizeof(gchar*)*4);
  argc = 1;

  argv[0] = client_data;

  if (message)
    {
      argv[1] = "--message";
      argv[2] = message;
      argc = 3;
    }
  
  gnome_client_set_clone_command (client, argc, argv);
  gnome_client_set_restart_command (client, argc, argv);

  return TRUE;
}


This is a bit more complex. A "save_yourself" must tell the session manager how to restart and "clone" (create a new instance of) the application. The restarted application should remember as much state as possible; in GnomeHello's case, it will remember the message being displayed. The simplest way to store application state is to generate a command line, as GnomeHello does. It's also possible to ask GnomeClient for a prefix to be used with the gnome-config API; you can then save information to a per-session configuration file. Applications with significant state will need to use this method.