changeset 4363:80feba8e9034

Merge libeggsmclient from upstream
author Ivan N. Zlatev <contact@i-nz.net>
date Sun, 23 Mar 2008 15:58:34 +0100
parents 0ea092cbb49f
children 695e1c91be36
files src/libeggsmclient/ChangeLog src/libeggsmclient/eggsmclient-xsmp.c
diffstat 2 files changed, 104 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/src/libeggsmclient/ChangeLog	Sun Mar 23 14:30:38 2008 +0100
+++ b/src/libeggsmclient/ChangeLog	Sun Mar 23 15:58:34 2008 +0100
@@ -1,17 +1,32 @@
-2008-03-03  Ivan N. Zlatev  <contact@i-nz.net>
+2008-03-23  Jussi Judin  <jjudin+audacious@iki.fi>
+
+	* eggdesktopfile.c (egg_desktop_file_new_from_key_file): do not 
+	leak the type.
+
+2008-03-15  Dan Winship  <danw@gnome.org>
 
-	* eggsmclient-xsmp.c (sm_client_xsmp_startup): Connect 
-	immediately, so that windows created before 
-	running the main loop will have SM_CLIENT_ID set. We are not 
-	supposed to modify SM_CLIENT_ID after the visible window has 
-	been created (e.g Metacity will just ignore us).
-	Delay setting the initial properties until after the main loop, 
-	has started in order to provide a larger time frame for the 
-	user to call egg_set_desktop_file().
+	* eggsmclient-xsmp.c: Reorganize; we have to call
+	gdk_set_sm_client_id() before the application creates any windows
+	(you're not allowed to change SM_CLIENT_ID while you have windows
+	mapped), which means that to be safe, we have to do it at startup
+	time, not after the main loop starts.
+	(EggSMClientXSMP): add a waiting_to_set_initial_properties flag.
+	(sm_client_xsmp_startup): Move the begining of the old
+	sm_client_xsmp_connect to here. Set
+	waiting_to_set_initial_properties and set up an idle handler to do
+	that.
+	(sm_client_xsmp_set_initial_properties): The rest of the old
+	sm_client_xsmp_connect.
+	(sm_client_xsmp_end_session): XSMP_STATE_START no longer exists,
+	but we have to deal with waiting_to_set_initial_properties now.
+	(xsmp_save_yourself): Likewise, if this arrives before we get a
+	chance to set the initial properties, set them now.
+
+	Based on a patch from Ivan N. Zlatev.
 
 2007-05-02  Dan Winship  <danw@novell.com>
 
-	* egglauncher.c: 
+	* egglauncher.c:
 	* eggdesktopfile.c: Replace EggLauncher with EggDesktopFile,
 	which is more like GnomeDesktopItem, but with a nicer launching
 	API.
--- a/src/libeggsmclient/eggsmclient-xsmp.c	Sun Mar 23 14:30:38 2008 +0100
+++ b/src/libeggsmclient/eggsmclient-xsmp.c	Sun Mar 23 15:58:34 2008 +0100
@@ -56,7 +56,6 @@
  */
 typedef enum
 {
-  XSMP_STATE_START,
   XSMP_STATE_IDLE,
   XSMP_STATE_SAVE_YOURSELF,
   XSMP_STATE_INTERACT_REQUEST,
@@ -101,6 +100,7 @@
   guint shutting_down : 1;
 
   /* Todo list */
+  guint waiting_to_set_initial_properties : 1;
   guint waiting_to_emit_quit : 1;
   guint waiting_to_emit_quit_cancelled : 1;
   guint waiting_to_save_myself : 1;
@@ -199,71 +199,6 @@
   return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL);
 }
 
-static void
-sm_client_xsmp_connect (EggSMClient *client)
-{
-  EggSMClientXSMP *xsmp = (EggSMClientXSMP *) client;
-  SmcCallbacks callbacks;
-  char *client_id;
-  char error_string_ret[256];
-
-  ice_init ();
-  SmcSetErrorHandler (smc_error_handler);
-
-  callbacks.save_yourself.callback      = xsmp_save_yourself;
-  callbacks.die.callback                = xsmp_die;
-  callbacks.save_complete.callback      = xsmp_save_complete;
-  callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
-
-  callbacks.save_yourself.client_data      = xsmp;
-  callbacks.die.client_data                = xsmp;
-  callbacks.save_complete.client_data      = xsmp;
-  callbacks.shutdown_cancelled.client_data = xsmp;
-
-  client_id = NULL;
-  error_string_ret[0] = '\0';
-  xsmp->connection =
-    SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor,
-		       SmcSaveYourselfProcMask | SmcDieProcMask |
-		       SmcSaveCompleteProcMask |
-		       SmcShutdownCancelledProcMask,
-		       &callbacks,
-		       xsmp->client_id, &client_id,
-		       sizeof (error_string_ret), error_string_ret);
-
-  if (!xsmp->connection)
-    {
-      g_warning ("Failed to connect to the session manager: %s\n",
-		 error_string_ret[0] ?
-		 error_string_ret : "no error message given");
-      xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
-      return;
-    }
-
-  /* We expect a pointless initial SaveYourself if either (a) we
-   * didn't have an initial client ID, or (b) we DID have an initial
-   * client ID, but the server rejected it and gave us a new one.
-   */
-  if (!xsmp->client_id ||
-      (client_id && strcmp (xsmp->client_id, client_id) != 0))
-    xsmp->expecting_initial_save_yourself = TRUE;
-
-  if (client_id)
-    {
-      g_free (xsmp->client_id);
-      xsmp->client_id = g_strdup (client_id);
-      free (client_id);
-
-      gdk_threads_enter ();
-      gdk_set_sm_client_id (xsmp->client_id);
-      gdk_threads_leave ();
-
-      g_debug ("Got client ID \"%s\"", xsmp->client_id);
-    }
-
-  xsmp->state = XSMP_STATE_IDLE;
-}
-
 static gboolean
 sm_client_xsmp_set_initial_properties (gpointer user_data)
 {
@@ -272,8 +207,12 @@
   GPtrArray *clone, *restart;
   char pid_str[64];
 
-  g_source_remove (xsmp->idle);
-  xsmp->idle = 0;
+  if (xsmp->idle)
+    {
+      g_source_remove (xsmp->idle);
+      xsmp->idle = 0;
+    }
+  xsmp->waiting_to_set_initial_properties = FALSE;
 
   if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART)
     xsmp->restart_style = SmRestartNever;
