← Back to team overview

ayatana-commits team mailing list archive

[Merge] lp:~cjcurran/indicator-session/user-images into lp:indicator-session

 

Conor Curran has proposed merging lp:~cjcurran/indicator-session/user-images into lp:indicator-session.

Requested reviews:
  Ted Gould (ted)

For more details, see:
https://code.launchpad.net/~cjcurran/indicator-session/user-images/+merge/72493

Over haul of the user menu, user images now being drawn with a border.
Spacing between entries has been padded.
User addition and deletion reflected in the menu dynamically.

-- 
https://code.launchpad.net/~cjcurran/indicator-session/user-images/+merge/72493
Your team ayatana-commits is subscribed to branch lp:indicator-session.
=== modified file 'src/dbus-shared-names.h'
--- src/dbus-shared-names.h	2011-07-22 17:00:09 +0000
+++ src/dbus-shared-names.h	2011-08-22 19:28:23 +0000
@@ -55,13 +55,13 @@
 #define USER_ITEM_PROP_LOGGED_IN  "user-item-logged-in"
 #define USER_ITEM_PROP_IS_CURRENT_USER "user-item-is-current-user"
 #define USER_ITEM_PROP_ICON       "user-item-icon-path"
-#define USER_ITEM_ICON_DEFAULT    "user-offline"
+#define USER_ITEM_ICON_DEFAULT    "avatar-default"
 
 #define RESTART_ITEM_TYPE         "x-canonical-restart-item"
 #define RESTART_ITEM_LABEL        "restart-label"
 #define RESTART_ITEM_ICON         "restart-icon"
 
-#define ICON_DEFAULT              "system-shutdown-panel"
-#define ICON_RESTART              "system-shutdown-panel-restart"
+#define ICON_DEFAULT              "system-devices-panel"
+#define ICON_RESTART              "system-devices-panel-alert"
 
 #endif /* __DBUS_SHARED_NAMES_H__ */

=== modified file 'src/indicator-session.c'
--- src/indicator-session.c	2011-08-22 12:32:00 +0000
+++ src/indicator-session.c	2011-08-22 19:28:23 +0000
@@ -167,7 +167,7 @@
   // devices
   self->devices.menu = GTK_MENU (dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME,
                                                       INDICATOR_SESSION_DBUS_OBJECT));
-  self->devices.image = indicator_image_helper ("system-devices-panel");
+  self->devices.image = indicator_image_helper (ICON_DEFAULT);
   
   gtk_widget_show (GTK_WIDGET(self->devices.menu));
   gtk_widget_show (GTK_WIDGET(self->devices.image));
@@ -499,7 +499,7 @@
   }
   else if (g_strcmp0(signal_name, "RebootRequired") == 0) {
     // TODO waiting on design to give me a name.
-    self->devices.image = indicator_image_helper ("system-devices-alert-panel");        
+    self->devices.image = indicator_image_helper (ICON_RESTART);        
   }  
 }
 

=== modified file 'src/user-menu-mgr.c'
--- src/user-menu-mgr.c	2011-08-22 12:32:00 +0000
+++ src/user-menu-mgr.c	2011-08-22 19:28:23 +0000
@@ -76,7 +76,7 @@
                     G_CALLBACK (user_change),
                     self);
   g_signal_connect (G_OBJECT (self->users_dbus_interface),
-                    "user-removed",
+                    "user-deleted",
                     G_CALLBACK (user_change),
                     self);
 }
@@ -92,8 +92,6 @@
 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;
 }
 
@@ -212,15 +210,7 @@
           dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, conflictedname);
           g_free(conflictedname);
         } else {
-          //g_debug ("%i %s", (gint)user->uid, user->real_name);
-          //g_debug ("users uid = %i", (gint)user->uid);
-          //g_debug ("users real name = %s", user->real_name);
-          if (user == NULL){
-            g_debug ("USER pointer is NULL");
-            return;
-          }
-          g_debug ("%p: %s", user, user->real_name);      
-          
+          g_debug ("%p: %s", user, user->real_name);                
           dbusmenu_menuitem_property_set (mi,
                                           USER_ITEM_PROP_NAME,
                                           user->real_name);
@@ -229,9 +219,16 @@
                                              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);
