← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~cjcurran/indicator-session/split-out-users into lp:indicator-session

 

Conor Curran has proposed merging lp:~cjcurran/indicator-session/split-out-users into lp:indicator-session.

Requested reviews:
  Ted Gould (ted)

For more details, see:
https://code.launchpad.net/~cjcurran/indicator-session/split-out-users/+merge/68110

Moves all the user menu stuff into its own gobject. The aim being to tidy the session service file so it becomes essentially just a main. 

Next up i will do a branch called "split out the device-menu-mgr", will do this monday and then we are ready to start adding the new devices/udev functionality.

Nothing worse than adding new code on top of stuff which really needs to be ripped apart.  
-- 
https://code.launchpad.net/~cjcurran/indicator-session/split-out-users/+merge/68110
Your team ayatana-commits is subscribed to branch lp:indicator-session.
=== modified file 'src/Makefile.am'
--- src/Makefile.am	2011-07-12 15:03:02 +0000
+++ src/Makefile.am	2011-07-15 15:41:18 +0000
@@ -91,7 +91,9 @@
 	dbusmenu-shared.h \
 	gconf-helper.c \
 	users-service-dbus.h \
-	users-service-dbus.c
+	users-service-dbus.c \
+	user-menu-mgr.h \
+	user-menu-mgr.c 	
 indicator_session_service_CFLAGS = \
 	$(SESSIONSERVICE_CFLAGS) \
 	$(GCONF_CFLAGS) \

=== modified file 'src/gconf-helper.h'
--- src/gconf-helper.h	2010-04-06 22:24:42 +0000
+++ src/gconf-helper.h	2011-07-15 15:41:18 +0000
@@ -39,6 +39,12 @@
 #define RESTART_KEY     GLOBAL_DIR "/suppress_restart_menuitem"
 #define SHUTDOWN_KEY    GLOBAL_DIR "/suppress_shutdown_menuitem"
 
+#define LOCKDOWN_DIR              "/desktop/gnome/lockdown"
+#define LOCKDOWN_KEY_USER         LOCKDOWN_DIR "/disable_user_switching"
+#define LOCKDOWN_KEY_SCREENSAVER  LOCKDOWN_DIR "/disable_lock_screen"
+#define KEYBINDING_DIR            "/apps/gnome_settings_daemon/keybindings"
+#define KEY_LOCK_SCREEN           KEYBINDING_DIR "/screensaver"
+
 typedef struct _RestartShutdownLogoutMenuItems
 {
 	DbusmenuMenuitem * logout_mi;

=== modified file 'src/session-service.c'
--- src/session-service.c	2011-07-14 15:35:57 +0000
+++ src/session-service.c	2011-07-15 15:41:18 +0000
@@ -43,11 +43,12 @@
 
 #include "dbus-shared-names.h"
 #include "dbusmenu-shared.h"
+#include "users-service-dbus.h"
+#include "user-menu-mgr.h"
 
 #include "gconf-helper.h"
 
 #include "session-dbus.h"
-#include "users-service-dbus.h"
 #include "lock-helper.h"
 #include "upower-client.h"
 
@@ -57,12 +58,6 @@
 
 #define EXTRA_LAUNCHER_DIR "/usr/share/indicators/session/applications"
 
-#define LOCKDOWN_DIR              "/desktop/gnome/lockdown"
-#define LOCKDOWN_KEY_USER         LOCKDOWN_DIR "/disable_user_switching"
-#define LOCKDOWN_KEY_SCREENSAVER  LOCKDOWN_DIR "/disable_lock_screen"
-
-#define KEYBINDING_DIR            "/apps/gnome_settings_daemon/keybindings"
-#define KEY_LOCK_SCREEN           KEYBINDING_DIR "/screensaver"
 
 typedef struct _ActivateData ActivateData;
 struct _ActivateData
@@ -71,14 +66,10 @@
   UserData *user;
 };
 
-static UsersServiceDbus  *dbus_interface = NULL;
+//static UsersServiceDbus  *dbus_interface = NULL;
 static SessionDbus       *session_dbus = NULL;
-
 static DbusmenuMenuitem  *lock_menuitem = NULL;
-static DbusmenuMenuitem  *switch_menuitem = NULL;
-
 static DbusmenuMenuitem * session_root_menuitem = NULL;
