← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~ted/indicator-session/menu-reshuffle into lp:indicator-session

 

Ted Gould has proposed merging lp:~ted/indicator-session/menu-reshuffle into lp:indicator-session.

Requested reviews:
  Conor Curran (cjcurran)

For more details, see:
https://code.launchpad.net/~ted/indicator-session/menu-reshuffle/+merge/67071

Fixing names
-- 
https://code.launchpad.net/~ted/indicator-session/menu-reshuffle/+merge/67071
Your team ayatana-commits is subscribed to branch lp:indicator-session.
=== modified file 'src/Makefile.am'
--- src/Makefile.am	2011-05-26 15:54:30 +0000
+++ src/Makefile.am	2011-07-06 18:13:39 +0000
@@ -14,7 +14,7 @@
 	gen-session-dbus.xml.h \
 	dbus-shared-names.h \
 	dbusmenu-shared.h \
-	users-service-client.h
+	users-service-client.h 
 libsession_la_CFLAGS = \
 	$(APPLET_CFLAGS) \
 	-Wall -Werror \
@@ -140,7 +140,7 @@
 	upower-client.h \
 	users-service-client.h \
 	users-service-marshal.h \
-	users-service-marshal.c
+	users-service-marshal.c 
 
 EXTRA_DIST = \
 	consolekit-manager.xml \

=== modified file 'src/dbus-shared-names.h'
--- src/dbus-shared-names.h	2011-01-14 03:07:18 +0000
+++ src/dbus-shared-names.h	2011-07-06 18:13:39 +0000
@@ -24,12 +24,7 @@
 #ifndef __DBUS_SHARED_NAMES_H__
 #define __DBUS_SHARED_NAMES_H__ 1
 
-#define INDICATOR_STATUS_DBUS_NAME  "com.canonical.indicator.status"
-#define INDICATOR_STATUS_DBUS_OBJECT "/com/canonical/indicator/status/menu"
-#define INDICATOR_STATUS_SERVICE_DBUS_OBJECT "/com/canonical/indicator/status/service"
-#define INDICATOR_STATUS_SERVICE_DBUS_INTERFACE "com.canonical.indicator.status.service"
-
-#define INDICATOR_USERS_DBUS_NAME  "com.canonical.indicator.users"
+#define INDICATOR_USERS_DBUS_NAME  INDICATOR_SESSION_DBUS_NAME
 #define INDICATOR_USERS_DBUS_OBJECT "/com/canonical/indicator/users/menu"
 #define INDICATOR_USERS_SERVICE_DBUS_OBJECT "/org/gnome/DisplayManager/UserManager"
 #define INDICATOR_USERS_SERVICE_DBUS_INTERFACE "org.gnome.DisplayManager.UserManager"

=== modified file 'src/indicator-session.c'
--- src/indicator-session.c	2011-05-26 15:54:30 +0000
+++ src/indicator-session.c	2011-07-06 18:13:39 +0000
@@ -20,6 +20,7 @@
 with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+//TODO - remember to reinsert Ted's comments.
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -61,8 +62,8 @@
 struct _IndicatorSession {
 	IndicatorObject parent;
 	IndicatorServiceManager * service;
-	GtkImage * status_image;
-	DbusmenuGtkMenu * menu;
+  IndicatorObjectEntry users;
+  IndicatorObjectEntry devices;
 	GCancellable * service_proxy_cancel;
 	GDBusProxy * service_proxy;
 };
@@ -74,15 +75,24 @@
 INDICATOR_SET_TYPE(INDICATOR_SESSION_TYPE)
 
 /* Prototypes */
-static GtkLabel * get_label (IndicatorObject * io);
-static GtkImage * get_icon (IndicatorObject * io);
-static GtkMenu * get_menu (IndicatorObject * io);
-static const gchar * get_accessible_desc (IndicatorObject * io);
-static gboolean build_menu_switch (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
-static gboolean new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
-static void icon_changed (IndicatorSession * session, const gchar * icon_name);
+static gboolean build_menu_switch (DbusmenuMenuitem * newitem,
+                                   DbusmenuMenuitem * parent,
+                                   DbusmenuClient * client,
+                                   gpointer user_data);
+static gboolean new_user_item (DbusmenuMenuitem * newitem,
+                               DbusmenuMenuitem * parent,
+                               DbusmenuClient * client,
+                               gpointer user_data);
+static void user_property_change (DbusmenuMenuitem * item,
+                                  const gchar * property,
+                                  GVariant * variant,
+                                  gpointer user_data);
+                               
+static gboolean build_restart_item (DbusmenuMenuitem * newitem,
+                                    DbusmenuMenuitem * parent,
+                                    DbusmenuClient * client,
+                                    gpointer user_data);
 static void service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data);
-static gboolean build_restart_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data);
 static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data);
 static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data);
 
@@ -90,6 +100,7 @@
 static void indicator_session_init       (IndicatorSession *self);
 static void indicator_session_dispose    (GObject *object);
 static void indicator_session_finalize   (GObject *object);
+static GList* indicator_session_get_entries (IndicatorObject* obj);
 
 G_DEFINE_TYPE (IndicatorSession, indicator_session, INDICATOR_OBJECT_TYPE);
 
@@ -102,81 +113,66 @@
 	object_class->finalize = indicator_session_finalize;
 
 	IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass);