+          g_debug ("user %s has this icon : %s",
+                    user->user_name,
+                    user->icon_file);
+          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);
+          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;       
@@ -364,9 +361,9 @@
              const gchar      *user_id,
              gpointer          user_data)
 {
-	//DbusmenuMenuitem *root = (DbusmenuMenuitem *)user_data;
-  // TODO sort this out.
-	//rebuild_user_items (root, service);
+  g_return_if_fail (USER_IS_MENU_MGR (user_data));  
+  UserMenuMgr* user_mgr = USER_MENU_MGR(user_data);  
+	user_menu_mgr_rebuild_items (user_mgr, FALSE);
 	return;
 }
 

=== modified file 'src/user-widget.c'
--- src/user-widget.c	2011-08-17 12:48:51 +0000
+++ src/user-widget.c	2011-08-22 19:28:23 +0000
@@ -3,7 +3,8 @@
 
 Authors:
     Conor Curran <conor.curran@xxxxxxxxxxxxx>
-
+    Mirco Müller <mirco.mueller@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 
 by the Free Software Foundation.
@@ -24,6 +25,7 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <glib.h>
+#include <math.h>
 #include <libindicator/indicator-image-helper.h>
 #include "user-widget.h"
 #include "dbus-shared-names.h"
@@ -35,6 +37,7 @@
 {
   DbusmenuMenuitem* twin_item;
   GtkWidget* user_image;
+  gboolean using_personal_icon;
   GtkWidget* user_name;
   GtkWidget* container;
   GtkWidget* tick_icon;
@@ -44,6 +47,13 @@
 
 #define USER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USER_WIDGET_TYPE, UserWidgetPrivate))
 
+typedef struct
+{
+  double r;
+  double g;
+  double b;
+} CairoColorRGB;
+
 /* Prototypes */
 static void user_widget_class_init    (UserWidgetClass *klass);
 static void user_widget_init          (UserWidget *self);
@@ -60,10 +70,22 @@
                                          gchar* property, 
                                          GVariant* value,
                                          gpointer userdata);
+                                         
+
+static void _color_shade (const CairoColorRGB *a,
+                          float k,
+                          CairoColorRGB *b);                                         
+
+static void draw_album_border (GtkWidget *widget, gboolean selected);
+                                         
 #if GTK_CHECK_VERSION(3, 0, 0)
 static gboolean user_widget_primitive_draw_cb_gtk_3 (GtkWidget *image,
                                                          cairo_t* cr,
                                                          gpointer user_data);
+static gboolean user_widget_draw_usericon_gtk_3 (GtkWidget *widget,
+                                                 cairo_t* cr,
+                                                 gpointer user_data);
+                                                         
 #else
 static gboolean user_widget_primitive_draw_cb (GtkWidget *image,
                                                    GdkEventExpose *event,
@@ -106,24 +128,9 @@
   
   // Create the UI elements.  
   priv->user_image = gtk_image_new ();
-  
-  // Just for now set the image to the default avator image
-  GdkPixbuf* pixbuf  = NULL; 
-  GError* error = NULL;
-  pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
-                                     "avatar-default",
-                                     32,
-                                     GTK_ICON_LOOKUP_FORCE_SIZE,
-                                     &error);
-  
-  if (pixbuf == NULL || error != NULL) {
-    g_warning ("Could not load the default avatar image for some reason");
-  }
-  else{
-    gtk_image_set_from_pixbuf (GTK_IMAGE(priv->user_image), pixbuf);
-    g_object_unref (pixbuf);
-  }
-
+ 	gtk_misc_set_alignment(GTK_MISC(priv->user_image), 0.0, 0.0);
+  gtk_misc_set_padding (GTK_MISC(priv->user_image),0, 4.0);
+  
   priv->user_name = gtk_label_new ("");
   priv->container = gtk_hbox_new (FALSE, 0);
 	priv->tick_icon = gtk_image_new_from_icon_name ("account-logged-in",
@@ -146,18 +153,23 @@
                       FALSE,
                       FALSE, 5);
   
