diff --git a/xfce4-session/xfsm-manager.c b/xfce4-session/xfsm-manager.c index c404506..f0827c4 100644 --- a/xfce4-session/xfsm-manager.c +++ b/xfce4-session/xfsm-manager.c @@ -71,12 +71,10 @@ Prototypes */ static gboolean xfsm_manager_startup (void); -static void xfsm_manager_handle_failed (void); -static gboolean xfsm_manager_startup_timedout (gpointer user_data); static void xfsm_manager_load_settings (XfceRc *rc); static gboolean xfsm_manager_load_session (void); static GdkPixbuf *xfsm_manager_load_session_preview (const gchar *name); - +static void xfsm_manager_startup_done (void); /* Static data @@ -84,7 +82,6 @@ static GdkPixbuf *xfsm_manager_load_session_preview (const gchar *name); static XfsmManagerState state = XFSM_MANAGER_STARTUP; static gboolean session_chooser = FALSE; static guint die_timeout_id = 0; -static guint startup_timeout_id = 0; static gboolean @@ -93,7 +90,7 @@ xfsm_manager_startup (void) xfsm_startup_foreign (); pending_properties = g_list_sort (pending_properties, (GCompareFunc) xfsm_properties_compare); - xfsm_manager_startup_continue (NULL); + xfsm_manager_begin_startup (); return FALSE; } @@ -127,36 +124,40 @@ xfsm_manager_restore_active_workspace (XfceRc *rc) } -static void -xfsm_manager_handle_failed (void) +void +xfsm_manager_handle_failed_client (XfsmProperties *properties) { - /* Handle apps that failed to start here */ - XfsmProperties *properties; - GList *lp; + GList *lp; - for (lp = starting_properties; lp != NULL; lp = lp->next) + if ((lp = g_list_find (starting_properties, properties)) == NULL) { - properties = XFSM_PROPERTIES (lp->data); - - if (properties->discard_command != NULL) - { - xfsm_verbose ("Client Id = %s failed to start, running discard " - "command now.\n\n", properties->client_id); - - g_spawn_sync (properties->current_directory, - properties->discard_command, - properties->environment, - G_SPAWN_SEARCH_PATH, - NULL, NULL, - NULL, NULL, - NULL, NULL); - } + xfsm_verbose("Client Id = %s failed to start, but not found in " + "startup properties list.\n\n", properties->client_id); + return; + } - xfsm_properties_free (properties); + if (properties->discard_command != NULL) + { + xfsm_verbose ("Client Id = %s failed to start, running discard " + "command now.\n\n", properties->client_id); + + g_spawn_sync (properties->current_directory, + properties->discard_command, + properties->environment, + G_SPAWN_SEARCH_PATH, + NULL, NULL, + NULL, NULL, + NULL, NULL); } - g_list_free (starting_properties); - starting_properties = NULL; + xfsm_properties_free (properties); + + starting_properties = g_list_delete_link (starting_properties, lp); + + if (starting_properties == NULL && state == XFSM_MANAGER_STARTUP) + { + xfsm_manager_startup_done (); + } } @@ -437,71 +438,38 @@ xfsm_manager_restart (void) void -xfsm_manager_startup_continue (const gchar *previous_id) +xfsm_manager_begin_startup (void) { - gboolean startup_done = FALSE; - gchar buffer[1024]; - XfceRc *rc; - - xfsm_verbose ("Manager startup continues [Previous Id = %s]\n\n", - previous_id != NULL ? previous_id : "None"); + xfsm_startup_begin (); +} - if (startup_timeout_id != 0) - { - g_source_remove (startup_timeout_id); - startup_timeout_id = 0; - /* work around broken clients */ - if (state != XFSM_MANAGER_STARTUP) - return; - } +static void +xfsm_manager_startup_done (void) +{ + gchar buffer[1024]; + XfceRc *rc; - startup_done = xfsm_startup_continue (previous_id); + xfsm_verbose ("Manager finished startup, entering IDLE mode now\n\n"); + state = XFSM_MANAGER_IDLE; - if (startup_done) + if (!failsafe_mode) { - xfsm_verbose ("Manager finished startup, entering IDLE mode now\n\n"); - state = XFSM_MANAGER_IDLE; - - if (!failsafe_mode) - { - /* handle apps that failed to start */ - xfsm_manager_handle_failed (); - - /* restore active workspace, this has to be done after the - * window manager is up, so we do it last. - */ - g_snprintf (buffer, 1024, "Session: %s", session_name); - rc = xfce_rc_simple_open (session_file, TRUE); - xfce_rc_set_group (rc, buffer); - xfsm_manager_restore_active_workspace (rc); - xfce_rc_close (rc); + /* restore active workspace, this has to be done after the + * window manager is up, so we do it last. + */ + g_snprintf (buffer, 1024, "Session: %s", session_name); + rc = xfce_rc_simple_open (session_file, TRUE); + xfce_rc_set_group (rc, buffer); + xfsm_manager_restore_active_workspace (rc); + xfce_rc_close (rc); - /* start legacy applications now */ - xfsm_legacy_startup (); - } - } - else - { - startup_timeout_id = g_timeout_add (STARTUP_TIMEOUT, - xfsm_manager_startup_timedout, - NULL); + /* start legacy applications now */ + xfsm_legacy_startup (); } } -static gboolean -xfsm_manager_startup_timedout (gpointer user_data) -{ - xfsm_verbose ("Manager startup timed out\n\n"); - - startup_timeout_id = 0; /* will be removed automagically once we return */ - xfsm_manager_startup_continue (NULL); - - return FALSE; -} - - gchar* xfsm_manager_generate_client_id (SmsConn sms_conn) { @@ -600,6 +568,12 @@ xfsm_manager_register_client (XfsmClient *client, if (properties == NULL) return FALSE; + if (properties->startup_timeout_id) + { + g_source_remove (properties->startup_timeout_id); + properties->startup_timeout_id = 0; + } + xfsm_client_set_initial_properties (client, properties); } else @@ -626,6 +600,7 @@ xfsm_manager_register_client (XfsmClient *client, if ((failsafe_mode || previous_id != NULL) && state == XFSM_MANAGER_STARTUP) { +#if 0 /* Only continue the startup if we are either in Failsafe mode (which * means that we don't have any previous_id at all) or the previous_id * matched one of the starting_properties. If there was no match @@ -633,6 +608,12 @@ xfsm_manager_register_client (XfsmClient *client, * See http://bugs.xfce.org/view_bug_page.php?f_id=212 for details. */ xfsm_manager_startup_continue (previous_id); +#endif + + if (starting_properties == NULL) + { + xfsm_manager_startup_done (); + } } return TRUE; diff --git a/xfce4-session/xfsm-manager.h b/xfce4-session/xfsm-manager.h index c005a3b..b0ffc7a 100644 --- a/xfce4-session/xfsm-manager.h +++ b/xfce4-session/xfsm-manager.h @@ -45,7 +45,8 @@ void xfsm_manager_init (XfceRc *rc); gboolean xfsm_manager_restart (void); -void xfsm_manager_startup_continue (const gchar *previous_id); +void xfsm_manager_begin_startup (void); +void xfsm_manager_handle_failed_client (XfsmProperties *properties); gchar* xfsm_manager_generate_client_id (SmsConn sms_conn) G_GNUC_PURE; diff --git a/xfce4-session/xfsm-properties.h b/xfce4-session/xfsm-properties.h index 62c6e5f..9be0a1c 100644 --- a/xfce4-session/xfsm-properties.h +++ b/xfce4-session/xfsm-properties.h @@ -49,6 +49,8 @@ struct _XfsmProperties gchar **restart_command; gint restart_style_hint; gchar *user_id; + + guint startup_timeout_id; }; diff --git a/xfce4-session/xfsm-startup.c b/xfce4-session/xfsm-startup.c index a9eb278..2e3f975 100644 --- a/xfce4-session/xfsm-startup.c +++ b/xfce4-session/xfsm-startup.c @@ -60,8 +60,8 @@ /* Prototypes */ -static gboolean xfsm_startup_continue_failsafe (void); -static gboolean xfsm_startup_continue_session (const gchar *previous_id); +static void xfsm_startup_begin_failsafe (void); +static void xfsm_startup_begin_session (void); static void xfsm_startup_child_watch (GPid pid, gint status, gpointer user_data); @@ -417,6 +417,13 @@ xfsm_startup_autostart (void) } +static gboolean +xfsm_startup_autostart_idled (gpointer data) +{ + xfsm_startup_autostart (); + return FALSE; +} + void xfsm_startup_foreign (void) @@ -429,126 +436,146 @@ xfsm_startup_foreign (void) } -/* Returns TRUE if done, else FALSE */ -gboolean -xfsm_startup_continue (const gchar *previous_id) +void +xfsm_startup_begin (void) { - gboolean startup_done = FALSE; - if (failsafe_mode) - startup_done = xfsm_startup_continue_failsafe (); + xfsm_startup_begin_failsafe (); else - startup_done = xfsm_startup_continue_session (previous_id); + xfsm_startup_begin_session (); - /* perform Autostart */ - if (startup_done) - xfsm_startup_autostart (); - - return startup_done; + /* FIXME: not sure if i want to do it this way */ + g_idle_add (xfsm_startup_autostart_idled, NULL); } static gboolean -xfsm_startup_continue_failsafe (void) -{ - FailsafeClient *fclient; - - fclient = (FailsafeClient *) g_list_nth_data (failsafe_clients, 0); - if (fclient != NULL) +xfsm_start_failsafe_client_idled (gpointer data) +{ + FailsafeClient *fclient = data; + + /* FIXME: SPLASH */ + /* let the user know whats going on */ + if (G_LIKELY (splash_screen != NULL)) { - /* let the user know whats going on */ - if (G_LIKELY (splash_screen != NULL)) - { - xfsm_splash_screen_next (splash_screen, - figure_app_name (fclient->command[0])); - } + xfsm_splash_screen_next (splash_screen, + figure_app_name (fclient->command[0])); + } + + /* start the application */ + xfsm_start_application (fclient->command, NULL, fclient->screen, + NULL, NULL, NULL); + g_strfreev (fclient->command); + g_free (fclient); + + return FALSE; +} - /* start the application */ - xfsm_start_application (fclient->command, NULL, fclient->screen, - NULL, NULL, NULL); - failsafe_clients = g_list_remove (failsafe_clients, fclient); - g_strfreev (fclient->command); - g_free (fclient); - /* there are more to come */ - return FALSE; +static void +xfsm_startup_begin_failsafe (void) +{ + GList *lp; + + for(lp = g_list_first (failsafe_clients); lp; lp = g_list_next (lp)) + { + g_idle_add (xfsm_start_failsafe_client_idled, lp->data); } - return TRUE; + g_list_free (failsafe_clients); + failsafe_clients = NULL; } static gboolean -xfsm_startup_continue_session (const gchar *previous_id) +xfsm_startup_client_timedout (gpointer data) { - XfsmProperties *properties; + XfsmProperties *properties = XFSM_PROPERTIES (data); + + properties->startup_timeout_id = 0; + xfsm_manager_handle_failed_client (properties); + + return FALSE; +} + + +static gboolean +xfsm_start_client_idled (gpointer data) +{ + XfsmProperties *properties = XFSM_PROPERTIES (data); gchar **argv; gint argc; GPid pid; gint n; - -again: - properties = (XfsmProperties *) g_list_nth_data (pending_properties, 0); - if (properties != NULL) - { - if (G_LIKELY (splash_screen != NULL)) - { - xfsm_splash_screen_next (splash_screen, - figure_app_name (properties->program)); - } - /* drop the properties from the pending list */ - pending_properties = g_list_remove (pending_properties, properties); + /* FIXME: SPLASH */ + if (G_LIKELY (splash_screen != NULL)) + { + xfsm_splash_screen_next (splash_screen, + figure_app_name (properties->program)); + } - /* generate the argument vector for the application (expanding variables) */ - argc = g_strv_length (properties->restart_command); - argv = g_new (gchar *, argc + 1); - for (n = 0; n < argc; ++n) - argv[n] = xfce_expand_variables (properties->restart_command[n], NULL); - argv[n] = NULL; + /* generate the argument vector for the application (expanding variables) */ + argc = g_strv_length (properties->restart_command); + argv = g_new (gchar *, argc + 1); + for (n = 0; n < argc; ++n) + argv[n] = xfce_expand_variables (properties->restart_command[n], NULL); + argv[n] = NULL; - /* fork a new process for the application */ + /* fork a new process for the application */ #ifdef HAVE_VFORK - pid = vfork (); + pid = vfork (); #else - pid = fork (); + pid = fork (); #endif - /* handle the child process */ - if (pid == 0) - { - /* execute the application here */ - execvp (argv[0], argv); - _exit (127); - } + /* handle the child process */ + if (pid == 0) + { + /* execute the application here */ + execvp (argv[0], argv); + _exit (127); + } - /* check if we failed to fork */ - if (G_UNLIKELY (pid < 0)) - { - /* tell the user that we failed to fork */ - perror ("Failed to fork new process"); - } - else - { - /* watch the child process */ - g_child_watch_add_full (G_PRIORITY_LOW, pid, xfsm_startup_child_watch, g_strdup (properties->client_id), xfsm_startup_child_watch_destroy); - } + /* check if we failed to fork */ + if (G_UNLIKELY (pid < 0)) + { + /* tell the user that we failed to fork */ + perror ("Failed to fork new process"); + } + else + { + /* watch the child process */ + g_child_watch_add_full (G_PRIORITY_LOW, pid, xfsm_startup_child_watch, g_strdup (properties->client_id), xfsm_startup_child_watch_destroy); + } - /* cleanup */ - g_strfreev (argv); + /* cleanup */ + g_strfreev (argv); + + /* move the properties to the list of starting applications */ + starting_properties = g_list_append (starting_properties, properties); - /* move the properties to the list of starting applications */ - starting_properties = g_list_append (starting_properties, properties); + /* set a timeout; client must register with SM before time runs out */ + properties->startup_timeout_id = g_timeout_add (STARTUP_TIMEOUT, + xfsm_startup_client_timedout, + properties); - /* try with the next pending if fork() failed */ - if (G_UNLIKELY (pid < 0)) - goto again; + return FALSE; +} - /* more to come... */ - return FALSE; + +static void +xfsm_startup_begin_session (void) +{ + GList *lp; + + for(lp = g_list_first (pending_properties); lp; lp = g_list_next (lp)) + { + g_idle_add (xfsm_start_client_idled, lp->data); } - return TRUE; + g_list_free (pending_properties); + pending_properties = NULL; } @@ -569,7 +596,13 @@ xfsm_startup_child_watch (GPid pid, if (strcmp (properties->client_id, client_id) == 0) { /* continue startup, this client failed most probably */ - xfsm_manager_startup_continue (NULL); + xfsm_verbose ("Client with id %s appears to have failed", client_id); + if (properties->startup_timeout_id) + { + g_source_remove (properties->startup_timeout_id); + properties->startup_timeout_id = 0; + } + xfsm_manager_handle_failed_client (properties); break; } } diff --git a/xfce4-session/xfsm-startup.h b/xfce4-session/xfsm-startup.h index 1640239..0315ba8 100644 --- a/xfce4-session/xfsm-startup.h +++ b/xfce4-session/xfsm-startup.h @@ -26,7 +26,7 @@ void xfsm_startup_init (XfceRc *rc); void xfsm_startup_foreign (void); -gboolean xfsm_startup_continue (const gchar *previous_id); +void xfsm_startup_begin (void); #endif /* !__XFSM_STARTUP_H__ */