libegg r858 - trunk/libegg/smclient
- From: danw svn gnome org
- To: svn-commits-list gnome org
- Subject: libegg r858 - trunk/libegg/smclient
- Date: Sun, 16 Mar 2008 14:51:29 +0000 (GMT)
Author: danw
Date: Sun Mar 16 14:51:29 2008
New Revision: 858
URL: http://svn.gnome.org/viewvc/libegg?rev=858&view=rev
Log:
* 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.
Modified:
trunk/libegg/smclient/ChangeLog
trunk/libegg/smclient/eggsmclient-xsmp.c
Modified: trunk/libegg/smclient/eggsmclient-xsmp.c
==============================================================================
--- trunk/libegg/smclient/eggsmclient-xsmp.c (original)
+++ trunk/libegg/smclient/eggsmclient-xsmp.c Sun Mar 16 14:51:29 2008
@@ -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;
@@ -200,72 +200,19 @@
}
static gboolean
-sm_client_xsmp_connect (gpointer user_data)
+sm_client_xsmp_set_initial_properties (gpointer user_data)
{
EggSMClientXSMP *xsmp = user_data;
- SmcCallbacks callbacks;
- char *client_id;
- char error_string_ret[256];
- char pid_str[64];
EggDesktopFile *desktop_file;
GPtrArray *clone, *restart;
+ char pid_str[64];
- g_source_remove (xsmp->idle);
- xsmp->idle = 0;
-
- 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 FALSE;
- }
-
- /* 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)
+ if (xsmp->idle)
{
- 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);
+ 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;
@@ -339,7 +286,7 @@
NULL);
}
- xsmp->state = XSMP_STATE_IDLE;
+ update_pending_events (xsmp);
return FALSE;
}
@@ -371,19 +318,76 @@
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);
- /* Don't connect to the session manager until we reach the main
- * loop, since the session manager may assume we're fully up and
- * running once we connect. (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->idle = g_idle_add (sm_client_xsmp_connect, client);
+ xsmp->waiting_to_set_initial_properties = TRUE;
+ xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client);
}
static void
@@ -473,11 +477,6 @@
switch (xsmp->state)
{
- case XSMP_STATE_START:
- /* Force the connection to complete (or fail) now. */
- sm_client_xsmp_connect (xsmp);
- break;
-
case XSMP_STATE_CONNECTION_CLOSED:
return FALSE;
@@ -498,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 */
@@ -638,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.
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]