-  gtk_widget_show_all (priv->container);
-  gtk_container_add (GTK_CONTAINER (self), priv->container);  
-  
+  gtk_widget_show_all (priv->container);  
+  gtk_container_add (GTK_CONTAINER (self), priv->container);    
   gtk_widget_show_all (priv->tick_icon);
   gtk_widget_set_no_show_all (priv->tick_icon, TRUE);
   gtk_widget_hide (priv->tick_icon);
   
+  
   // Fetch the drawing context.
   #if GTK_CHECK_VERSION(3, 0, 0) 
   g_signal_connect_after (GTK_WIDGET(self), "draw", 
                           G_CALLBACK(user_widget_primitive_draw_cb_gtk_3),
                           GTK_WIDGET(self));
+
+  g_signal_connect_after (GTK_WIDGET(priv->user_image), "draw", 
+                          G_CALLBACK(user_widget_draw_usericon_gtk_3),
+                          GTK_WIDGET(self));
+                          
   #else
   g_signal_connect_after (GTK_WIDGET(self), "expose-event", 
                           G_CALLBACK(user_widget_primitive_draw_cb),
@@ -168,8 +180,6 @@
 static void
 user_widget_dispose (GObject *object)
 {
-  //UserWidgetPrivate * priv = USER_WIDGET_GET_PRIVATE(USER_WIDGET(object)); 
-
   G_OBJECT_CLASS (user_widget_parent_class)->dispose (object);
 }
 
@@ -180,9 +190,11 @@
   G_OBJECT_CLASS (user_widget_parent_class)->finalize (object);
 }
 
+
+/*****************************************************************/
+
 #if GTK_CHECK_VERSION(3, 0, 0)  
 
-// Draw the radio dot and/or green check mark
 // TODO handle drawing of green check mark
 static gboolean
 user_widget_primitive_draw_cb_gtk_3 (GtkWidget *widget,
@@ -201,15 +213,13 @@
   }
   
   GtkStyle *style;
-  gdouble x, y;
-  gdouble offset = 15.0;
-  
+  gdouble x, y;  
   style = gtk_widget_get_style (widget);
   
   GtkAllocation allocation;
   gtk_widget_get_allocation (widget, &allocation);
   x = allocation.x + 13;        
-  y = offset;
+  y = allocation.height / 2;
   
   cairo_arc (cr, x, y, 3.0, 0.0, 2 * G_PI);;
   
@@ -221,68 +231,362 @@
   return FALSE;  
 }
 
+static gboolean
+user_widget_draw_usericon_gtk_3 (GtkWidget *widget,
+                                 cairo_t* cr,
+                                 gpointer user_data)
+{
+  g_return_val_if_fail(IS_USER_WIDGET(user_data), FALSE);
+  UserWidget* meta = USER_WIDGET(user_data);
+  UserWidgetPrivate * priv = USER_WIDGET_GET_PRIVATE(meta);  
+
+  if (priv->using_personal_icon == FALSE)
+    return FALSE;
+  
+  draw_album_border (widget, FALSE);  
+  return FALSE;
+}
+/**
+ * TODO:
+ * Sort out gtk2
+ */
 // GTK 2 Expose handler
 #else