-static DbusmenuMenuitem * users_root_menuitem = NULL;
 
 static GMainLoop * mainloop = NULL;
 static DBusGProxy * up_main_proxy = NULL;
@@ -100,9 +91,7 @@
 
 static GConfClient * gconf_client = NULL;
 
-static void rebuild_session_items (DbusmenuMenuitem *root, UsersServiceDbus *service);
-static void rebuild_user_items (DbusmenuMenuitem *root, UsersServiceDbus *service);
-static void activate_online_accounts (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data);
+static void rebuild_session_items (DbusmenuMenuitem *root);
 
 static void
 lockdown_changed (GConfClient *client,
@@ -118,7 +107,7 @@
 	}
 
 	if (g_strcmp0 (key, LOCKDOWN_KEY_USER) == 0 || g_strcmp0 (key, LOCKDOWN_KEY_SCREENSAVER) == 0) {
-		rebuild_session_items(session_root_menuitem, dbus_interface);
+		rebuild_session_items(session_root_menuitem);
 	}
 
 	return;
@@ -170,9 +159,8 @@
 	ensure_gconf_client ();
 
 	if (!gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_SCREENSAVER, NULL)) {
-		lock_screen(NULL, 0, NULL);
+		lock_screen (NULL, 0, NULL);
 	}
-
 	return;
 }
 
@@ -228,7 +216,7 @@
 	gboolean local_can_suspend = g_value_get_boolean(&candoit);
 	if (local_can_suspend != can_suspend) {
 		can_suspend = local_can_suspend;
-		rebuild_session_items(session_root_menuitem, dbus_interface);
+		rebuild_session_items(session_root_menuitem);
 	}
 
 	return;
@@ -253,7 +241,7 @@
 	gboolean local_can_hibernate = g_value_get_boolean(&candoit);
 	if (local_can_hibernate != can_hibernate) {
 		can_hibernate = local_can_hibernate;
-		rebuild_session_items(session_root_menuitem, dbus_interface);
+		rebuild_session_items(session_root_menuitem);
 	}
 
 	return;
@@ -314,7 +302,7 @@
 
 	if (OUT_allowed != *can_do) {
 		*can_do = OUT_allowed;
-		rebuild_session_items (session_root_menuitem, dbus_interface);
+		rebuild_session_items (session_root_menuitem);
 	}
 }
 
@@ -391,216 +379,10 @@
 	return;
 }
 
