users: Fixup buggy AdwNavigation behavior

Previously, events from accountsservice would be used to change the
state of the AdwNavigation in ways that don't correspond to the event
that happened. For example, deleting an account would pop the top page
off the stack, even if that page didn't belong to that account.

Especially buggy is the behavior of replacing the currently visible page
with the contents of an account that just changed. systemd-homed changes
the user record whenever authentication happens successfully. So, user
Foo might be trying to edit user Bar, type in their password at the
polkit prompt, and end up looking at a broken version of their own
settings page again: the title would be "Bar", there'd be no list of
users, and hitting the back button would take Foo back to the same
settings page they're currently looking at.

This commits refactors the handling of the accountsservice signals to
fix all the bugs

Fixes https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/2911
This commit is contained in:
Adrian Vovk 2024-02-21 20:41:09 -05:00 committed by Felipe Borges
parent bb604ad9dd
commit 87a62a7c4a
3 changed files with 31 additions and 17 deletions

View file

@ -720,6 +720,10 @@ cc_user_page_set_user (CcUserPage *self,
g_object_notify (G_OBJECT (self), "is-current-user");
g_object_notify (G_OBJECT (self), "is-admin");
if (!is_current_user (user))
adw_navigation_page_set_title (ADW_NAVIGATION_PAGE (self), get_real_or_user_name (user));
adw_navigation_page_set_tag (ADW_NAVIGATION_PAGE (self), act_user_get_user_name (user));
cc_avatar_chooser_set_user (self->avatar_chooser, self->user);
setup_avatar_for_user (self->avatar, self->user);
gtk_widget_set_visible (GTK_WIDGET (self->avatar_remove_button),

View file

@ -97,8 +97,6 @@ on_user_row_activated (CcUsersPage *self,
user_page = cc_user_page_new ();
cc_user_page_set_user (user_page, user, self->permission);
adw_navigation_page_set_title (ADW_NAVIGATION_PAGE (user_page), get_real_or_user_name (user));
adw_navigation_view_push (self->navigation, ADW_NAVIGATION_PAGE (user_page));
}
@ -156,37 +154,50 @@ static void
on_user_changed (CcUsersPage *self,
ActUser *user)
{
CcUserPage *visible_user_page;
CcUserPage *page;
guint position;
visible_user_page = CC_USER_PAGE (adw_navigation_view_get_visible_page (self->navigation));
cc_user_page_set_user (visible_user_page, user, self->permission);
/* Refresh the users list */
g_list_store_sort (self->model, sort_users, self);
/* If the user has a page open, refresh that page */
page = CC_USER_PAGE (adw_navigation_view_find_page (self->navigation, act_user_get_user_name (user)));
if (page != NULL)
cc_user_page_set_user (page, user, self->permission);
}
static void
on_user_added (CcUsersPage *self,
ActUser *user)
{
CcUserPage *user_page;
g_list_store_insert_sorted (self->model, user, sort_users, self);
CcUserPage *page;
g_list_store_insert_sorted (self->model, user, sort_users, self);
user_page = cc_user_page_new ();
cc_user_page_set_user (user_page, user, self->permission);
adw_navigation_page_set_title (ADW_NAVIGATION_PAGE (user_page), get_real_or_user_name (user));
page = CC_USER_PAGE (adw_navigation_view_get_visible_page (self->navigation));
if (page != self->current_user_page)
return;
adw_navigation_view_push (self->navigation, ADW_NAVIGATION_PAGE (user_page));
/* We're on the current user's page and a new user was just created. It's very likely the user
* was just created by our own add-user dialog. So let's display the new user */
page = cc_user_page_new ();
cc_user_page_set_user (page, user, self->permission);
adw_navigation_view_push (self->navigation, ADW_NAVIGATION_PAGE (page));
}
static void
on_user_removed (CcUsersPage *self,
ActUser *user)
{
guint position;
AdwNavigationPage *page;
guint position;
if (g_list_store_find (self->model, user, &position)) {
g_list_store_remove (self->model, position);
}
if (g_list_store_find (self->model, user, &position))
g_list_store_remove (self->model, position);
adw_navigation_view_pop (self->navigation);
page = adw_navigation_view_find_page (self->navigation, act_user_get_user_name (user));
if (page != NULL)
adw_navigation_view_pop_to_page (self->navigation, ADW_NAVIGATION_PAGE (self->current_user_page));
}
static void

View file

@ -9,7 +9,6 @@
<child>
<object class="CcUserPage" id="current_user_page">
<property name="title" translatable="yes">Users</property>
<property name="tag">current-user</property>
<child>
<object class="AdwPreferencesGroup" id="other_users_group">