-
-// Draw the triangle if the player is running ...
 static gboolean
 user_widget_primitive_draw_cb (GtkWidget *widget,
                                GdkEventExpose *event,
                                gpointer user_data)
 {
-  /*
   g_return_val_if_fail(IS_USER_WIDGET(user_data), FALSE);
   UserWidget* meta = USER_WIDGET(user_data);
   UserWidgetPrivate * priv = USER_WIDGET_GET_PRIVATE(meta);  
 
+  // Draw dot only when user is the current user.
+  if (!dbusmenu_menuitem_property_get_bool (priv->twin_item,
+                                            USER_ITEM_PROP_IS_CURRENT_USER)){
+    return FALSE;                                           
+  }
+  
   GtkStyle *style;
   cairo_t *cr;
-  int x, y, arrow_width, arrow_height;               
-
-  gint offset = 3;
-  arrow_width = 5; 
-  arrow_height = 9;
-  
-  style = gtk_widget_get_style (widget);
-
   cr = (cairo_t*) gdk_cairo_create (gtk_widget_get_window (widget));  
   
-  GtkAllocation allocation;
+  gdouble x, y;  
+  style = gtk_widget_get_style (widget);
+  
   gtk_widget_get_allocation (widget, &allocation);
-  x = allocation.x;
-  y = allocation.y;
-    
-  // Draw player icon  
-  if (priv->icon_buf != NULL){  
-    gdk_cairo_set_source_pixbuf (cr,
-                                 priv->icon_buf,
-                                 x + arrow_width + 1,
-                                 y + offset);
-    cairo_paint (cr);
-  }
-    
-  // Draw triangle but only if the player is running.
-  if (dbusmenu_menuitem_property_get_bool (priv->twin_item,
-                                             DBUSMENU_METADATA_MENUITEM_PLAYER_RUNNING)){
-    y += (double)arrow_height/2.0 + offset;
-    cairo_set_line_width (cr, 1.0);
+  x = allocation.x + 13;        
+  y = allocation.height / 2;
+  
+  cairo_arc (cr, x, y, 3.0, 0.0, 2 * G_PI);;
+  
+  cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0,
+                            style->fg[gtk_widget_get_state(widget)].green/65535.0,
+                            style->fg[gtk_widget_get_state(widget)].blue/65535.0);
+  cairo_fill (cr);      
+  cairo_destroy (cr);
 
-    cairo_move_to (cr, x, y);
-    cairo_line_to (cr, x, y + arrow_height);
-    cairo_line_to (cr, x + arrow_width, y + (double)arrow_height/2.0);
-    cairo_close_path (cr);
-    cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0,
-                              style->fg[gtk_widget_get_state(widget)].green/65535.0,
-                              style->fg[gtk_widget_get_state(widget)].blue/65535.0);
-    cairo_fill (cr);                                             
-  }
-  
-  cairo_destroy (cr);*/
   return FALSE;  
 }
 #endif
 
 
