]> www.fi.muni.cz Git - evince.git/commitdiff
Update smclient from libegg trunk.
authorChristian Persch <chpe@src.gnome.org>
Mon, 27 Oct 2008 12:17:02 +0000 (12:17 +0000)
committerChristian Persch <chpe@src.gnome.org>
Mon, 27 Oct 2008 12:17:02 +0000 (12:17 +0000)
svn path=/trunk/; revision=3239

cut-n-paste/smclient/eggdesktopfile.c
cut-n-paste/smclient/eggdesktopfile.h
cut-n-paste/smclient/eggsmclient-xsmp.c
cut-n-paste/smclient/eggsmclient.c

index ccc908302ad0de009ba4a35afbdc6c634c240cc0..e88930597bf873b50fbab09df36500d467bb4b7f 100644 (file)
@@ -31,9 +31,8 @@
 #include <unistd.h>
 
 #include <glib/gi18n.h>
-#include <gdk/gdk.h>
-#include <gtk/gtkwindow.h>
 #include <gdk/gdkx.h>
+#include <gtk/gtk.h>
 
 struct EggDesktopFile {
   GKeyFile           *key_file;
@@ -56,7 +55,6 @@ struct EggDesktopFile {
 EggDesktopFile *
 egg_desktop_file_new (const char *desktop_file_path, GError **error)
 {
-  EggDesktopFile *desktop_file;
   GKeyFile *key_file;
 
   key_file = g_key_file_new ();
@@ -66,13 +64,8 @@ egg_desktop_file_new (const char *desktop_file_path, GError **error)
       return NULL;
     }
 
-  desktop_file = egg_desktop_file_new_from_key_file (key_file,
-                                                    desktop_file_path,
-                                                    error);
-  if (!desktop_file)
-    g_key_file_free (key_file);
-
-  return desktop_file;
+  return egg_desktop_file_new_from_key_file (key_file, desktop_file_path,
+                                            error);
 }
 
 /**
@@ -106,9 +99,42 @@ egg_desktop_file_new_from_data_dirs (const char  *desktop_file_path,
                                                     full_path,
                                                     error);
   g_free (full_path);
-  if (!desktop_file)
-    g_key_file_free (key_file);
+  return desktop_file;
+}
+
+/**
+ * egg_desktop_file_new_from_dirs:
+ * @desktop_file_path: relative path to a Freedesktop-style Desktop file
+ * @search_dirs: NULL-terminated array of directories to search
+ * @error: error pointer
+ *
+ * Looks for @desktop_file_path in the paths returned from
+ * g_get_user_data_dir() and g_get_system_data_dirs(), and creates
+ * a new #EggDesktopFile from it.
+ *
+ * Return value: the new #EggDesktopFile, or %NULL on error.
+ **/
+EggDesktopFile *
+egg_desktop_file_new_from_dirs (const char  *desktop_file_path,
+                               const char **search_dirs,
+                               GError     **error)
+{
+  EggDesktopFile *desktop_file;
+  GKeyFile *key_file;
+  char *full_path;
+
+  key_file = g_key_file_new ();
+  if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs,
+                                 &full_path, 0, error))
+    {
+      g_key_file_free (key_file);
+      return NULL;
+    }
 
+  desktop_file = egg_desktop_file_new_from_key_file (key_file,
+                                                    full_path,
+                                                    error);
+  g_free (full_path);
   return desktop_file;
 }
 
@@ -119,8 +145,8 @@ egg_desktop_file_new_from_data_dirs (const char  *desktop_file_path,
  * @error: error pointer
  *
  * Creates a new #EggDesktopFile for @key_file. Assumes ownership of
- * @key_file on success (meaning it will be freed when the desktop_file
- * is freed).
+ * @key_file (on success or failure); you should consider @key_file to
+ * be freed after calling this function.
  *
  * Return value: the new #EggDesktopFile, or %NULL on error.
  **/
@@ -137,6 +163,7 @@ egg_desktop_file_new_from_key_file (GKeyFile    *key_file,
       g_set_error (error, EGG_DESKTOP_FILE_ERROR,
                   EGG_DESKTOP_FILE_ERROR_INVALID,
                   _("File is not a valid .desktop file"));
+      g_key_file_free (key_file);
       return NULL;
     }
 
@@ -160,13 +187,14 @@ egg_desktop_file_new_from_key_file (GKeyFile    *key_file,
                       EGG_DESKTOP_FILE_ERROR_INVALID,
                       _("Unrecognized desktop file Version '%s'"), version);
          g_free (version);
+         g_key_file_free (key_file);
          return NULL;
        }
