aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/indicator-session.c170
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);