diff options
-rw-r--r-- | src/indicator-session.c | 170 |
1 files changed, 105 insertions, 65 deletions
diff --git a/src/indicator-session.c b/src/indicator-session.c index 8a4e298..a4bb5e1 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -62,6 +62,8 @@ static guint status_menu_pos_offset (void); static guint users_menu_pos_offset (void); static guint session_menu_pos_offset (void); static void child_realized (DbusmenuMenuitem * child, gpointer userdata); +static gboolean start_service (gpointer userdata); +static void start_service_phase2 (DBusGProxy * proxy, guint status, GError * error, gpointer data); GtkLabel * get_label (void) @@ -138,6 +140,11 @@ child_realized (DbusmenuMenuitem * child, gpointer userdata) return; } + if (client == NULL) { + g_warning("Child realized for a menu we don't have? Section: %s", errorstr); + return; + } + position += posfunc(); g_debug("SUS: Adding child: %d", position); GtkMenuItem * widget = dbusmenu_gtkclient_menuitem_get(client, child); @@ -262,29 +269,13 @@ connect_to_status (gpointer userdata) return FALSE; } -static gboolean -build_status_menu (gpointer userdata) +/* Follow up the service being started by connecting + up the DBus Menu Client and creating our separator. + Also creates an idle func to connect to the service for + getting the icon that we should be using on the panel. */ +static void +status_followup (void) { - g_debug("Building Status Menu"); - guint returnval = 0; - GError * error = NULL; - - if (proxy == NULL) { - /* If we don't have DBus, let's stay in the idle loop */ - return TRUE; - } - - if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_STATUS_DBUS_NAME, 0, &returnval, &error)) { - g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); - g_error_free(error); - return FALSE; - } - - if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { - g_error("Return value isn't indicative of success: %d", returnval); - return FALSE; - } - status_client = dbusmenu_gtkclient_new(INDICATOR_STATUS_DBUS_NAME, INDICATOR_STATUS_DBUS_OBJECT); g_signal_connect(G_OBJECT(status_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(status_menu_root_changed), main_menu); @@ -294,7 +285,7 @@ build_status_menu (gpointer userdata) g_idle_add(connect_to_status, NULL); - return FALSE; + return; } /* Users menu */ @@ -354,29 +345,11 @@ users_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot, return; } -static gboolean -build_users_menu (gpointer userdata) +/* Follow up the service being started by connecting + up the DBus Menu Client and creating our separator. */ +static void +users_followup (void) { - g_debug("Building Users Menu"); - guint returnval = 0; - GError * error = NULL; - - if (proxy == NULL) { - /* If we don't have DBus, let's stay in the idle loop */ - return TRUE; - } - - if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_USERS_DBUS_NAME, 0, &returnval, &error)) { - g_error("Unable to send message to DBus to start service"); - g_error_free(error); - return FALSE; - } - - if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { - g_error("Return value isn't indicative of success: %d", returnval); - return FALSE; - } - users_client = dbusmenu_gtkclient_new(INDICATOR_USERS_DBUS_NAME, INDICATOR_USERS_DBUS_OBJECT); g_signal_connect(G_OBJECT(users_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(users_menu_root_changed), main_menu); @@ -384,7 +357,7 @@ build_users_menu (gpointer userdata) gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), users_separator); gtk_widget_hide(users_separator); /* Should be default, I'm just being explicit. $(%*#$ hide already! */ - return FALSE; + return; } /* Session Menu Stuff */ @@ -432,37 +405,101 @@ session_menu_root_changed(DbusmenuGtkClient * client, DbusmenuMenuitem * newroot return; } +/* Follow up the service being started by connecting + up the DBus Menu Client. */ +static void +session_followup (void) +{ + session_client = dbusmenu_gtkclient_new(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_OBJECT); + g_signal_connect(G_OBJECT(session_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(session_menu_root_changed), main_menu); + + return; +} + +/* Base menu stuff */ + +/* This takes the response to the service starting up. + It checks to see if it's started and if so, continues + with the follow function for the particular area that + it's working in. */ +static void +start_service_phase2 (DBusGProxy * proxy, guint status, GError * error, gpointer data) +{ + /* If we've got an error respond to it */ + if (error != NULL) { + g_critical("Starting service has resulted in error."); + g_error_free(error); + /* Try it all again, we need to get this started! */ + g_idle_add(start_service, data); + return; + } + + /* If it's not running or we started it, try again */ + if (status != DBUS_START_REPLY_SUCCESS && status != DBUS_START_REPLY_ALREADY_RUNNING) { + g_critical("Return value isn't indicative of success: %d", status); + /* Try it all again, we need to get this started! */ + g_idle_add(start_service, data); + return; + } + + /* Check which part of the menu we're in and do the + appropriate follow up from the service being started. */ + switch (GPOINTER_TO_INT(data)) { + case STATUS_SECTION: + status_followup(); + break; + case USERS_SECTION: + users_followup(); + break; + case SESSION_SECTION: + session_followup(); + break; + default: + g_critical("Oh, how can we get a value that we don't know!"); + break; + } + + return; +} + +/* Our idle service starter. It looks at the section that + we're doing and then asks async for that service to be + started by dbus. Probably not really useful to be in + the idle loop as it's so quick, but why not. */ static gboolean -build_session_menu (gpointer userdata) +start_service (gpointer userdata) { - g_debug("Building Session Menu"); - guint returnval = 0; - GError * error = NULL; + g_debug("Starting a service"); if (proxy == NULL) { /* If we don't have DBus, let's stay in the idle loop */ return TRUE; } - if (!org_freedesktop_DBus_start_service_by_name (proxy, INDICATOR_SESSION_DBUS_NAME, 0, &returnval, &error)) { - g_error("Unable to send message to DBus to start service: %s", error != NULL ? error->message : "(NULL error)" ); - g_error_free(error); - return FALSE; - } - - if (returnval != DBUS_START_REPLY_SUCCESS && returnval != DBUS_START_REPLY_ALREADY_RUNNING) { - g_error("Return value isn't indicative of success: %d", returnval); + const gchar * service = NULL; + switch (GPOINTER_TO_INT(userdata)) { + case STATUS_SECTION: + service = INDICATOR_STATUS_DBUS_NAME; + break; + case USERS_SECTION: + service = INDICATOR_USERS_DBUS_NAME; + break; + case SESSION_SECTION: + service = INDICATOR_SESSION_DBUS_NAME; + break; + default: + g_critical("Oh, how can we get a value that we don't know!"); return FALSE; } - session_client = dbusmenu_gtkclient_new(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_OBJECT); - g_signal_connect(G_OBJECT(session_client), DBUSMENU_GTKCLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(session_menu_root_changed), main_menu); + org_freedesktop_DBus_start_service_by_name_async (proxy, service, 0 /* Flags */, start_service_phase2, userdata); return FALSE; } -/* Base menu stuff */ - +/* Indicator based function to get the menu for the whole + applet. This starts up asking for the parts of the menu + from the various services. */ GtkMenu * get_menu (void) { @@ -472,10 +509,13 @@ get_menu (void) g_warning("Unable to get proxy for DBus itself. Seriously."); } - g_idle_add(build_status_menu, NULL); - g_idle_add(build_users_menu, NULL); - g_idle_add(build_session_menu, NULL); + /* Startup in the idle loop */ + g_idle_add(start_service, GINT_TO_POINTER(STATUS_SECTION)); + g_idle_add(start_service, GINT_TO_POINTER(USERS_SECTION)); + g_idle_add(start_service, GINT_TO_POINTER(SESSION_SECTION)); + /* Build a temp menu incase someone can ask for it + before the services start. Fast user! */ main_menu = GTK_MENU(gtk_menu_new()); loading_item = gtk_menu_item_new_with_label("Loading..."); gtk_menu_shell_append(GTK_MENU_SHELL(main_menu), loading_item); |