[gdm] Add new 'is-loaded' property to user object



commit b02dd2f7a684e36de84dfec778d6c4e39836efde
Author: Ray Strode <rstrode redhat com>
Date:   Mon Aug 30 13:49:58 2010 -0400

    Add new 'is-loaded' property to user object
    
    Since the user objects are loaded asynchronously,
    there is a timeframe where they are incomplete.
    
    This commit adds an "is-loaded" property to
    GdmUser to mark when the user is fully loaded.

 gui/simple-greeter/gdm-user-manager.c |   40 +++++++++++++---
 gui/simple-greeter/gdm-user.c         |   78 +++++++++++++++++++++++++++++++++
 gui/simple-greeter/gdm-user.h         |    1 +
 3 files changed, 111 insertions(+), 8 deletions(-)
---
diff --git a/gui/simple-greeter/gdm-user-manager.c b/gui/simple-greeter/gdm-user-manager.c
index 40707b9..01117e2 100644
--- a/gui/simple-greeter/gdm-user-manager.c
+++ b/gui/simple-greeter/gdm-user-manager.c
@@ -758,27 +758,51 @@ remove_user (GdmUserManager *manager,
 }
 
 static void
-on_new_user_changed (GdmUser        *user,
-                     GdmUserManager *manager)
+on_new_user_loaded (GdmUser        *user,
+                    GParamSpec     *pspec,
+                    GdmUserManager *manager)
 {
         const char *username;
 
-        username = gdm_user_get_user_name (user);
-
-        if (username == NULL) {
+        if (!gdm_user_is_loaded (user)) {
                 return;
         }
 
-        g_signal_handlers_disconnect_by_func (user, on_new_user_changed, manager);
+        g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
         manager->priv->new_users = g_slist_remove (manager->priv->new_users,
                                                    user);
 
+        username = gdm_user_get_user_name (user);
+
+        if (username == NULL) {
+                const char *object_path;
+
+                object_path = gdm_user_get_object_path (user);
+
+                if (object_path != NULL) {
+                        g_warning ("GdmUserManager: user has no username "
+                                   "(object path: %s, uid: %lu)",
+                                   object_path, gdm_user_get_uid (user));
+                } else {
+                        g_warning ("GdmUserManager: user has no username (uid: %lu)",
+                                   gdm_user_get_uid (user));
+                }
+                g_object_unref (user);
+                return;
+        }
+
         if (username_in_exclude_list (manager, username)) {
                 g_debug ("GdmUserManager: excluding user '%s'", username);
                 g_object_unref (user);
                 return;
         }
 
+        /* User added already through alternative, but less authoratative means.
+         */
+        if (g_hash_table_lookup (manager->priv->users_by_name, username) != NULL) {
+                g_hash_table_remove (manager->priv->users_by_name, username);
+        }
+
         add_user (manager, user);
         g_object_unref (user);
 }
@@ -800,7 +824,7 @@ add_new_user_for_object_path (const char     *object_path,
 
         manager->priv->new_users = g_slist_prepend (manager->priv->new_users, user);
 
-        g_signal_connect (user, "changed", G_CALLBACK (on_new_user_changed), manager);
+        g_signal_connect (user, "notify::is-loaded", G_CALLBACK (on_new_user_loaded), manager);
 }
 
 static void
@@ -2734,7 +2758,7 @@ gdm_user_manager_finalize (GObject *object)
                 user = GDM_USER (node->data);
                 next_node = node->next;
 
-                g_signal_handlers_disconnect_by_func (user, on_new_user_changed, manager);
+                g_signal_handlers_disconnect_by_func (user, on_new_user_loaded, manager);
                 g_object_unref (user);
                 manager->priv->new_users = g_slist_delete_link (manager->priv->new_users, node);
                 node = next_node;
diff --git a/gui/simple-greeter/gdm-user.c b/gui/simple-greeter/gdm-user.c
index de46329..25951ba 100644
--- a/gui/simple-greeter/gdm-user.c
+++ b/gui/simple-greeter/gdm-user.c
@@ -46,6 +46,11 @@
 #define USER_ACCOUNTS_INTERFACE "org.freedesktop.Accounts.User"
 
 enum {
+        PROP_0,
+        PROP_IS_LOADED
+};
+
+enum {
         CHANGED,
         SESSIONS_CHANGED,
         LAST_SIGNAL
@@ -66,6 +71,8 @@ struct _GdmUser {
         char           *icon_file;
         GList          *sessions;
         gulong          login_frequency;
+
+        guint           is_loaded : 1;
 };
 
 typedef struct _GdmUserClass
@@ -139,6 +146,43 @@ gdm_user_get_num_sessions (GdmUser    *user)
 }
 
 static void
+gdm_user_set_property (GObject        *object,
+                       guint           prop_id,
+                       const GValue   *value,
+                       GParamSpec     *pspec)
+{
+        GdmUser *user;
+
+        user = GDM_USER (object);
+
+        switch (prop_id) {
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_user_get_property (GObject        *object,
+                       guint           prop_id,
+                       GValue         *value,
+                       GParamSpec     *pspec)
+{
+        GdmUser *user;
+
+        user = GDM_USER (object);
+
+        switch (prop_id) {
+        case PROP_IS_LOADED:
+                g_value_set_boolean (value, user->is_loaded);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
 gdm_user_class_init (GdmUserClass *class)
 {
         GObjectClass *gobject_class;
@@ -146,6 +190,16 @@ gdm_user_class_init (GdmUserClass *class)
         gobject_class = G_OBJECT_CLASS (class);
 
         gobject_class->finalize = gdm_user_finalize;
+        gobject_class->set_property = gdm_user_set_property;
+        gobject_class->get_property = gdm_user_get_property;
+
+        g_object_class_install_property (gobject_class,
+                                         PROP_IS_LOADED,
+                                         g_param_spec_boolean ("is-loaded",
+                                                               NULL,
+                                                               NULL,
+                                                               FALSE,
+                                                               G_PARAM_READABLE));
 
         signals [CHANGED] =
                 g_signal_new ("changed",
@@ -209,6 +263,16 @@ gdm_user_finalize (GObject *object)
                 (*G_OBJECT_CLASS (gdm_user_parent_class)->finalize) (object);
 }
 
+static void
+set_is_loaded (GdmUser  *user,
+               gboolean  is_loaded)
+{
+        if (user->is_loaded != is_loaded) {
+                user->is_loaded = is_loaded;
+                g_object_notify (G_OBJECT (user), "is-loaded");
+        }
+}
+
 /**
  * _gdm_user_update_from_pwent:
  * @user: the user object to update.
@@ -297,6 +361,10 @@ _gdm_user_update_from_pwent (GdmUser             *user,
                 changed = TRUE;
         }
 
+        if (!user->is_loaded) {
+                set_is_loaded (user, TRUE);
+        }
+
         if (changed) {
                 g_signal_emit (user, signals[CHANGED], 0);
         }
@@ -877,6 +945,10 @@ on_get_all_finished (DBusGProxy     *proxy,
         g_hash_table_foreach (hash_table, (GHFunc) collect_props, user);
         g_hash_table_unref (hash_table);
 
+        if (!user->is_loaded) {
+                set_is_loaded (user, TRUE);
+        }
+
         g_signal_emit (user, signals[CHANGED], 0);
 
 out:
@@ -958,3 +1030,9 @@ gdm_user_new_from_object_path (const gchar *object_path)
         g_object_unref (user);
         return NULL;
 }
+
+gboolean
+gdm_user_is_loaded (GdmUser *user)
+{
+        return user->is_loaded;
+}
diff --git a/gui/simple-greeter/gdm-user.h b/gui/simple-greeter/gdm-user.h
index 2aee30a..4d6ced8 100644
--- a/gui/simple-greeter/gdm-user.h
+++ b/gui/simple-greeter/gdm-user.h
@@ -56,6 +56,7 @@ GdkPixbuf            *gdm_user_render_icon         (GdmUser   *user,
 
 gint                  gdm_user_collate             (GdmUser   *user1,
                                                     GdmUser   *user2);
+gboolean              gdm_user_is_loaded           (GdmUser *user);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]