@@ -347,6 +286,7 @@
 		      NULL);
     }
 
+  update_pending_events (xsmp);
   return FALSE;
 }
 
@@ -378,18 +318,75 @@
 			const char  *client_id)
 {
   EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client;
+  SmcCallbacks callbacks;
+  char *ret_client_id;
+  char error_string_ret[256];
 
-  xsmp->state = XSMP_STATE_START;
-  if (xsmp->client_id)
-    g_free (xsmp->client_id);
   xsmp->client_id = g_strdup (client_id);
 
-  sm_client_xsmp_connect (client);
-  /* Do not initialize the properties until we reach the main.
-   * This also gives the application a chance to call 
-   * egg_set_desktop_file() before we set the initial
-   * properties.
+  ice_init ();
+  SmcSetErrorHandler (smc_error_handler);
+
+  callbacks.save_yourself.callback      = xsmp_save_yourself;
+  callbacks.die.callback                = xsmp_die;
+  callbacks.save_complete.callback      = xsmp_save_complete;
+  callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled;
+
+  callbacks.save_yourself.client_data      = xsmp;
+  callbacks.die.client_data                = xsmp;
+  callbacks.save_complete.client_data      = xsmp;
+  callbacks.shutdown_cancelled.client_data = xsmp;
+
+  client_id = NULL;
+  error_string_ret[0] = '\0';
+  xsmp->connection =
+    SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor,
+		       SmcSaveYourselfProcMask | SmcDieProcMask |
+		       SmcSaveCompleteProcMask |
+		       SmcShutdownCancelledProcMask,
+		       &callbacks,
+		       xsmp->client_id, &ret_client_id,
+		       sizeof (error_string_ret), error_string_ret);
+
+  if (!xsmp->connection)
+    {
+      g_warning ("Failed to connect to the session manager: %s\n",
+		 error_string_ret[0] ?
+		 error_string_ret : "no error message given");
+      xsmp->state = XSMP_STATE_CONNECTION_CLOSED;
+      return;
+    }
+
+  /* We expect a pointless initial SaveYourself if either (a) we
+   * didn't have an initial client ID, or (b) we DID have an initial
+   * client ID, but the server rejected it and gave us a new one.
    */
+  if (!xsmp->client_id ||
+      (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0))
+    xsmp->expecting_initial_save_yourself = TRUE;
+
+  if (ret_client_id)
+    {
+      g_free (xsmp->client_id);
+      xsmp->client_id = g_strdup (ret_client_id);
+      free (ret_client_id);
+
+      gdk_threads_enter ();
+      gdk_set_sm_client_id (xsmp->client_id);
+      gdk_threads_leave ();
+
+      g_debug ("Got client ID \"%s\"", xsmp->client_id);
+    }
+
+  xsmp->state = XSMP_STATE_IDLE;
+
+  /* Do not set the initial properties until we reach the main loop,
+   * so that the application has a chance to call
+   * egg_set_desktop_file(). (This may also help the session manager
+   * have a better idea of when the application is fully up and
+   * running.)
+   */
+  xsmp->waiting_to_set_initial_properties = TRUE;
   xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
 }
 
@@ -480,11 +477,6 @@
 
       switch (xsmp->state)
 	{
-	case XSMP_STATE_START:
-	  /* Force the connection to complete (or fail) now. */
-	  sm_client_xsmp_connect (client);
-	  break;
-
 	case XSMP_STATE_CONNECTION_CLOSED:
 	  return FALSE;
 
@@ -505,6 +497,9 @@
 	  return TRUE;
 
 	case XSMP_STATE_IDLE:
+	  if (xsmp->waiting_to_set_initial_properties)
+	    sm_client_xsmp_set_initial_properties (xsmp);
+
 	  if (!xsmp->expecting_initial_save_yourself)
 	    break;
 	  /* else fall through */
@@ -645,6 +640,9 @@
       return;
     }
 
+  if (xsmp->waiting_to_set_initial_properties)
+    sm_client_xsmp_set_initial_properties (xsmp);
+
   /* If this is the initial SaveYourself, ignore it; we've already set
    * properties and there's no reason to actually save state too.
    */