-	io_class->get_label = get_label;
-	io_class->get_image = get_icon;
-	io_class->get_menu = get_menu;
-	io_class->get_accessible_desc = get_accessible_desc;
-
+  io_class->get_entries = indicator_session_get_entries;
 	return;
 }
 
 static void
 indicator_session_init (IndicatorSession *self)
 {
-	/* Set good defaults */
 	self->service = NULL;
 	self->service_proxy_cancel = NULL;
 	self->service_proxy = NULL;
-
+  
 	/* Now let's fire these guys up. */
-	self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_VERSION);
-	g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(service_connection_cb), self);
-
-	self->status_image = indicator_image_helper(ICON_DEFAULT);
-	self->menu = dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME, INDICATOR_SESSION_DBUS_OBJECT);
-
-	DbusmenuClient * client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(self->menu));
-	dbusmenu_client_add_type_handler(client, MENU_SWITCH_TYPE, build_menu_switch);
-	dbusmenu_client_add_type_handler(client, USER_ITEM_TYPE, new_user_item);
-	dbusmenu_client_add_type_handler(client, RESTART_ITEM_TYPE, build_restart_item);
-
+	self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME,
+                                                        INDICATOR_SESSION_DBUS_VERSION);
+	g_signal_connect(G_OBJECT(self->service),
+                   INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE,
+                   G_CALLBACK(service_connection_cb), self);
+  // users
+  self->users.menu =  GTK_MENU (dbusmenu_gtkmenu_new (INDICATOR_USERS_DBUS_NAME,
+                                                      INDICATOR_USERS_DBUS_OBJECT));
+  self->users.label = GTK_LABEL (gtk_label_new ("Users"));
+
+  // devices
+  self->devices.menu = GTK_MENU (dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME,
+                                                      INDICATOR_SESSION_DBUS_OBJECT));
+  self->devices.label = GTK_LABEL (gtk_label_new ("Devices"));
+  
+  gtk_widget_show (GTK_WIDGET(self->devices.menu));
+  gtk_widget_show (GTK_WIDGET(self->devices.label));
+  gtk_widget_show (GTK_WIDGET(self->users.label));
+  gtk_widget_show (GTK_WIDGET(self->users.menu));
+  
+  g_object_ref (self->users.menu);
+  g_object_ref (self->devices.menu);
+  
+  // Setup the handlers for users
+	DbusmenuClient * users_client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(DBUSMENU_GTKMENU(self->users.menu)));
+	dbusmenu_client_add_type_handler(users_client, USER_ITEM_TYPE, new_user_item);
+	dbusmenu_client_add_type_handler(users_client, MENU_SWITCH_TYPE, build_menu_switch);
+  
+  // Setup the handlers for devices
+	DbusmenuClient * devices_client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(DBUSMENU_GTKMENU(self->devices.menu)));
+	dbusmenu_client_add_type_handler (devices_client,
+                                    RESTART_ITEM_TYPE,
+                                    build_restart_item);
+  
 	GtkAccelGroup * agroup = gtk_accel_group_new();
-	dbusmenu_gtkclient_set_accel_group(DBUSMENU_GTKCLIENT(client), agroup);
+	dbusmenu_gtkclient_set_accel_group(DBUSMENU_GTKCLIENT(devices_client), agroup);
 
 	self->service_proxy_cancel = g_cancellable_new();
 
 	g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
-		                  G_DBUS_PROXY_FLAGS_NONE,
-		                  NULL,
-		                  INDICATOR_SESSION_DBUS_NAME,
-		                  INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
-		                  INDICATOR_SESSION_SERVICE_DBUS_IFACE,
-		                  self->service_proxy_cancel,
-		                  service_proxy_cb,
-	                          self);
-
-	return;
-}
-
-/* Callback from trying to create the proxy for the serivce, this
-   could include starting the service.  Sometime it'll fail and
-   we'll try to start that dang service again! */
-static void
-service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
-{
-	GError * error = NULL;
-
-	IndicatorSession * self = INDICATOR_SESSION(user_data);
-	g_return_if_fail(self != NULL);
-
-	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
-
-	if (self->service_proxy_cancel != NULL) {
-		g_object_unref(self->service_proxy_cancel);
-		self->service_proxy_cancel = NULL;
-	}
-
-	if (error != NULL) {
-		g_warning("Could not grab DBus proxy for %s: %s", INDICATOR_SESSION_DBUS_NAME, error->message);
-		g_error_free(error);
-		return;
-	}
-
-	/* Okay, we're good to grab the proxy at this point, we're
-	sure that it's ours. */
-	self->service_proxy = proxy;
-
-	g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
+	      	                  G_DBUS_PROXY_FLAGS_NONE,
+		                        NULL,
+		                        INDICATOR_SESSION_DBUS_NAME,
+		                        INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
+		                        INDICATOR_SESSION_SERVICE_DBUS_IFACE,
+		                        self->service_proxy_cancel,
+		                        service_proxy_cb,
+                            self);
 
 	return;
 }
@@ -201,6 +197,14 @@
 		g_object_unref(self->service_proxy_cancel);
 		self->service_proxy_cancel = NULL;
 	}
+  
+  if (self->users.menu != NULL) {
+    g_object_unref (self->users.menu);
+  }
+  
+  if (self->devices.menu != NULL) {
+    g_object_unref (self->devices.menu);
+  }
 
 	G_OBJECT_CLASS (indicator_session_parent_class)->dispose (object);
 	return;