+static void
+draw_album_border(GtkWidget *widg, gboolean selected)
+{
+  cairo_t *cr;  
+  cr = gdk_cairo_create (gtk_widget_get_window (widg));
+  #if GTK_CHECK_VERSION(3, 0, 0)
+  gtk_style_context_add_class (gtk_widget_get_style_context (widg),
+                               "menu");
+  #endif
+  
+  GtkStyle *style;
+  style = gtk_widget_get_style (widg);
+  
+  GtkAllocation alloc;
+  gtk_widget_get_allocation (widg, &alloc);
+  gint offset = 0;
+  gint v_offset = 4;
+  
+  alloc.width = alloc.width + (offset * 2);
+  alloc.height = alloc.height - v_offset - 2;
+  alloc.x = alloc.x - offset;
+  alloc.y = alloc.y + v_offset/2 +1;
+
+  CairoColorRGB bg_normal, fg_normal;
+
+  bg_normal.r = style->bg[0].red/65535.0;
+  bg_normal.g = style->bg[0].green/65535.0;
+  bg_normal.b = style->bg[0].blue/65535.0;
+
+  gint state = selected ? 5 : 0;
+  
+  fg_normal.r = style->fg[state].red/65535.0;
+  fg_normal.g = style->fg[state].green/65535.0;
+  fg_normal.b = style->fg[state].blue/65535.0;
+
+  CairoColorRGB dark_top_color;
+  CairoColorRGB light_bottom_color;
+  CairoColorRGB background_color;
+  
+  _color_shade ( &bg_normal, 0.93, &background_color );
+  _color_shade ( &bg_normal, 0.23, &dark_top_color );
+  _color_shade ( &fg_normal, 0.55, &light_bottom_color );
+  
+  cairo_rectangle (cr,
+                   alloc.x, alloc.y,
+                   alloc.width, alloc.height);
+
+  cairo_set_line_width (cr, 1.0);
+  
+  cairo_clip ( cr );
+
+  cairo_move_to (cr, alloc.x, alloc.y );
+  cairo_line_to (cr, alloc.x + alloc.width,
+                alloc.y );
+  cairo_line_to ( cr, alloc.x + alloc.width,
+                  alloc.y + alloc.height );
+  cairo_line_to ( cr, alloc.x, alloc.y + alloc.height );
+  cairo_line_to ( cr, alloc.x, alloc.y);
+  cairo_close_path (cr);
+
+  cairo_set_source_rgba ( cr,
+                          background_color.r,
+                          background_color.g,
+                          background_color.b,
+                          1.0 );
+  
+  cairo_stroke ( cr );
+  
+  cairo_move_to (cr, alloc.x, alloc.y );
+  cairo_line_to (cr, alloc.x + alloc.width,
+                alloc.y );
+
+  cairo_close_path (cr);
+  cairo_set_source_rgba ( cr,
+                          dark_top_color.r,
+                          dark_top_color.g,
+                          dark_top_color.b,
+                          1.0 );
+  
+  cairo_stroke ( cr );
+  
+  cairo_move_to ( cr, alloc.x + alloc.width,
+                  alloc.y + alloc.height );
+  cairo_line_to ( cr, alloc.x, alloc.y + alloc.height );
+
+  cairo_close_path (cr);
+  cairo_set_source_rgba ( cr,
+                         light_bottom_color.r,
+                         light_bottom_color.g,
+                         light_bottom_color.b,
+                         1.0);
+  
+  cairo_stroke ( cr );
+  cairo_destroy (cr);   
+}
+
+static void
+_color_rgb_to_hls (gdouble *r,
+                   gdouble *g,
+                   gdouble *b)
+{
+  gdouble min;
+  gdouble max;
+  gdouble red;
+  gdouble green;
+  gdouble blue;
+  gdouble h = 0;
+  gdouble l;
+  gdouble s;
+  gdouble delta;
+
+  red = *r;
+  green = *g;
+  blue = *b;
+
+  if (red > green)
+  {
+    if (red > blue)
+      max = red;
+    else
+      max = blue;
+
+    if (green < blue)
+      min = green;
+    else
+    min = blue;
+  }
+  else
+  {
+    if (green > blue)
+      max = green;
+    else
+    max = blue;
+
+    if (red < blue)
+      min = red;
+    else
+      min = blue;
+  }
+  l = (max+min)/2;
+  if (fabs (max-min) < 0.0001)
+  {
+    h = 0;
+    s = 0;
+  }
+  else
+  {
+    if (l <= 0.5)
+    s = (max-min)/(max+min);
+    else
+    s = (max-min)/(2-max-min);
+
+    delta = (max -min) != 0 ? (max -min) : 1;
+    
+    if(delta == 0)
+      delta = 1;
+    if (red == max)
+      h = (green-blue)/delta;
+    else if (green == max)
+      h = 2+(blue-red)/delta;
+    else if (blue == max)
+      h = 4+(red-green)/delta;
+
+    h *= 60;
+    if (h < 0.0)
+      h += 360;
+  }
+
+  *r = h;
+  *g = l;
+  *b = s;
+}
+
+static void
+_color_hls_to_rgb (gdouble *h,
+                   gdouble *l, 
+                   gdouble *s)
+{
+  gdouble hue;
+  gdouble lightness;
+  gdouble saturation;
+  gdouble m1, m2;
+  gdouble r, g, b;
+
+  lightness = *l;
+  saturation = *s;
+
+  if (lightness <= 0.5)
+    m2 = lightness*(1+saturation);
+  else
+    m2 = lightness+saturation-lightness*saturation;
+
+  m1 = 2*lightness-m2;
+
+  if (saturation == 0)
+  {
+    *h = lightness;
+    *l = lightness;
+    *s = lightness;
+  }
+  else
+  {
+    hue = *h+120;
+    while (hue > 360)
+      hue -= 360;
+    while (hue < 0)
+      hue += 360;
+
+    if (hue < 60)
+      r = m1+(m2-m1)*hue/60;
+    else if (hue < 180)
+      r = m2;
+    else if (hue < 240)
+      r = m1+(m2-m1)*(240-hue)/60;
+    else
+      r = m1;
+
+    hue = *h;
+    while (hue > 360)
+      hue -= 360;
+    while (hue < 0)
+      hue += 360;
+
+    if (hue < 60)
+      g = m1+(m2-m1)*hue/60;
+    else if (hue < 180)
+      g = m2;
+    else if (hue < 240)
+      g = m1+(m2-m1)*(240-hue)/60;
+    else
+      g = m1;
+
+    hue = *h-120;
+    while (hue > 360)
+      hue -= 360;
+    while (hue < 0)
+      hue += 360;
+
+    if (hue < 60)
+      b = m1+(m2-m1)*hue/60;
+    else if (hue < 180)
+      b = m2;
+    else if (hue < 240)
+      b = m1+(m2-m1)*(240-hue)/60;
+    else
+      b = m1;
+
+    *h = r;
+    *l = g;
+    *s = b;
+  }
+}
+
+void
+_color_shade (const CairoColorRGB *a, float k, CairoColorRGB *b)
+{
+  double red;
+  double green;
+  double blue;
+
+  red   = a->r;
+  green = a->g;
+  blue  = a->b;
+
+  if (k == 1.0)
+  {
+    b->r = red;
+    b->g = green;
+    b->b = blue;
+    return;
+  }
+
+  _color_rgb_to_hls (&red, &green, &blue);
+
+  green *= k;
+  if (green > 1.0)
+    green = 1.0;
+  else if (green < 0.0)
+    green = 0.0;
+
+  blue *= k;
+  if (blue > 1.0)
+    blue = 1.0;
+  else if (blue < 0.0)
+    blue = 0.0;
+
+  _color_hls_to_rgb (&red, &green, &blue);
+
+  b->r = red;
+  b->g = green;
+  b->b = blue;
+}
+
+
+/*****************************************************************/
+
 /* Suppress/consume keyevents */
 static gboolean
 user_widget_button_release_event (GtkWidget *menuitem, 
@@ -291,6 +595,10 @@
   return FALSE;
 }
 