-      else 
       g_free (version);
     }
 
   desktop_file = g_new0 (EggDesktopFile, 1);
+  desktop_file->key_file = key_file;
 
   if (g_path_is_absolute (source))
     desktop_file->source = g_filename_to_uri (source, NULL, NULL);
@@ -202,7 +230,7 @@ egg_desktop_file_new_from_key_file (GKeyFile    *key_file,
       if (!exec)
        {
          egg_desktop_file_free (desktop_file);
-         g_free(type);
+         g_free (type);
          return NULL;
        }
 
@@ -235,7 +263,7 @@ egg_desktop_file_new_from_key_file (GKeyFile    *key_file,
       if (!url)
        {
          egg_desktop_file_free (desktop_file);
-         g_free(type);
+         g_free (type);
          return NULL;
        }
       g_free (url);
@@ -245,7 +273,7 @@ egg_desktop_file_new_from_key_file (GKeyFile    *key_file,
   else
     desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED;
 
-  g_free(type);
+  g_free (type);
 
   /* Check the Icon key */
   desktop_file->icon = g_key_file_get_string (key_file,
@@ -270,7 +298,6 @@ egg_desktop_file_new_from_key_file (GKeyFile    *key_file,
        }
     }
 
-  desktop_file->key_file = key_file;
   return desktop_file;
 }
 
@@ -290,22 +317,6 @@ egg_desktop_file_free (EggDesktopFile *desktop_file)
   g_free (desktop_file);
 }
 
-/**
- * egg_desktop_file_get_key_file:
- * @desktop_file: an #EggDesktopFile
- *
- * Gets the #GKeyFile associated with @desktop_file. You must not free
- * this value, and changes made to it will not be reflected by
- * @desktop_file.
- *
- * Return value: the #GKeyFile associated with @desktop_file.
- **/
-GKeyFile *
-egg_desktop_file_get_key_file (EggDesktopFile *desktop_file)
-{
-  return desktop_file->key_file;
-}
-
 /**
  * egg_desktop_file_get_source:
  * @desktop_file: an #EggDesktopFile
@@ -369,6 +380,81 @@ egg_desktop_file_get_icon (EggDesktopFile *desktop_file)
   return desktop_file->icon;
 }
 
+gboolean
+egg_desktop_file_has_key (EggDesktopFile  *desktop_file,
+                         const char      *key,
+                         GError         **error)
+{
+  return g_key_file_has_key (desktop_file->key_file,
+                            EGG_DESKTOP_FILE_GROUP, key,
+                            error);
+}
+
+char *
+egg_desktop_file_get_string (EggDesktopFile  *desktop_file,
+                            const char      *key,
+                            GError         **error)
+{
+  return g_key_file_get_string (desktop_file->key_file,
+                               EGG_DESKTOP_FILE_GROUP, key,
+                               error);
+}
+
+char *
+egg_desktop_file_get_locale_string (EggDesktopFile  *desktop_file,
+                                   const char      *key,
+                                   const char      *locale,
+                                   GError         **error)
+{
+  return g_key_file_get_locale_string (desktop_file->key_file,
+                                      EGG_DESKTOP_FILE_GROUP, key, locale,
+                                      error);
+}
+
+gboolean
+egg_desktop_file_get_boolean (EggDesktopFile  *desktop_file,
+                             const char      *key,
+                             GError         **error)
+{
+  return g_key_file_get_boolean (desktop_file->key_file,
+                                EGG_DESKTOP_FILE_GROUP, key,
+                                error);
+}
+
+double
+egg_desktop_file_get_numeric (EggDesktopFile  *desktop_file,
+                             const char      *key,
+                             GError         **error)
+{
+  return g_key_file_get_double (desktop_file->key_file,
+                               EGG_DESKTOP_FILE_GROUP, key,
+                               error);
+}
+
+char **
+egg_desktop_file_get_string_list (EggDesktopFile  *desktop_file,
+                                 const char      *key,
+                                 gsize           *length,
+                                 GError         **error)
+{
+  return g_key_file_get_string_list (desktop_file->key_file,
+                                    EGG_DESKTOP_FILE_GROUP, key, length,
+                                    error);
+}
+
+char **
+egg_desktop_file_get_locale_string_list (EggDesktopFile  *desktop_file,
+                                        const char      *key,
+                                        const char      *locale,
+                                        gsize           *length,
+                                        GError         **error)
+{
+  return g_key_file_get_locale_string_list (desktop_file->key_file,
+                                           EGG_DESKTOP_FILE_GROUP, key,
+                                           locale, length,
+                                           error);
+}
+
 /**
  * egg_desktop_file_can_launch:
  * @desktop_file: an #EggDesktopFile
@@ -823,7 +909,7 @@ parse_link (EggDesktopFile  *desktop_file,
   return TRUE;
 }
 
-#ifdef HAVE_GDK_X11_DISPLAY_BROADCAST_STARTUP_MESSAGE
+#if GTK_CHECK_VERSION (2, 12, 0)
 static char *
 start_startup_notification (GdkDisplay     *display,
                            EggDesktopFile *desktop_file,
@@ -934,21 +1020,29 @@ set_startup_notification_timeout (GdkDisplay *display,
   g_timeout_add (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH,
                 startup_notification_timeout, sn_data);
 }
-#endif /* HAVE_GDK_X11_DISPLAY_BROADCAST_STARTUP_MESSAGE */
-
-extern char **environ;
+#endif /* GTK 2.12 */
 
 static GPtrArray *
 array_putenv (GPtrArray *env, char *variable)
 {
-  int i, keylen;
+  guint i, keylen;
 
   if (!env)
     {
+      char **envp;
+
       env = g_ptr_array_new ();
 
-      for (i = 0; environ[i]; i++)
-       g_ptr_array_add (env, g_strdup (environ[i]));
+      envp = g_listenv ();
+      for (i = 0; envp[i]; i++)
+        {
+          const char *value;
+
+          value = g_getenv (envp[i]);
+          g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i],
+                                                 value ? value : ""));
+        }
+      g_strfreev (envp);
     }
 
   keylen = strcspn (variable, "=");