@@ -214,105 +218,65 @@
 	return;
 }
 
+/* Callback from trying to create the proxy for the service, this
+   could include starting the service.  Sometime it'll fail and
+   we'll try to start that dang service again! */
 static void
-icon_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data)
+service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data)
 {
-	IndicatorSession * self = INDICATOR_SESSION(user_data);
 	GError * error = NULL;
-	gchar * name;
-	GVariant * result;
-
-	result = g_dbus_proxy_call_finish(self->service_proxy, res, &error);
+
+	IndicatorSession * self = INDICATOR_SESSION(user_data);
+	g_return_if_fail(self != NULL);
+
+	GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+
+	if (self->service_proxy_cancel != NULL) {
+		g_object_unref(self->service_proxy_cancel);
+		self->service_proxy_cancel = NULL;
+	}
 
 	if (error != NULL) {
-		return;
-	}
-
-	g_variant_get(result, "(&s)", &name);
-
-	if (name == NULL || name[0] == '\0') {
-		return;
-	}
-
-	indicator_image_helper_update(self->status_image, name);
-	return;
-}
-
-static void
-service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
-{
-	IndicatorSession * self = INDICATOR_SESSION(user_data);
-
-	if (connected) {
-		g_dbus_proxy_call(self->service_proxy, "GetIcon", NULL,
-		                  G_DBUS_CALL_FLAGS_NONE, -1, NULL,
-		                  icon_name_get_cb, user_data);
-	} else {
-		indicator_image_helper_update(self->status_image, ICON_DEFAULT);
-	}
-
-	return;
-}
-
-static GtkLabel *
-get_label (IndicatorObject * io)
-{
-	return NULL;
-}
-
-static const gchar *
-get_accessible_desc (IndicatorObject * io)
-{
-	return _("Session");
-}
-
-static void
-icon_changed (IndicatorSession * session, const gchar * icon_name)
-{
-	indicator_image_helper_update(session->status_image, icon_name);
-	return;
-}
-
-/* Receives all signals from the service, routed to the appropriate functions */
-static void
-receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
-                GVariant * parameters, gpointer user_data)
-{
-	IndicatorSession * self = INDICATOR_SESSION(user_data);
-
-	if (g_strcmp0(signal_name, "IconUpdated") == 0) {
-		const gchar *name;
-		g_variant_get (parameters, "(&s)", &name);
-		icon_changed(self, name);
-	}
-
-	return;
-}
-
-static GtkImage *
-get_icon (IndicatorObject * io)
-{
-	gtk_widget_show(GTK_WIDGET(INDICATOR_SESSION(io)->status_image));
-	return INDICATOR_SESSION(io)->status_image;
-}
-
-static void
-user_property_change (DbusmenuMenuitem * item, const gchar * property, GVariant * variant, gpointer user_data)
-{
-	if (g_strcmp0(property, USER_ITEM_PROP_LOGGED_IN) == 0) {
-		if (g_variant_get_boolean(variant)) {
-			gtk_widget_show(GTK_WIDGET(user_data));
-		} else {
-			gtk_widget_hide(GTK_WIDGET(user_data));
-		}
-	}
-	return;
+		g_warning("Could not grab DBus proxy for %s: %s", INDICATOR_SESSION_DBUS_NAME, error->message);
+		g_error_free(error);
+		return;
+	}
+
+	/* Okay, we're good to grab the proxy at this point, we're
+	sure that it's ours. */
+	self->service_proxy = proxy;
+
+	g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
+
+	return;
+}
+
+
+static GList*
+indicator_session_get_entries (IndicatorObject* obj)
+{
+	g_return_val_if_fail(IS_INDICATOR_SESSION(obj), NULL);
+  IndicatorSession* self = INDICATOR_SESSION (obj);
+  
+	GList * retval = NULL;
+
+  retval = g_list_prepend (retval, &self->users);
+  retval = g_list_prepend (retval, &self->devices);
+
+	if (retval != NULL) {
+		retval = g_list_reverse(retval);
+	}
+	return retval;  
 }
 
 /* Builds an item with a hip little logged in icon. */
 static gboolean
-new_user_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
+new_user_item (DbusmenuMenuitem * newitem,
+               DbusmenuMenuitem * parent,
+               DbusmenuClient * client,
+               gpointer user_data)
 {
+  g_debug ("new user item  called ");
 	GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
 	gint padding = 0;
 	gtk_widget_style_get(GTK_WIDGET(gmi), "horizontal-padding", &padding, NULL);
@@ -369,22 +333,99 @@
 
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
 
-	g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(user_property_change), icon);
+	g_signal_connect (G_OBJECT(newitem),
+                    DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED,
+                    G_CALLBACK(user_property_change), icon);
 
 	return TRUE;
 }
 