+
+/** 
+ * TODO, be sensitive to UI updates
+ * */
 static void 
 user_widget_property_update (DbusmenuMenuitem* item, gchar* property, 
                              GVariant* value, gpointer userdata)
@@ -300,6 +608,8 @@
 }
 
 
+
+
 static void
 user_widget_set_twin_item (UserWidget* self,
                            DbusmenuMenuitem* twin_item)
@@ -325,9 +635,48 @@
     gtk_widget_hide(priv->tick_icon);
 	}
 
-	g_debug("Using user icon for '%s' from file: %s",
-          dbusmenu_menuitem_property_get(twin_item, USER_ITEM_PROP_NAME), icon_name);
-
+  GdkPixbuf* pixbuf  = NULL; 
+  GError* error = NULL;
+  pixbuf = gdk_pixbuf_new_from_file_at_size(icon_name, 32, 32, NULL);
+
+  if (pixbuf == NULL || error != NULL) {
+    g_warning ("Could not load the user image (%s) for some reason",
+                icon_name);
+    if (pixbuf != NULL){
+      g_object_unref (pixbuf);
+      pixbuf = NULL;
+    }
+    if (error != NULL){
+      g_error_free (error);
+      error = NULL;
+    }
+    
+    priv->using_personal_icon = FALSE;
+    
+    pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                       USER_ITEM_ICON_DEFAULT,
+                                       32,
+                                       GTK_ICON_LOOKUP_FORCE_SIZE,
+                                       &error);                
+  }
+  else{
+    priv->using_personal_icon = TRUE;
+  }    
+
+  if (pixbuf == NULL || error != NULL) {
+    g_warning ("Could not load the user image");
+    if (error != NULL){
+      g_error_free (error);
+      error = NULL;
+    }                    
+  }  
+  else{
+    gtk_image_set_from_pixbuf (GTK_IMAGE(priv->user_image), pixbuf);
+  }
+  if (pixbuf != NULL){
+    g_object_unref (pixbuf);  
+    pixbuf = NULL;
+  }
 }
 
  /**

=== modified file 'src/users-service-dbus.c'
--- src/users-service-dbus.c	2011-08-18 11:20:19 +0000
+++ src/users-service-dbus.c	2011-08-22 19:28:23 +0000
@@ -58,6 +58,8 @@
 static void     user_deleted                           (DBusGProxy        *proxy,
                                                         const gchar       *user_id,
                                                         gpointer           user_data);
+static void     user_changed                            (DBusGProxy       *proxy,
+                                                         gpointer          user_data);                                                        
 static void     seat_proxy_session_added               (DBusGProxy        *seat_proxy,
                                                         const gchar       *session_id,
                                                         UsersServiceDbus  *service);
@@ -711,11 +713,6 @@
   g_return_if_fail(IS_USERS_SERVICE_DBUS(self));
   UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (self);
 
-  if (g_hash_table_size (priv->users) > 0)
-    {
-      return;
-    }
-
   if (priv->count > MINIMUM_USERS && priv->count < MAXIMUM_USERS)
     {
       GPtrArray *users = NULL;
@@ -758,15 +755,37 @@
 
               continue;
             }
-
-          user = g_new0 (UserData, 1);
-
+          
+          user = g_hash_table_lookup (priv->users, id);
+            // Double check we havent processed this user already
+          if (user != NULL)
+            {
+              g_free(user->user_name);
+              g_free(user->real_name);
+              g_free(user->icon_file);
+              user->real_name_conflict = FALSE;              
+              //continue;                                     
+            }
+          else
+            {            
+            user = g_new0 (UserData, 1);
+            }
+          // Can't subscribe to the Changed signal on each individual user path
+          // for some reason.
+          dbus_g_proxy_add_signal (proxy,
+                                   "Changed",
+                                   G_TYPE_INVALID);
+
+          dbus_g_proxy_connect_signal (proxy, "Changed",
+                                       G_CALLBACK(user_changed),
+                                       self,
+                                       NULL);
           user->uid         = g_value_get_uint64 (g_hash_table_lookup (properties, "Uid"));
           user->user_name   = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "UserName")));
           user->real_name   = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "RealName")));
           user->icon_file    = g_strdup (g_value_get_string (g_hash_table_lookup (properties, "IconFile")));
           user->real_name_conflict = FALSE;
-		  user->menuitem    = NULL;
+		      user->menuitem    = NULL;
 
           g_hash_table_unref (properties);
 
@@ -782,31 +801,50 @@
 }
 
 static void
+user_changed (DBusGProxy  *proxy,
+              gpointer     user_data)
+{
+  g_debug ("JUST RESYNCED THE USERS FROM A USER CHANGE");
+  UsersServiceDbus *service = (UsersServiceDbus *)user_data;
+  sync_users (service);
+}
+
+static void
 user_added (DBusGProxy  *proxy,
             const gchar *user_id,
             gpointer     user_data)
 {
   UsersServiceDbus *service = (UsersServiceDbus *)user_data;
   UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service);
-
   priv->count++;
 
   if (priv->count < MAXIMUM_USERS)
     {
       sync_users (service);
     }
+
+  g_signal_emit (service,
+                 signals[USER_ADDED],
+                 0,
+                 user_id);   
 }
 
 static void
 user_deleted (DBusGProxy  *proxy,
               const gchar *user_id,
               gpointer     user_data)
-{
+{  
   UsersServiceDbus *service = (UsersServiceDbus *)user_data;
   UsersServiceDbusPrivate *priv = USERS_SERVICE_DBUS_GET_PRIVATE (service);
 
   priv->count--;
   g_hash_table_remove (priv->users, user_id);
+
+  g_signal_emit (service,
+                 signals[USER_DELETED],
+                 0,
+                 user_id);   
+  
 }
 
 UserData *


Follow ups