@@ -1113,7 +1207,7 @@ egg_desktop_file_launchv (EggDesktopFile *desktop_file,
        }
       g_free (command);
 
-#ifdef HAVE_GDK_X11_DISPLAY_BROADCAST_STARTUP_MESSAGE
+#if GTK_CHECK_VERSION (2, 12, 0)
       startup_id = start_startup_notification (display, desktop_file,
                                               argv[0], screen_num,
                                               workspace, launch_time);
@@ -1126,7 +1220,10 @@ egg_desktop_file_launchv (EggDesktopFile *desktop_file,
        }
 #else
       startup_id = NULL;
-#endif /* HAVE_GDK_X11_DISPLAY_BROADCAST_STARTUP_MESSAGE */
+#endif /* GTK 2.12 */
+
+      if (env != NULL)
+       g_ptr_array_add (env, NULL);
 
       current_success =
        g_spawn_async_with_pipes (directory,
@@ -1141,7 +1238,7 @@ egg_desktop_file_launchv (EggDesktopFile *desktop_file,
 
       if (startup_id)
        {
-#ifdef HAVE_GDK_X11_DISPLAY_BROADCAST_STARTUP_MESSAGE
+#if GTK_CHECK_VERSION (2, 12, 0)
          if (current_success)
            {
              set_startup_notification_timeout (display, startup_id);
@@ -1152,7 +1249,7 @@ egg_desktop_file_launchv (EggDesktopFile *desktop_file,
                g_free (startup_id);
            }
          else
-#endif /* HAVE_GDK_X11_DISPLAY_BROADCAST_STARTUP_MESSAGE */
+#endif /* GTK 2.12 */
            g_free (startup_id);
        }
       else if (ret_startup_id)
index f1305413e9f9a39272d073862207f1578eb7f74b..f8a3d3e035668e9448db0d88aba178bbefd8136a 100644 (file)
@@ -31,22 +31,23 @@ typedef enum {
 
        EGG_DESKTOP_FILE_TYPE_APPLICATION,
        EGG_DESKTOP_FILE_TYPE_LINK,
-       EGG_DESKTOP_FILE_TYPE_DIRECTORY,
+       EGG_DESKTOP_FILE_TYPE_DIRECTORY
 } EggDesktopFileType;
 
 EggDesktopFile     *egg_desktop_file_new                (const char   *desktop_file_path,
                                                         GError      **error);
 
-EggDesktopFile     *egg_desktop_file_new_from_data_dirs (const char  *desktop_file_path,
-                                                        GError     **error);
-EggDesktopFile     *egg_desktop_file_new_from_key_file  (GKeyFile     *desktop,
+EggDesktopFile     *egg_desktop_file_new_from_data_dirs (const char   *desktop_file_path,
+                                                        GError      **error);
+EggDesktopFile     *egg_desktop_file_new_from_dirs      (const char   *desktop_file_path,
+                                                        const char  **search_dirs,
+                                                        GError      **error);
+EggDesktopFile     *egg_desktop_file_new_from_key_file  (GKeyFile     *key_file,
                                                         const char   *source,
                                                         GError      **error);
 
 void                egg_desktop_file_free               (EggDesktopFile  *desktop_file);
 
-GKeyFile           *egg_desktop_file_get_key_file       (EggDesktopFile  *desktop_file);
-
 const char         *egg_desktop_file_get_source         (EggDesktopFile  *desktop_file);
 
 EggDesktopFileType  egg_desktop_file_get_desktop_file_type (EggDesktopFile  *desktop_file);
@@ -109,6 +110,34 @@ typedef enum {
 #define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS  "StartupWMClass"
 #define EGG_DESKTOP_FILE_KEY_URL               "URL"
 
+/* Accessors */
+gboolean  egg_desktop_file_has_key                (EggDesktopFile  *desktop_file,
+                                                  const char      *key,
+                                                  GError         **error);
+char     *egg_desktop_file_get_string             (EggDesktopFile  *desktop_file,
+                                                  const char      *key,
+                                                  GError         **error) G_GNUC_MALLOC;
+char     *egg_desktop_file_get_locale_string      (EggDesktopFile  *desktop_file,
+                                                  const char      *key,
+                                                  const char      *locale,
+                                                  GError         **error) G_GNUC_MALLOC;
+gboolean  egg_desktop_file_get_boolean            (EggDesktopFile  *desktop_file,
+                                                  const char      *key,
+                                                  GError         **error);
+double    egg_desktop_file_get_numeric            (EggDesktopFile  *desktop_file,
+                                                  const char      *key,
+                                                  GError         **error);
+char    **egg_desktop_file_get_string_list        (EggDesktopFile  *desktop_file,
+                                                  const char      *key,
+                                                  gsize           *length,
+                                                  GError         **error) G_GNUC_MALLOC;
+char    **egg_desktop_file_get_locale_string_list (EggDesktopFile  *desktop_file,
+                                                  const char      *key,
+                                                  const char      *locale,
+                                                  gsize           *length,
+                                                  GError         **error) G_GNUC_MALLOC;
+
+
 /* Errors */
 #define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark()
 
@@ -117,7 +146,7 @@ GQuark egg_desktop_file_error_quark (void);
 typedef enum {
        EGG_DESKTOP_FILE_ERROR_INVALID,
        EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE,
-       EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION,
+       EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION
 } EggDesktopFileError;
 
 /* Global application desktop file */
index eebce07e5aa5b19c3d845fffdcae0cbacf93cb62..e4b11f6288d64e84d3eeff238d343feabd866d19 100644 (file)
@@ -62,11 +62,10 @@ typedef enum
   XSMP_STATE_INTERACT,
   XSMP_STATE_SAVE_YOURSELF_DONE,
   XSMP_STATE_SHUTDOWN_CANCELLED,
-  XSMP_STATE_CONNECTION_CLOSED,
+  XSMP_STATE_CONNECTION_CLOSED
 } EggSMClientXSMPState;
 
 static const char *state_names[] = {
-  "start",
   "idle",
   "save-yourself",
   "interact-request",
@@ -221,19 +220,14 @@ sm_client_xsmp_set_initial_properties (gpointer user_data)
   desktop_file = egg_get_desktop_file ();
   if (desktop_file)
     {
-      GKeyFile *key_file;
       GError *err = NULL;
       char *cmdline, **argv;
       int argc;
 
-      key_file = egg_desktop_file_get_key_file (desktop_file);
-
       if (xsmp->restart_style == SmRestartIfRunning)
        {
-         if (g_key_file_has_key (key_file, EGG_DESKTOP_FILE_GROUP,
-                                 "X-GNOME-AutoRestart", NULL) &&
-             g_key_file_get_boolean (key_file, EGG_DESKTOP_FILE_GROUP,
-                                     "X-GNOME-AutoRestart", NULL))
+         if (egg_desktop_file_get_boolean (desktop_file, 
+                                           "X-GNOME-AutoRestart", NULL))
            xsmp->restart_style = SmRestartImmediately;
        }
 
@@ -771,30 +765,6 @@ do_save_yourself (EggSMClientXSMP *xsmp)
   xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE;
 }
 
-static void
-merge_keyfiles (GKeyFile *dest, GKeyFile *source)
-{
-  int g, k;
-  char **groups, **keys, *value;
-
-  groups = g_key_file_get_groups (source, NULL);
-  for (g = 0; groups[g]; g++)
-    {
-      keys = g_key_file_get_keys (source, groups[g], NULL, NULL);
-      for (k = 0; keys[k]; k++)
-       {
-         value = g_key_file_get_value (source, groups[g], keys[k], NULL);
-         if (value)
-           {
-             g_key_file_set_value (dest, groups[g], keys[k], value);
-             g_free (value);
-           }
-       }
-      g_strfreev (keys);
-    }
-  g_strfreev (groups);
-}
-
 static void
 save_state (EggSMClientXSMP *xsmp)
 {
@@ -825,30 +795,54 @@ save_state (EggSMClientXSMP *xsmp)
   if (desktop_file)
     {
       GKeyFile *merged_file;
-      char *exec;
-      int i;
 
       merged_file = g_key_file_new ();
-      merge_keyfiles (merged_file, egg_desktop_file_get_key_file (desktop_file));
-      merge_keyfiles (merged_file, state_file);
-
-      g_key_file_free (state_file);
-      state_file = merged_file;
-
-      /* Update Exec key using "--sm-client-state-file %k" */
-      restart = generate_command (xsmp->restart_command,
-                                 NULL, "%k");
-      for (i = 0; i < restart->len; i++)
-       restart->pdata[i] = g_shell_quote (restart->pdata[i]);
-      g_ptr_array_add (restart, NULL);
-      exec = g_strjoinv (" ", (char **)restart->pdata);
-      g_strfreev ((char **)restart->pdata);
-      g_ptr_array_free (restart, FALSE);
-
-      g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP,
-                            EGG_DESKTOP_FILE_KEY_EXEC,
-                            exec);
-      g_free (exec);
+      if (g_key_file_load_from_file (merged_file,
+                                    egg_desktop_file_get_source (desktop_file),
+                                    G_KEY_FILE_KEEP_COMMENTS |
+                                    G_KEY_FILE_KEEP_TRANSLATIONS, NULL))
+       {
+         guint g, k, i;
+         char **groups, **keys, *value, *exec;
+
+         groups = g_key_file_get_groups (state_file, NULL);
+         for (g = 0; groups[g]; g++)
+           {
+             keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL);
+             for (k = 0; keys[k]; k++)
+               {
+                 value = g_key_file_get_value (state_file, groups[g],
+                                               keys[k], NULL);
+                 if (value)
+                   {
+                     g_key_file_set_value (merged_file, groups[g],
+                                           keys[k], value);
+                     g_free (value);
+                   }
+               }
+             g_strfreev (keys);
+           }
+         g_strfreev (groups);
+
+         g_key_file_free (state_file);
+         state_file = merged_file;
+
+         /* Update Exec key using "--sm-client-state-file %k" */
+         restart = generate_command (xsmp->restart_command,
+                                     NULL, "%k");
+         for (i = 0; i < restart->len; i++)
+           restart->pdata[i] = g_shell_quote (restart->pdata[i]);
+         g_ptr_array_add (restart, NULL);
+         exec = g_strjoinv (" ", (char **)restart->pdata);
+         g_strfreev ((char **)restart->pdata);
+         g_ptr_array_free (restart, FALSE);
+
+         g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP,
+                                EGG_DESKTOP_FILE_KEY_EXEC,
+                                exec);
+         g_free (exec);
+
+       }
     }
 
   /* Now write state_file to disk. (We can't use mktemp(), because
@@ -1077,7 +1071,7 @@ set_properties (EggSMClientXSMP *xsmp, ...)
   GPtrArray *props;
   SmProp *prop;
   va_list ap;
-  int i;
+  guint i;
 
   props = g_ptr_array_new ();
 
@@ -1170,7 +1164,7 @@ ptrarray_prop (const char *name, GPtrArray *values)
   SmProp *prop;
   SmPropValue pv;
   GArray *vals;
-  int i;
+  guint i;
 
   prop = g_new (SmProp, 1);
   prop->name = (char *)name;
index 642703faa7f7e6f3d16be11ac320d6e4ff23e3be..8e2254f0389b9d6502cb596b8a275f17d6d53c8a 100644 (file)
@@ -38,7 +38,7 @@ enum {
   LAST_SIGNAL
 };
 
-static guint signals[LAST_SIGNAL] = { 0 };
+static guint signals[LAST_SIGNAL];
 
 struct _EggSMClientPrivate {
   GKeyFile *state_file;
@@ -179,19 +179,6 @@ static gboolean sm_client_disable = FALSE;
 static char *sm_client_state_file = NULL;
 static char *sm_client_id = NULL;
 
-static GOptionEntry entries[] = {
-  { "sm-client-disable", 0, 0,
-    G_OPTION_ARG_NONE, &sm_client_disable,
-    N_("Disable connection to session manager"), NULL },
-  { "sm-client-state-file", 0, 0,
-    G_OPTION_ARG_STRING, &sm_client_state_file,
-    N_("Specify file containing saved configuration"), N_("FILE") },
-  { "sm-client-id", 0, 0,
-    G_OPTION_ARG_STRING, &sm_client_id,
-    N_("Specify session management ID"), N_("ID") },
-  { NULL }
-};
-
 static gboolean
 sm_client_post_parse_func (GOptionContext  *context,
                           GOptionGroup    *group,
@@ -200,6 +187,20 @@ sm_client_post_parse_func (GOptionContext  *context,
 {
   EggSMClient *client = egg_sm_client_get ();
 
+  if (sm_client_id == NULL)
+    {
+      const gchar *desktop_autostart_id;
+
+      desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+
+      if (desktop_autostart_id != NULL)
+        sm_client_id = g_strdup (desktop_autostart_id);
+    }
+
+  /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
+   * use the same client id. */
+  g_unsetenv ("DESKTOP_AUTOSTART_ID");
+
   if (EGG_SM_CLIENT_GET_CLASS (client)->startup)
     EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id);
   return TRUE;
@@ -217,6 +218,22 @@ sm_client_post_parse_func (GOptionContext  *context,
 GOptionGroup *
 egg_sm_client_get_option_group (void)
 {
+  const GOptionEntry entries[] = {
+    { "sm-client-disable", 0, 0,
+      G_OPTION_ARG_NONE, &sm_client_disable,
+      N_("Disable connection to session manager"), NULL },
+    { "sm-client-state-file", 0, 0,
+      G_OPTION_ARG_FILENAME, &sm_client_state_file,
+      N_("Specify file containing saved configuration"), N_("FILE") },
+    { "sm-client-id", 0, 0,
+      G_OPTION_ARG_STRING, &sm_client_id,
+      N_("Specify session management ID"), N_("ID") },
+    /* Compatibility options */
+    { "sm-disable", 0, G_OPTION_FLAG_HIDDEN,
+      G_OPTION_ARG_NONE, &sm_client_disable,
+      NULL, NULL },
+    { NULL }
+  };
   GOptionGroup *group;
 
   /* Use our own debug handler for the "EggSMClient" domain. */
@@ -224,8 +241,8 @@ egg_sm_client_get_option_group (void)
                     egg_sm_client_debug_handler, NULL);
 
   group = g_option_group_new ("sm-client",
-                             _("Session Management Options"),
-                             _("Show Session Management options"),
+                             _("Session management options:"),
+                             _("Show session management options"),
                              NULL, NULL);
   g_option_group_add_entries (group, entries);
   g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func);
@@ -300,16 +317,16 @@ egg_sm_client_get (void)
 #elif defined (GDK_WINDOWING_QUARTZ)
          global_client = egg_sm_client_osx_new ();
 #else
-         /* If both D-Bus and XSMP are compiled in, try D-Bus first
-          * and fall back to XSMP if D-Bus session management isn't
-          * available.
+         /* If both D-Bus and XSMP are compiled in, try XSMP first
+          * (since it supports state saving) and fall back to D-Bus
+          * if XSMP isn't available.
           */
-# ifdef EGG_SM_CLIENT_BACKEND_DBUS
-         global_client = egg_sm_client_dbus_new ();
-# endif
 # ifdef EGG_SM_CLIENT_BACKEND_XSMP
+         global_client = egg_sm_client_xsmp_new ();
+# endif
+# ifdef EGG_SM_CLIENT_BACKEND_DBUS
          if (!global_client)
-           global_client = egg_sm_client_xsmp_new ();
+           global_client = egg_sm_client_dbus_new ();
 # endif
 #endif
        }