[gnome-control-center] user-accounts: Prevent crashes if current user is not in carousel



commit 4e43bd6ce866d39f9ae96fbb7beeccf9ede281b5
Author: Ondrej Holy <oholy redhat com>
Date:   Tue Dec 5 16:22:29 2017 +0100

    user-accounts: Prevent crashes if current user is not in carousel
    
    In a specific cases, current user doesn't have to be returned from
    accountsservice, or can be skipped by act_user_is_system_account check.
    System users should not be shown. This is expected for root account,
    but should not happen with regular user accounts. It needs to be fixed
    in accountsservice if you see this happening with regular user accounts.
    We have to be just sure that Users panel doesn't crash in such cases
    and show all non-system user accounts returned from accountsservice.
    Empty page is shown currently only if act_user_manager_list_users
    returns nothing, but it has to be also shown if only system accounts
    are returned. To fix this issue, do not try to show current user, but
    show first user account in carousel instead if there is any. First user
    account is current user in normal case.
    
    The patch also fixes problems that current user account is sometimes
    selected instead of currently selected user account. This is because
    of preselection of first item in um_carousel_add, which causes unwanted
    signal emissions...
    
    https://bugzilla.gnome.org/show_bug.cgi?id=773673

 panels/user-accounts/um-carousel.c   |   19 ++++++++++--
 panels/user-accounts/um-carousel.h   |    2 +
 panels/user-accounts/um-user-panel.c |   52 ++++++++--------------------------
 3 files changed, 29 insertions(+), 44 deletions(-)