-/* Checks to see if we can create sessions */
-static gboolean
-check_new_session (void)
-{
-	return TRUE;
-}
-
-/* Starts a new generic session */
-static void
-activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data)
-{
-	lock_if_possible();
-
-    users_service_dbus_show_greeter (USERS_SERVICE_DBUS(user_data));
-
-	return;
-}
-
-/* Activates a session for a particular user. */
-static void
-activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data)
-{
-  UserData *user = (UserData *)user_data;
-  UsersServiceDbus *service = user->service;
-
-  lock_if_possible();
-
-  users_service_dbus_activate_user_session (service, user);
-}
-
-/* Comparison function to look into the UserData struct
-   to compare by using the username value */
-static gint
-compare_users_by_username (const gchar *a,
-                           const gchar *b)
-{
-  UserData *user1 = (UserData *)a;
-  UserData *user2 = (UserData *)b;
-
-  gint retval = g_strcmp0 (user1->real_name, user2->real_name);
-
-  /* If they're the same, they're both in conflict. */
-  if (retval == 0) {
-    user1->real_name_conflict = TRUE;
-    user2->real_name_conflict = TRUE;
-  }
-
-  return retval;
-}
-
-/* Builds up the menu for us */
-static void 
-rebuild_user_items (DbusmenuMenuitem *root,
-                    UsersServiceDbus *service)
-{
-  DbusmenuMenuitem *mi = NULL;
-  DbusmenuMenuitem *guest_mi = NULL;
-  GList *u;
-  UserData *user;
-  gboolean can_activate;
-  GList *children;
-
-  /* Make sure we have a valid GConf client, and build one
-     if needed */
-  ensure_gconf_client ();
-
-  /* Check to see which menu items we're allowed to have */
-  can_activate = users_service_dbus_can_activate_session (service) &&
-      !gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_USER, NULL);
-
-  /* Remove the old menu items if that makes sense */
-  children = dbusmenu_menuitem_take_children (root);
-  g_list_foreach (children, (GFunc)g_object_unref, NULL);
-  g_list_free (children);
-
-  /* Set to NULL just incase we don't end up building one */
-  users_service_dbus_set_guest_item(service, NULL);
-
-  /* Build all of the user switching items */
-  if (can_activate == TRUE)
-  {
-    if (check_new_session ()){
-      switch_menuitem = dbusmenu_menuitem_new ();
-      dbusmenu_menuitem_property_set (switch_menuitem,
-                                      DBUSMENU_MENUITEM_PROP_TYPE,
-                                      MENU_SWITCH_TYPE);
-      dbusmenu_menuitem_property_set (switch_menuitem,
-                                      MENU_SWITCH_USER,
-                                      g_get_user_name());
-      dbusmenu_menuitem_child_append (root, switch_menuitem);
-      g_signal_connect (G_OBJECT (switch_menuitem),
-                        DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
-                        G_CALLBACK (activate_new_session),
-                        service);
-    }
-
-    GList * users = NULL;
-    users = users_service_dbus_get_user_list (service);
-    guint user_count = g_list_length(users);
-    // g_debug ("USER COUNT = %i", user_count);
-    // We only want to show this menu when we have more than one registered 
-    // user
-    session_dbus_set_user_menu_visibility (session_dbus, user_count > 1);
-
-    if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) {
-      users = g_list_sort (users, (GCompareFunc)compare_users_by_username);
-    }
-
-    for (u = users; u != NULL; u = g_list_next (u)) {
-      user = u->data;
-      user->service = service;
-
-      g_debug ("%i %s", (gint)user->uid, user->user_name);
-
-      if (g_strcmp0(user->user_name, "guest") == 0) {
-        /* Check to see if the guest has sessions and so therefore should
-           get a check mark. */
-        if (user->sessions != NULL) {
-          dbusmenu_menuitem_property_set_bool (guest_mi,
-                                               USER_ITEM_PROP_LOGGED_IN,
-                                               TRUE);
-        }
-        /* If we're showing user accounts, keep going through the list */
-        if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) {
-          continue;
-        }
-        /* If not, we can stop here */
-        break;
-      }
-
-      if (user_count > MINIMUM_USERS && user_count < MAXIMUM_USERS) {
-        mi = dbusmenu_menuitem_new ();
-        dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE);
-        if (user->real_name_conflict) {
-          gchar * conflictedname = g_strdup_printf("%s (%s)", user->real_name, user->user_name);
-          dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, conflictedname);
-          g_free(conflictedname);
-        } else {
-          dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, user->real_name);
-        }
-        dbusmenu_menuitem_property_set_bool (mi,
-                                             USER_ITEM_PROP_LOGGED_IN,
-                                             user->sessions != NULL);
-        if (user->icon_file != NULL && user->icon_file[0] != '\0') {
-          dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, user->icon_file);
-        } else {
-          dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, USER_ITEM_ICON_DEFAULT);
-        }
-        
-        gboolean logged_in = g_strcmp0 (user->user_name, g_get_user_name()) == 0;       
-        dbusmenu_menuitem_property_set_bool (mi,
-                                             USER_ITEM_PROP_IS_CURRENT_USER,
-                                             logged_in);          
-        if (logged_in == TRUE){
-          g_debug ("about to set the users real name to %s for user %s",
-                    user->real_name, user->user_name);
-          session_dbus_set_users_real_name (session_dbus, user->real_name);
-        }
-        
-        dbusmenu_menuitem_child_append (root, mi);
-        g_signal_connect (G_OBJECT (mi),
-                          DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
-                          G_CALLBACK (activate_user_session),
-                          user);
-        user->menuitem = mi;
-      }
-    }
-    g_list_free(users);
-  }
-  // Add the online accounts and separator
-  DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new();
-  dbusmenu_menuitem_property_set (separator1,
-                                  DBUSMENU_MENUITEM_PROP_TYPE,
-                                  DBUSMENU_CLIENT_TYPES_SEPARATOR);
-  dbusmenu_menuitem_child_append (root, separator1);
-  DbusmenuMenuitem * online_accounts_item = dbusmenu_menuitem_new();
-  dbusmenu_menuitem_property_set (online_accounts_item,
-                                  DBUSMENU_MENUITEM_PROP_TYPE,
-                                  DBUSMENU_CLIENT_TYPES_DEFAULT);
-  dbusmenu_menuitem_property_set (online_accounts_item,
-                                  DBUSMENU_MENUITEM_PROP_LABEL,
-                                  _("Online Accounts..."));
-
-  g_signal_connect (G_OBJECT (online_accounts_item),
-                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
-                    G_CALLBACK (activate_online_accounts),
-                    NULL);
-                                  
-  dbusmenu_menuitem_child_append (root, online_accounts_item);    
-}
-
-// TODO
-// Wait until dialog is complete to find out name to pass
-// to the control centre.
-static void
-activate_online_accounts (DbusmenuMenuitem *mi,
-                          guint timestamp,
-                          gpointer user_data)
-{
-  GError * error = NULL;
-  if (!g_spawn_command_line_async("gnome-control-center online-accounts", &error))
-  {
-    g_warning("Unable to show control centre: %s", error->message);
-    g_error_free(error);
-  }
-}
-
-static void
-rebuild_session_items (DbusmenuMenuitem *root,
-                       UsersServiceDbus *service)
+
+static void
+rebuild_session_items (DbusmenuMenuitem *root)
+                       
 {
   gboolean can_lockscreen;
 
@@ -725,17 +507,6 @@
 	return;
 }
 