-/* 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. */
-static GtkMenu *
-get_menu (IndicatorObject * io)
-{
-	return GTK_MENU(INDICATOR_SESSION(io)->menu);
-}
-
-static void
-switch_property_change (DbusmenuMenuitem * item, const gchar * property, GVariant * variant, gpointer user_data)
+static void
+user_property_change (DbusmenuMenuitem * item,
+                      const gchar * property,
+                      GVariant * variant,
+                      gpointer user_data)
+{
+	if (g_strcmp0(property, USER_ITEM_PROP_LOGGED_IN) == 0) {
+		if (g_variant_get_boolean(variant)) {
+			gtk_widget_show(GTK_WIDGET(user_data));
+		} else {
+			gtk_widget_hide(GTK_WIDGET(user_data));
+		}
+	}
+	return;
+}
+
+
+static void
+icon_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data)
+{
+	IndicatorSession * self = INDICATOR_SESSION(user_data);
+	GError * error = NULL;
+	gchar * name;
+	GVariant * result;
+
+	result = g_dbus_proxy_call_finish(self->service_proxy, res, &error);
+
+	if (error != NULL) {
+		return;
+	}
+
+	g_variant_get(result, "(&s)", &name);
+
+	if (name == NULL || name[0] == '\0') {
+		return;
+	}
+
+	indicator_image_helper_update(self->users.image, name);
+	return;
+}
+
+static void
+service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data)
+{
+	IndicatorSession * self = INDICATOR_SESSION (user_data);
+
+	if (connected) {
+		g_dbus_proxy_call(self->service_proxy, "GetIcon", NULL,
+		                  G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+		                  icon_name_get_cb, user_data);
+	} else {
+		indicator_image_helper_update(self->users.image, ICON_DEFAULT);
+	}
+
+	return;
+}
+
+static void
+icon_changed (IndicatorSession * session, const gchar * icon_name)
+{
+	indicator_image_helper_update(session->users.image, icon_name);
+	return;
+}
+
+/* Receives all signals from the service, routed to the appropriate functions */
+static void
+receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name,
+                GVariant * parameters, gpointer user_data)
+{
+	IndicatorSession * self = INDICATOR_SESSION(user_data);
+
+	if (g_strcmp0(signal_name, "IconUpdated") == 0) {
+		const gchar *name;
+		g_variant_get (parameters, "(&s)", &name);
+		icon_changed(self, name);
+	}
+
+	return;
+}
+
+
+static void
+switch_property_change (DbusmenuMenuitem * item,
+                        const gchar * property,
+                        GVariant * variant,
+                        gpointer user_data)
 {
 	if (g_strcmp0(property, MENU_SWITCH_USER) != 0) {
 		return;
@@ -395,17 +436,11 @@
 	gboolean set_ellipsize = FALSE;
 	gboolean no_name_in_lang = FALSE;
 
-	/* TRANSLATORS: Translate the '1' below into anything other than
-	   '1' if "Switch From %s..." doesn't make sense in your language.
-	   Instead, the string "Switch User..." will be used. */
 	const gchar * translate = C_("session_menu:switchfrom", "1");
 	if (g_strcmp0(translate, "1") != 0) {
 		no_name_in_lang = TRUE;
 	}
 
-	/* If there's a NULL string of some type, then we want to
-	   go back to our old 'Switch User' which isn't great but
-	   eh, this error condition should never happen. */
 	if (variant == NULL || g_variant_get_string(variant, NULL) == NULL || g_variant_get_string(variant, NULL)[0] == '\0' || no_name_in_lang) {
 		finalstring = _("Switch User...");
 		set_ellipsize = FALSE;
@@ -434,8 +469,6 @@
 		gdouble ems = width / pixels_per_em;
 		g_debug("Username width %fem", ems);
 
-		/* TODO: We need some way to remove the elipsis from appearing
-		         twice in the label.  Not sure how to do that yet. */
 		finalstring = g_strdup_printf(_("Switch From %s..."), username);
 		if (ems >= 20.0f) {
 			set_ellipsize = TRUE;
@@ -460,10 +493,11 @@
 
 static const gchar * dbusmenu_item_data = "dbusmenu-item";
 
-/* IF the label or icon changes we need to grab that and update
-   the menu item */
 static void
-restart_property_change (DbusmenuMenuitem * item, const gchar * property, GVariant * variant, gpointer user_data)
+restart_property_change (DbusmenuMenuitem * item,
+                         const gchar * property,
+                         GVariant * variant,
+                         gpointer user_data)
 {
 	DbusmenuGtkClient * client = DBUSMENU_GTKCLIENT(user_data);
 	GtkMenuItem * gmi = dbusmenu_gtkclient_menuitem_get(client, item);
@@ -482,14 +516,14 @@
 		}
 		g_object_unref(G_OBJECT(gicon));
 	}
-
 	return;
 }
 
-/* Builds the restart item which is a more traditional GTK image
-   menu item that puts the graphic into the gutter. */
 static gboolean
-build_restart_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
+build_restart_item (DbusmenuMenuitem * newitem,
+                    DbusmenuMenuitem * parent,
+                    DbusmenuClient * client,
+                    gpointer user_data)
 {
 	GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_image_menu_item_new());
 	if (gmi == NULL) {
@@ -500,7 +534,6 @@
 
 	g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(restart_property_change), client);
 
-	/* Grab the inital variants and put them into the item */
 	GVariant * variant;
 	variant = dbusmenu_menuitem_property_get_variant(newitem, RESTART_ITEM_LABEL);
 	if (variant != NULL) {
@@ -515,24 +548,27 @@
 	return TRUE;
 }
 
-
-/* Callback for when the style changes so we can reevaluate the
-   size of the user name with the potentially new font. */
 static void
-switch_style_set (GtkWidget * widget, GtkStyle * prev_style, gpointer user_data)
+switch_style_set (GtkWidget * widget,
+                  GtkStyle * prev_style,
+                  gpointer user_data)
 {
 	DbusmenuGtkClient * client = DBUSMENU_GTKCLIENT(user_data);
-	DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget), dbusmenu_item_data));
+	DbusmenuMenuitem * mi = DBUSMENU_MENUITEM(g_object_get_data(G_OBJECT(widget),
+                                                              dbusmenu_item_data));
 