---
diff --git a/panels/user-accounts/um-carousel.c b/panels/user-accounts/um-carousel.c
index f7d0a26..78b5d5f 100644
--- a/panels/user-accounts/um-carousel.c
+++ b/panels/user-accounts/um-carousel.c
@@ -202,6 +202,15 @@ um_carousel_select_item (UmCarousel     *self,
         gchar *page_name;
         gboolean page_changed = TRUE;
 
+        /* Select first user if none is specified */
+        if (item == NULL)
+        {
+                if (self->children != NULL)
+                        item = self->children->data;
+                else
+                        return;
+        }
+
         if (self->selected_item != NULL)
         {
                 page_changed = (self->selected_item->page != item->page);
@@ -304,10 +313,6 @@ um_carousel_add (GtkContainer *container,
         gtk_widget_show_all (self->last_box);
 
         update_buttons_visibility (self);
-
-        /* If there's only one child, select it. */
-        if (self->children->next == NULL)
-                um_carousel_select_item_at_index (self, 0);
 }
 
 void
@@ -398,3 +403,9 @@ um_carousel_init (UmCarousel *self)
         g_signal_connect_swapped (self->stack, "size-allocate", G_CALLBACK (on_size_allocate), self);
         g_signal_connect_swapped (self->stack, "notify::transition-running", G_CALLBACK 
(on_transition_running), self);
 }
+
+guint
+um_carousel_get_item_count (UmCarousel *self)
+{
+        return g_list_length (self->children);
+}
diff --git a/panels/user-accounts/um-carousel.h b/panels/user-accounts/um-carousel.h
index 0812ca3..731e1c7 100644
--- a/panels/user-accounts/um-carousel.h
+++ b/panels/user-accounts/um-carousel.h
@@ -46,6 +46,8 @@ UmCarouselItem  *um_carousel_find_item   (UmCarousel     *self,
 void             um_carousel_select_item (UmCarousel     *self,
                                           UmCarouselItem *item);
 
+guint            um_carousel_get_item_count (UmCarousel  *self);
+
 G_END_DECLS
 
 #endif /* UM_CAROUSEL_H */
diff --git a/panels/user-accounts/um-user-panel.c b/panels/user-accounts/um-user-panel.c
index cb60625..fd8d5b5 100644
--- a/panels/user-accounts/um-user-panel.c
+++ b/panels/user-accounts/um-user-panel.c
@@ -239,6 +239,8 @@ user_added (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
         /* Show heading for other accounts if new one have been added. */
         show_carousel = (d->other_accounts > 0);
         gtk_revealer_set_reveal_child (GTK_REVEALER (d->carousel), show_carousel);
+
+        gtk_stack_set_visible_child_name (GTK_STACK (d->stack), PAGE_USERS);
 }
 
 static gint
@@ -276,10 +278,9 @@ reload_users (CcUserPanelPrivate *d, ActUser *selected_user)
 {
         ActUser *user;
         GSList *list, *l;
-        UmCarouselItem *item;
+        UmCarouselItem *item = NULL;
         GtkSettings *settings;
         gboolean animations;
-        gboolean can_reload;
 
         settings = gtk_settings_get_default ();
 
@@ -287,19 +288,11 @@ reload_users (CcUserPanelPrivate *d, ActUser *selected_user)
         g_object_set (settings, "gtk-enable-animations", FALSE, NULL);
 
         um_carousel_purge_items (d->carousel);
-
         d->other_accounts = 0;
 
         list = act_user_manager_list_users (d->um);
         g_debug ("Got %d users\n", g_slist_length (list));
 
-        can_reload = (list != NULL);
-        gtk_stack_set_visible_child_name (GTK_STACK (d->stack),
-                                          can_reload ? PAGE_USERS : PAGE_NO_USERS);
-
-        if (!can_reload)
-            return;
-
         list = g_slist_sort (list, (GCompareFunc) sort_users);
         for (l = list; l; l = l->next) {
                 user = l->data;
@@ -308,31 +301,18 @@ reload_users (CcUserPanelPrivate *d, ActUser *selected_user)
         }
         g_slist_free (list);
 
-        if (selected_user) {
+        if (um_carousel_get_item_count (d->carousel) == 0)
+                gtk_stack_set_visible_child_name (GTK_STACK (d->stack), PAGE_NO_USERS);
+        if (d->other_accounts == 0)
+                gtk_revealer_set_reveal_child (GTK_REVEALER (d->carousel), FALSE);
+
+        if (selected_user)
                 item = um_carousel_find_item (d->carousel, selected_user, user_compare);
-                um_carousel_select_item (d->carousel, item);
-        }
+        um_carousel_select_item (d->carousel, item);
 
         g_object_set (settings, "gtk-enable-animations", animations, NULL);
 }
 
-static void
-user_removed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
-{
-        gboolean show_carousel;
-
-        d->other_accounts--;
-        show_carousel = (d->other_accounts > 0);
-        gtk_revealer_set_reveal_child (GTK_REVEALER (d->carousel),
-                                       show_carousel);
-
-        reload_users (d, NULL);
-
-        /* Show the current user */
-        user = act_user_manager_get_user_by_id (d->um, getuid ());
-        show_user (user, d);
-}
-
 static gint
 user_compare (gconstpointer i,
               gconstpointer u)
@@ -356,10 +336,7 @@ user_compare (gconstpointer i,
 static void
 user_changed (ActUserManager *um, ActUser *user, CcUserPanelPrivate *d)
 {
-        if (act_user_get_uid (user) != act_user_get_uid (d->selected_user))
-                return;
-
-        reload_users (d, user);
+        reload_users (d, d->selected_user);
 }
 
 static void
@@ -1120,7 +1097,6 @@ users_loaded (ActUserManager     *manager,
               GParamSpec         *pspec,
               CcUserPanelPrivate *d)
 {
-        ActUser *user;
         GtkWidget *dialog;
 
         if (act_user_manager_no_service (d->um)) {
@@ -1142,13 +1118,9 @@ users_loaded (ActUserManager     *manager,
         g_signal_connect (d->um, "user-changed", G_CALLBACK (user_changed), d);
         g_signal_connect (d->um, "user-is-logged-in-changed", G_CALLBACK (user_changed), d);
         g_signal_connect (d->um, "user-added", G_CALLBACK (user_added), d);
-        g_signal_connect (d->um, "user-removed", G_CALLBACK (user_removed), d);
+        g_signal_connect (d->um, "user-removed", G_CALLBACK (user_changed), d);
 
         reload_users (d, NULL);
-
-        /* Show the current user firstly. */
-        user = act_user_manager_get_user_by_id (d->um, getuid ());
-        show_user (user, d);
 }
 
 static void


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