-/* Signal called when a user is added.  It updates the count and
-   rebuilds the menu */
-static void
-user_change (UsersServiceDbus *service,
-             const gchar      *user_id,
-             gpointer          user_data)
-{
-	DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
-	rebuild_user_items (root, service);
-	return;
-}
 
 /* When the service interface starts to shutdown, we
    should follow it. */
@@ -819,32 +590,20 @@
 	g_idle_add(lock_screen_setup, NULL);
 
   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);
+  rebuild_session_items (session_root_menuitem);
 
   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);
-  
+  // Users
+  UserMenuMgr* user_mgr = user_menu_mgr_new (session_dbus);
+    
   setup_restart_watch();
-
 	setup_up();
 
-  DbusmenuServer * users_server = dbusmenu_server_new (INDICATOR_USERS_DBUS_OBJECT);
-  dbusmenu_server_set_root (users_server, users_root_menuitem);
+  DbusmenuServer* users_server = dbusmenu_server_new (INDICATOR_USERS_DBUS_OBJECT);
+  
+  dbusmenu_server_set_root (users_server, user_mgr_get_root_item (user_mgr));
 
   mainloop = g_main_loop_new(NULL, FALSE);
   g_main_loop_run(mainloop);

=== added file 'src/user-menu-mgr.c'
--- src/user-menu-mgr.c	1970-01-01 00:00:00 +0000
+++ src/user-menu-mgr.c	2011-07-15 15:41:18 +0000
@@ -0,0 +1,358 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * user-menu-mgr.c
+ * Copyright (C) Conor Curran 2011 <conor.curran@xxxxxxxxxxxxx>
+ * 
+ * user-menu-mgr.c is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * user-menu-mgr.c is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+#include <libdbusmenu-glib/client.h>
+
+#include "user-menu-mgr.h"
+#include "gconf-helper.h"
+#include "dbus-shared-names.h"
+#include "dbusmenu-shared.h"
+#include "lock-helper.h"
+#include "users-service-dbus.h"
+
+static GConfClient * gconf_client = NULL;
+static DbusmenuMenuitem  *switch_menuitem = NULL;
+
+struct _UserMenuMgr
+{
+	GObject parent_instance;
+  UsersServiceDbus* users_dbus_interface;
+  DbusmenuMenuitem* root_item;
+  gint user_count;
+  SessionDbus* session_dbus_interface;  
+};
+
+static void activate_new_session (DbusmenuMenuitem * mi,
+                                  guint timestamp,
+                                  gpointer user_data);
+static void activate_user_session (DbusmenuMenuitem *mi,
+                                   guint timestamp,
+                                   gpointer user_data);
+static gint compare_users_by_username (const gchar *a,
+                                       const gchar *b);
+static void activate_online_accounts (DbusmenuMenuitem *mi,
+                                      guint timestamp,
+                                      gpointer user_data);
+static void user_menu_mgr_rebuild_items (UserMenuMgr *self);
+static gboolean check_new_session ();
+static void user_change (UsersServiceDbus *service,
+                         const gchar      *user_id,
+                         gpointer          user_data);
+
+static void ensure_gconf_client ();
+
+G_DEFINE_TYPE (UserMenuMgr, user_menu_mgr, G_TYPE_OBJECT);
+
+
+static void
+user_menu_mgr_init (UserMenuMgr *self)
+{
+  self->users_dbus_interface = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL);
+  self->root_item = dbusmenu_menuitem_new ();
+  g_signal_connect (G_OBJECT (self->users_dbus_interface),
+                    "user-added",
+                    G_CALLBACK (user_change),
+                    self);
+  g_signal_connect (G_OBJECT (self->users_dbus_interface),
+                    "user-removed",
+                    G_CALLBACK (user_change),
+                    self);
+}
+
+static void
+user_menu_mgr_finalize (GObject *object)
+{
+	/* TODO: Add deinitalization code here */
+	G_OBJECT_CLASS (user_menu_mgr_parent_class)->finalize (object);
+}
+
+static void
+user_menu_mgr_class_init (UserMenuMgrClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	//GObjectClass* parent_class = G_OBJECT_CLASS (klass);
+
+	object_class->finalize = user_menu_mgr_finalize;
+}
+
+/* Builds up the menu for us */
+static void 
+user_menu_mgr_rebuild_items (UserMenuMgr *self)
+{
+  DbusmenuMenuitem *mi = NULL;
+  DbusmenuMenuitem *guest_mi = NULL;
+  GList *u;
+  UserData *user;
+  gboolean can_activate;
+  GList *children;
+
+  /* Make sure we have a valid GConf client, and build one
+     if needed */
+  ensure_gconf_client ();
+
+  /* Check to see which menu items we're allowed to have */
+  can_activate = users_service_dbus_can_activate_session (self->users_dbus_interface) &&
+      !gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_USER, NULL);
+
+  /* Remove the old menu items if that makes sense */
+  children = dbusmenu_menuitem_take_children (self->root_item);
+  g_list_foreach (children, (GFunc)g_object_unref, NULL);
+  g_list_free (children);
+
+  /* Set to NULL just incase we don't end up building one */
+  users_service_dbus_set_guest_item(self->users_dbus_interface, NULL);
+
+  /* Build all of the user switching items */
+  if (can_activate == TRUE)
+  {
+    if (check_new_session ()){
+      switch_menuitem = dbusmenu_menuitem_new ();
+      dbusmenu_menuitem_property_set (switch_menuitem,
+                                      DBUSMENU_MENUITEM_PROP_TYPE,
+                                      MENU_SWITCH_TYPE);
+      dbusmenu_menuitem_property_set (switch_menuitem,
+                                      MENU_SWITCH_USER,
+                                      g_get_user_name());
+      dbusmenu_menuitem_child_append (self->root_item, switch_menuitem);
+      g_signal_connect (G_OBJECT (switch_menuitem),
+                        DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                        G_CALLBACK (activate_new_session),
+                        self->users_dbus_interface);
+    }
+
+    GList * users = NULL;
+    users = users_service_dbus_get_user_list (self->users_dbus_interface);
+    self->user_count = g_list_length(users);
+    
+    g_debug ("USER COUNT = %i", self->user_count);
+    session_dbus_set_user_menu_visibility (self->session_dbus_interface, self->user_count > 1);
+
+    if (self->user_count > MINIMUM_USERS && self->user_count < MAXIMUM_USERS) {
+      users = g_list_sort (users, (GCompareFunc)compare_users_by_username);
+    }
+
+    for (u = users; u != NULL; u = g_list_next (u)) {
+      user = u->data;
+      user->service = self->users_dbus_interface;
+
+      g_debug ("%i %s", (gint)user->uid, user->user_name);
+
+      if (g_strcmp0(user->user_name, "guest") == 0) {
+        /* Check to see if the guest has sessions and so therefore should
+           get a check mark. */
+        if (user->sessions != NULL) {
+          dbusmenu_menuitem_property_set_bool (guest_mi,
+                                               USER_ITEM_PROP_LOGGED_IN,
+                                               TRUE);
+        }
+        /* If we're showing user accounts, keep going through the list */
+        if (self->user_count > MINIMUM_USERS && self->user_count < MAXIMUM_USERS) {
+          continue;
+        }
+        /* If not, we can stop here */
+        break;
+      }
+
+      if (self->user_count > MINIMUM_USERS && self->user_count < MAXIMUM_USERS) {
+        mi = dbusmenu_menuitem_new ();
+        dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, USER_ITEM_TYPE);
+        if (user->real_name_conflict) {
+          gchar * conflictedname = g_strdup_printf("%s (%s)", user->real_name, user->user_name);
+          dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, conflictedname);
+          g_free(conflictedname);
+        } else {
+          dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, user->real_name);
+        }
+        dbusmenu_menuitem_property_set_bool (mi,
+                                             USER_ITEM_PROP_LOGGED_IN,
+                                             user->sessions != NULL);
+        if (user->icon_file != NULL && user->icon_file[0] != '\0') {
+          dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, user->icon_file);
+        } else {
+          dbusmenu_menuitem_property_set(mi, USER_ITEM_PROP_ICON, USER_ITEM_ICON_DEFAULT);
+        }
+        
+        gboolean logged_in = g_strcmp0 (user->user_name, g_get_user_name()) == 0;       
+        dbusmenu_menuitem_property_set_bool (mi,
+                                             USER_ITEM_PROP_IS_CURRENT_USER,
+                                             logged_in);          
+        if (logged_in == TRUE){
+          g_debug ("about to set the users real name to %s for user %s",
+                    user->real_name, user->user_name);
+          session_dbus_set_users_real_name (self->session_dbus_interface, user->real_name);
+        }
+        
+        dbusmenu_menuitem_child_append (self->root_item, mi);
+        g_signal_connect (G_OBJECT (mi),
+                          DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                          G_CALLBACK (activate_user_session),
+                          user);
+        user->menuitem = mi;
+      }
+    }
+    g_list_free(users);
+  }
+  // Add the online accounts and separator
+  DbusmenuMenuitem * separator1 = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (separator1,
+                                  DBUSMENU_MENUITEM_PROP_TYPE,
+                                  DBUSMENU_CLIENT_TYPES_SEPARATOR);
+  dbusmenu_menuitem_child_append (self->root_item, separator1);
+  DbusmenuMenuitem * online_accounts_item = dbusmenu_menuitem_new();
+  dbusmenu_menuitem_property_set (online_accounts_item,
+                                  DBUSMENU_MENUITEM_PROP_TYPE,
+                                  DBUSMENU_CLIENT_TYPES_DEFAULT);
+  dbusmenu_menuitem_property_set (online_accounts_item,
+                                  DBUSMENU_MENUITEM_PROP_LABEL,
+                                  _("Online Accounts..."));
+
+  g_signal_connect (G_OBJECT (online_accounts_item),
+                    DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
+                    G_CALLBACK (activate_online_accounts),
+                    NULL);
+                                  
+  dbusmenu_menuitem_child_append (self->root_item, online_accounts_item);    
+}
+
+/* Checks to see if we can create sessions */
+// TODO what is this ?
+static gboolean
+check_new_session ()
+{
+	return TRUE;
+}
+
+/* Check to see if the lockdown key is protecting from
+   locking the screen.  If not, lock it. */
+static void
+lock_if_possible (void) {
+	ensure_gconf_client ();
+
+	if (!gconf_client_get_bool (gconf_client, LOCKDOWN_KEY_SCREENSAVER, NULL)) {
+		lock_screen(NULL, 0, NULL);
+	}
+
+	return;
+}
+
+
+/* Starts a new generic session */
+static void
+activate_new_session (DbusmenuMenuitem * mi, guint timestamp, gpointer user_data)
+{
+	lock_if_possible();
+
+  users_service_dbus_show_greeter (USERS_SERVICE_DBUS(user_data));
+
+	return;
+}
+
+/* Activates a session for a particular user. */
+static void
+activate_user_session (DbusmenuMenuitem *mi, guint timestamp, gpointer user_data)
+{
+  UserData *user = (UserData *)user_data;
+  UsersServiceDbus *service = user->service;
+
+  lock_if_possible();
+
+  users_service_dbus_activate_user_session (service, user);
+}
+
+/* Comparison function to look into the UserData struct
+   to compare by using the username value */
+static gint
+compare_users_by_username (const gchar *a,
+                           const gchar *b)
+{
+  UserData *user1 = (UserData *)a;
+  UserData *user2 = (UserData *)b;
+
+  gint retval = g_strcmp0 (user1->real_name, user2->real_name);
+
+  /* If they're the same, they're both in conflict. */
+  if (retval == 0) {
+    user1->real_name_conflict = TRUE;
+    user2->real_name_conflict = TRUE;
+  }
+
+  return retval;
+}
+
+// TODO
+// Wait until dialog is complete to find out name to pass
+// to the control centre.
+static void
+activate_online_accounts (DbusmenuMenuitem *mi,
+                          guint timestamp,
+                          gpointer user_data)
+{
+  GError * error = NULL;
+  if (!g_spawn_command_line_async("gnome-control-center online-accounts", &error))
+  {
+    g_warning("Unable to show control centre: %s", error->message);
+    g_error_free(error);
+  }
+}
+
+/* Signal called when a user is added.  It updates the count and
+   rebuilds the menu */
+static void
+user_change (UsersServiceDbus *service,
+             const gchar      *user_id,
+             gpointer          user_data)
+{
+	//DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
+  // TODO sort this out.
+	//rebuild_user_items (root, service);
+	return;
+}
+
+/* Ensures that we have a GConf client and if we build one
+   set up the signal handler. */
+static void
+ensure_gconf_client ()
+{
+	if (!gconf_client) {
+		gconf_client = gconf_client_get_default ();
+		gconf_client_add_dir (gconf_client, LOCKDOWN_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+		gconf_client_add_dir (gconf_client, KEYBINDING_DIR, GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
+	}
+}
+
+DbusmenuMenuitem*
+user_mgr_get_root_item (UserMenuMgr* self)
+{
+  return self->root_item;
+}
+
+
+/*
+ * Clean Entry Point 
+ */
+UserMenuMgr* user_menu_mgr_new (SessionDbus* session_dbus)
+{
+  UserMenuMgr* user_mgr = g_object_new (USER_TYPE_MENU_MGR, NULL);
+  user_mgr->session_dbus_interface = session_dbus;
+  user_menu_mgr_rebuild_items (user_mgr);    
+  return user_mgr;
+}
+  
+

=== added file 'src/user-menu-mgr.h'
--- src/user-menu-mgr.h	1970-01-01 00:00:00 +0000
+++ src/user-menu-mgr.h	2011-07-15 15:41:18 +0000
@@ -0,0 +1,53 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * user-menu-mgr.c
+ * Copyright (C) Conor Curran 2011 <conor.curran@xxxxxxxxxxxxx>
+ * 
+ * user-menu-mgr.c is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * user-menu-mgr.c is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+#ifndef _USER_MENU_MGR_H_
+#define _USER_MENU_MGR_H_
+
+
+#include <glib-object.h>
+#include <libdbusmenu-gtk3/menuitem.h>
+
+#include "session-dbus.h"
+
+G_BEGIN_DECLS
+
+#define USER_TYPE_MENU_MGR             (user_menu_mgr_get_type ())
+#define USER_MENU_MGR(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), USER_TYPE_MENU_MGR, UserMenuMgr))
+#define USER_MENU_MGR_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), USER_TYPE_MENU_MGR, UserMenuMgrClass))
+#define USER_IS_MENU_MGR(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), USER_TYPE_MENU_MGR))
+#define USER_IS_MENU_MGR_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), USER_TYPE_MENU_MGR))
+#define USER_MENU_MGR_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), USER_TYPE_MENU_MGR, UserMenuMgrClass))
+
+typedef struct _UserMenuMgrClass UserMenuMgrClass;
+typedef struct _UserMenuMgr UserMenuMgr;
+
+struct _UserMenuMgrClass
+{
+	GObjectClass parent_class;
+};
+
+GType user_menu_mgr_get_type (void) G_GNUC_CONST;
+UserMenuMgr* user_menu_mgr_new (SessionDbus* session_dbus);
+
+DbusmenuMenuitem* user_mgr_get_root_item (UserMenuMgr* self);
+G_END_DECLS
+
+#endif /* _USER_MENU_MGR_H_ */


Follow ups