-	switch_property_change(mi, MENU_SWITCH_USER, dbusmenu_menuitem_property_get_variant(mi, MENU_SWITCH_USER), client);
+	switch_property_change (mi,
+                          MENU_SWITCH_USER,
+                          dbusmenu_menuitem_property_get_variant(mi, MENU_SWITCH_USER),
+                          client);
 	return;
 }
 
-/* This function checks to see if the user name is short enough
-   to not need ellipsing itself, or if, it will get ellipsed by
-   the standard label processor. */
 static gboolean
-build_menu_switch (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data)
+build_menu_switch (DbusmenuMenuitem * newitem,
+                   DbusmenuMenuitem * parent,
+                   DbusmenuClient * client,
+                   gpointer user_data)
 {
 	GtkMenuItem * gmi = GTK_MENU_ITEM(gtk_menu_item_new());
 	if (gmi == NULL) {
@@ -542,9 +578,17 @@
 
 	dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, gmi, parent);
 
-	g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(switch_property_change), client);
-	g_signal_connect(G_OBJECT(gmi), "style-set", G_CALLBACK(switch_style_set), client);
-	switch_property_change(newitem, MENU_SWITCH_USER, dbusmenu_menuitem_property_get_variant(newitem, MENU_SWITCH_USER), client);
+	g_signal_connect (G_OBJECT(newitem),
+                    DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED,
+                    G_CALLBACK(switch_property_change),
+                    client);
+	g_signal_connect (G_OBJECT(gmi),
+                    "style-set",
+                    G_CALLBACK(switch_style_set),
+                    client);
+	switch_property_change (newitem,
+                          MENU_SWITCH_USER,
+                          dbusmenu_menuitem_property_get_variant(newitem, MENU_SWITCH_USER), client);
 
 	return TRUE;
 }

=== modified file 'src/session-service.c'
--- src/session-service.c	2011-05-26 15:54:30 +0000
+++ src/session-service.c	2011-07-06 18:13:39 +0000
@@ -8,6 +8,7 @@
     Ted Gould <ted@xxxxxxxxxxxxx>
     Christoph Korn <c_korn@xxxxxx>
     Cody Russell <crussell@xxxxxxxxxxxxx>
+    Conor Curran <conor.curran@xxxxxxxxxxxxx>
 
 This program is free software: you can redistribute it and/or modify it 
 under the terms of the GNU General Public License version 3, as published 
@@ -80,7 +81,9 @@
 static DbusmenuMenuitem  *lock_menuitem = NULL;
 static DbusmenuMenuitem  *switch_menuitem = NULL;
 
-static DbusmenuMenuitem * root_menuitem = NULL;
+static DbusmenuMenuitem * session_root_menuitem = NULL;
+static DbusmenuMenuitem * users_root_menuitem = NULL;
+
 static GMainLoop * mainloop = NULL;
 static DBusGProxy * up_main_proxy = NULL;
 static DBusGProxy * up_prop_proxy = NULL;
@@ -101,7 +104,8 @@
 
 static GConfClient * gconf_client = NULL;
 
-static void rebuild_items (DbusmenuMenuitem *root, UsersServiceDbus *service);
+static void rebuild_session_items (DbusmenuMenuitem *root, UsersServiceDbus *service);
+static void rebuild_user_items (DbusmenuMenuitem *root, UsersServiceDbus *service);
 
 static void
 lockdown_changed (GConfClient *client,
@@ -117,7 +121,7 @@
 	}
 
 	if (g_strcmp0 (key, LOCKDOWN_KEY_USER) == 0 || g_strcmp0 (key, LOCKDOWN_KEY_SCREENSAVER) == 0) {
-		rebuild_items(root_menuitem, dbus_interface);
+		rebuild_session_items(session_root_menuitem, dbus_interface);
 	}
 
 	return;
@@ -228,7 +232,7 @@
 	gboolean local_can_suspend = g_value_get_boolean(&candoit);
 	if (local_can_suspend != can_suspend) {
 		can_suspend = local_can_suspend;
-		rebuild_items(root_menuitem, dbus_interface);
+		rebuild_session_items(session_root_menuitem, dbus_interface);
 	}
 
 	return;
@@ -253,7 +257,7 @@
 	gboolean local_can_hibernate = g_value_get_boolean(&candoit);
 	if (local_can_hibernate != can_hibernate) {
 		can_hibernate = local_can_hibernate;
-		rebuild_items(root_menuitem, dbus_interface);
+		rebuild_session_items(session_root_menuitem, dbus_interface);
 	}
 
 	return;
@@ -314,7 +318,7 @@
 
 	if (OUT_allowed != *can_do) {
 		*can_do = OUT_allowed;
-		rebuild_items (root_menuitem, dbus_interface);
+		rebuild_session_items (session_root_menuitem, dbus_interface);
 	}
 }
 
@@ -508,18 +512,18 @@
 }
 
 /* Take a desktop file and execute it */
-static void
+/*static void
 desktop_activate_cb (DbusmenuMenuitem * mi, guint timestamp, gpointer data)
 {
 	GAppInfo * appinfo = G_APP_INFO(data);
 	g_return_if_fail(appinfo != NULL);
 	g_app_info_launch(appinfo, NULL, NULL, NULL);
 	return;
-}
+}*/
 
 /* Look at the GAppInfo structures and sort based on
    the application names */
-static gint
+/*static gint
 sort_app_infos (gconstpointer a, gconstpointer b)
 {
 	GAppInfo * appa = G_APP_INFO(a);
@@ -537,12 +541,13 @@
 	}
 
 	return g_strcmp0(namea, nameb);
-}
+}*/
 
 /* Builds up the menu for us */
-static void
-rebuild_items (DbusmenuMenuitem *root,
-               UsersServiceDbus *service)
+
+static void 
+rebuild_user_items (DbusmenuMenuitem *root,
+                    UsersServiceDbus *service)
 {
   DbusmenuMenuitem *mi = NULL;
   DbusmenuMenuitem * guest_mi = NULL;
@@ -569,7 +574,9 @@
   /* Lock screen item */
   if (can_lockscreen) {
 	lock_menuitem = dbusmenu_menuitem_new();
-	dbusmenu_menuitem_property_set(lock_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _("Lock Screen"));
+	dbusmenu_menuitem_property_set (lock_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Lock Screen"));
 
 	gchar * shortcut = gconf_client_get_string(gconf_client, KEY_LOCK_SCREEN, NULL);
 	if (shortcut != NULL) {
@@ -580,7 +587,10 @@
 		g_debug("Unable to get lock screen shortcut.");
 	}
 
-	g_signal_connect(G_OBJECT(lock_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(lock_screen), NULL);
+	g_signal_connect (G_OBJECT(lock_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(lock_screen),
+                    NULL);
 	dbusmenu_menuitem_child_append(root, lock_menuitem);
   }
 
@@ -592,14 +602,22 @@
     {
 		if (can_lockscreen) {
 			DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new();
-			dbusmenu_menuitem_property_set(separator1, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
-			dbusmenu_menuitem_child_append(root, separator1);
+      dbusmenu_menuitem_property_set_bool (separator1,
+                                           DBUSMENU_MENUITEM_PROP_VISIBLE,
+                                           TRUE);
+			dbusmenu_menuitem_property_set (separator1,
+                                      DBUSMENU_MENUITEM_PROP_TYPE,
+                                      DBUSMENU_CLIENT_TYPES_SEPARATOR);
+			dbusmenu_menuitem_child_append (root, separator1);
 		}
 
       if (check_guest_session ())
         {
           guest_mi = dbusmenu_menuitem_new ();
-		  dbusmenu_menuitem_property_set (guest_mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE);
+          dbusmenu_menuitem_property_set_bool (guest_mi,
+                                               DBUSMENU_MENUITEM_PROP_VISIBLE,
+                                               TRUE);
+		      dbusmenu_menuitem_property_set (guest_mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE);
           dbusmenu_menuitem_property_set (guest_mi, USER_ITEM_PROP_NAME, _("Guest Session"));
           dbusmenu_menuitem_property_set_bool (guest_mi, USER_ITEM_PROP_LOGGED_IN, FALSE);
           dbusmenu_menuitem_child_append (root, guest_mi);
@@ -680,53 +698,124 @@
 		dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
 		dbusmenu_menuitem_child_append(root, separator);
 	}
+}
+
+static void
+rebuild_session_items (DbusmenuMenuitem *root,
+                       UsersServiceDbus *service)
+{
+  gboolean can_lockscreen;
+
+  /* Make sure we have a valid GConf client, and build one
+     if needed */
+  ensure_gconf_client ();
+
+  can_lockscreen = !gconf_client_get_bool ( gconf_client,
+                                            LOCKDOWN_KEY_SCREENSAVER,
+                                            NULL);
+  /* Lock screen item */
+  if (can_lockscreen) {
+	lock_menuitem = dbusmenu_menuitem_new();
+	dbusmenu_menuitem_property_set (lock_menuitem,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Lock Screen"));
+
+	gchar * shortcut = gconf_client_get_string(gconf_client, KEY_LOCK_SCREEN, NULL);
+	if (shortcut != NULL) {
+		g_debug("Lock screen shortcut: %s", shortcut);
+		dbusmenu_menuitem_property_set_shortcut_string(lock_menuitem, shortcut);
+		g_free(shortcut);
+	} else {
+		g_debug("Unable to get lock screen shortcut.");
+	}
+
+	g_signal_connect (G_OBJECT(lock_menuitem),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(lock_screen), NULL);
+	dbusmenu_menuitem_child_append(root, lock_menuitem);
+  }
 
 	/* Start going through the session based items. */
 
 	logout_mi = dbusmenu_menuitem_new();
 	if (supress_confirmations()) {
-		dbusmenu_menuitem_property_set(logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out"));
+		dbusmenu_menuitem_property_set (logout_mi,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Log Out"));
 	} else {
-		dbusmenu_menuitem_property_set(logout_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Log Out\342\200\246"));
+		dbusmenu_menuitem_property_set (logout_mi,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Log Out\342\200\246"));
 	}
-	dbusmenu_menuitem_property_set_bool(logout_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_logout());
+	dbusmenu_menuitem_property_set_bool (logout_mi,
+                                       DBUSMENU_MENUITEM_PROP_VISIBLE,
+                                       show_logout());
 	dbusmenu_menuitem_child_append(root, logout_mi);
-	g_signal_connect(G_OBJECT(logout_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "logout");
+	g_signal_connect( G_OBJECT(logout_mi),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_dialog), "logout");
 
 	if (can_suspend && allow_suspend) {
 		suspend_mi = dbusmenu_menuitem_new();
-		dbusmenu_menuitem_property_set(suspend_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Suspend"));
-		dbusmenu_menuitem_child_append(root, suspend_mi);
-		g_signal_connect(G_OBJECT(suspend_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(machine_sleep), "Suspend");
+		dbusmenu_menuitem_property_set (suspend_mi,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Suspend"));
+		dbusmenu_menuitem_child_append (root, suspend_mi);
+		g_signal_connect( G_OBJECT(suspend_mi),
+                      DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                      G_CALLBACK(machine_sleep),
+                      "Suspend");
 	}
 
 	if (can_hibernate && allow_hibernate) {
 		hibernate_mi = dbusmenu_menuitem_new();
-		dbusmenu_menuitem_property_set(hibernate_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Hibernate"));
+		dbusmenu_menuitem_property_set (hibernate_mi,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Hibernate"));
 		dbusmenu_menuitem_child_append(root, hibernate_mi);
-		g_signal_connect(G_OBJECT(hibernate_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(machine_sleep), "Hibernate");
+		g_signal_connect (G_OBJECT(hibernate_mi),
+                      DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                      G_CALLBACK(machine_sleep), "Hibernate");
 	}
 
 	restart_mi = dbusmenu_menuitem_new();
-	dbusmenu_menuitem_property_set(restart_mi, DBUSMENU_MENUITEM_PROP_TYPE, RESTART_ITEM_TYPE);
+	dbusmenu_menuitem_property_set (restart_mi,
+                                  DBUSMENU_MENUITEM_PROP_TYPE,
+                                  RESTART_ITEM_TYPE);
 	if (supress_confirmations()) {
-		dbusmenu_menuitem_property_set(restart_mi, RESTART_ITEM_LABEL, _("Restart"));
+		dbusmenu_menuitem_property_set (restart_mi,
+                                    RESTART_ITEM_LABEL,
+                                    _("Restart"));
 	} else {
-		dbusmenu_menuitem_property_set(restart_mi, RESTART_ITEM_LABEL, _("Restart\342\200\246"));
+		dbusmenu_menuitem_property_set (restart_mi,
+                                    RESTART_ITEM_LABEL,
+                                    _("Restart\342\200\246"));
 	}
-	dbusmenu_menuitem_property_set_bool(restart_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_restart());
+	dbusmenu_menuitem_property_set_bool (restart_mi,
+                                       DBUSMENU_MENUITEM_PROP_VISIBLE,
+                                       show_restart());
 	dbusmenu_menuitem_child_append(root, restart_mi);
-	g_signal_connect(G_OBJECT(restart_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "restart");
+	g_signal_connect (G_OBJECT(restart_mi),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_dialog), "restart");
 
 	shutdown_mi = dbusmenu_menuitem_new();
 	if (supress_confirmations()) {
-		dbusmenu_menuitem_property_set(shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down"));
+		dbusmenu_menuitem_property_set (shutdown_mi,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Shut Down"));
 	} else {
-		dbusmenu_menuitem_property_set(shutdown_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Shut Down\342\200\246"));
+		dbusmenu_menuitem_property_set (shutdown_mi,
+                                    DBUSMENU_MENUITEM_PROP_LABEL,
+                                    _("Shut Down\342\200\246"));
 	}
-	dbusmenu_menuitem_property_set_bool(shutdown_mi, DBUSMENU_MENUITEM_PROP_VISIBLE, show_shutdown());
-	dbusmenu_menuitem_child_append(root, shutdown_mi);
-	g_signal_connect(G_OBJECT(shutdown_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_dialog), "shutdown");
+	dbusmenu_menuitem_property_set_bool (shutdown_mi,
+                                       DBUSMENU_MENUITEM_PROP_VISIBLE,
+                                       show_shutdown());
+	dbusmenu_menuitem_child_append (root, shutdown_mi);
+	g_signal_connect (G_OBJECT(shutdown_mi),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK(show_dialog), "shutdown");
 
 	RestartShutdownLogoutMenuItems * restart_shutdown_logout_mi = g_new0 (RestartShutdownLogoutMenuItems, 1);
 	restart_shutdown_logout_mi->logout_mi = logout_mi;
@@ -735,61 +824,6 @@
 
 	update_menu_entries(restart_shutdown_logout_mi);
 
-	/* now add extra launchers */
-	GDir *extra_launchers_dir;
-	extra_launchers_dir = g_dir_open (EXTRA_LAUNCHER_DIR, 0, NULL);
-	if (extra_launchers_dir != NULL) {
-		GList * launchers = NULL;
-
-		/* Find all the desktop files we want to use */
-		for (;;) {
-			const gchar *extra_launcher_file;
-
-			extra_launcher_file = g_dir_read_name (extra_launchers_dir);
-			if (extra_launcher_file == NULL)
-				break;
-			if (!g_str_has_suffix (extra_launcher_file, ".desktop"))
-				continue;
-
-			gchar *full_path = g_build_filename (EXTRA_LAUNCHER_DIR, extra_launcher_file, NULL);
-			GAppInfo * appinfo = G_APP_INFO(g_desktop_app_info_new_from_filename (full_path));
-			g_free (full_path);
-
-			launchers = g_list_prepend(launchers, appinfo);
-		}
-		g_dir_close(extra_launchers_dir);
-
-		/* Sort the desktop files based on their names */
-		launchers = g_list_sort(launchers, sort_app_infos);
-
-		/* Turn each one into a separate menu item */
-		GList * launcher = NULL;
-		gboolean sepadded = FALSE;
-		for (launcher = launchers; launcher != NULL; launcher = g_list_next(launcher)) {
-			GAppInfo * appinfo = G_APP_INFO(launcher->data);
-
-			/* Make sure we have a separator */
-			if (!sepadded) {
-				DbusmenuMenuitem * separator = dbusmenu_menuitem_new();
-				dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
-				dbusmenu_menuitem_child_append(root, separator);
-				g_object_unref(separator);
-				sepadded = TRUE;
-			}
-
-			/* Build the item */
-			DbusmenuMenuitem * desktop_mi = dbusmenu_menuitem_new();
-			dbusmenu_menuitem_property_set(desktop_mi, DBUSMENU_MENUITEM_PROP_LABEL, g_app_info_get_name(appinfo));
-			g_signal_connect(G_OBJECT(desktop_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(desktop_activate_cb), appinfo);
-			g_object_weak_ref(G_OBJECT(desktop_mi), (GWeakNotify)g_object_unref, appinfo);
-
-			/* Put into the menu */
-			dbusmenu_menuitem_child_append(root, desktop_mi);
-		}
-
-		g_list_free(launchers);
-	}
-
 	return;
 }
 
@@ -801,7 +835,7 @@
              gpointer          user_data)
 {
 	DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
-	rebuild_items (root, service);
+	rebuild_user_items (root, service);
 	return;
 }
 
@@ -869,7 +903,7 @@
 int
 main (int argc, char ** argv)
 {
-    g_type_init();
+  g_type_init();
 
 	/* Setting up i18n and gettext.  Apparently, we need
 	   all of these. */
@@ -887,32 +921,37 @@
 
 	g_idle_add(lock_screen_setup, NULL);
 
-    root_menuitem = dbusmenu_menuitem_new();
-	g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem));
-
-    dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL);
-
-    rebuild_items (root_menuitem, dbus_interface);
-
-    g_signal_connect (G_OBJECT (dbus_interface),
-                      "user-added",
-                      G_CALLBACK (user_change),
-                      root_menuitem);
-    g_signal_connect (G_OBJECT (dbus_interface),
-                      "user-removed",
-                      G_CALLBACK (user_change),
-                      root_menuitem);
-
-	setup_restart_watch();
-
+  session_root_menuitem = dbusmenu_menuitem_new();
+	g_debug("Session Root ID: %d", dbusmenu_menuitem_get_id(session_root_menuitem));
+
+  dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL);
+
+  rebuild_session_items (session_root_menuitem, dbus_interface);
+
+
+  DbusmenuServer * server = dbusmenu_server_new(INDICATOR_SESSION_DBUS_OBJECT);
+  dbusmenu_server_set_root(server, session_root_menuitem);
+    
+  users_root_menuitem = dbusmenu_menuitem_new();
+  rebuild_user_items (users_root_menuitem, dbus_interface);
+  g_signal_connect (G_OBJECT (dbus_interface),
+                    "user-added",
+                    G_CALLBACK (user_change),
+                    users_root_menuitem);
+  g_signal_connect (G_OBJECT (dbus_interface),
+                    "user-removed",
+                    G_CALLBACK (user_change),
+                    users_root_menuitem);
+  
+  setup_restart_watch();
 	setup_up();
 
-    DbusmenuServer * server = dbusmenu_server_new(INDICATOR_SESSION_DBUS_OBJECT);
-    dbusmenu_server_set_root(server, root_menuitem);
-
-    mainloop = g_main_loop_new(NULL, FALSE);
-    g_main_loop_run(mainloop);
-
-    return 0;
+  DbusmenuServer * users_server = dbusmenu_server_new (INDICATOR_USERS_DBUS_OBJECT);
+  dbusmenu_server_set_root (users_server, users_root_menuitem);
+
+  mainloop = g_main_loop_new(NULL, FALSE);
+  g_main_loop_run(mainloop);
+  
+  return 0;
 }
 

=== modified file 'src/users-service-dbus.c'
--- src/users-service-dbus.c	2010-09-01 20:22:20 +0000
+++ src/users-service-dbus.c	2011-07-06 18:13:39 +0000
@@ -586,7 +586,6 @@
   g_return_if_fail(IS_USERS_SERVICE_DBUS(service));
   UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service);
   uid_t          uid;
-  gboolean       res;
   struct passwd *pwent;
   UserData      *user;
 
@@ -621,7 +620,7 @@
       return;
     }
 
-  res = do_add_session (service, user, session_id);
+  do_add_session (service, user, session_id);
 }
 
 static void


Follow ups