From 02302c9b0837a843239f1551ae0684eb497e1956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nelson=20Ben=C3=ADtez=20Le=C3=B3n?= Date: Sun, 2 Apr 2023 19:56:18 -0400 Subject: CcPanelList: center sidebar row when activating a panel When activating a panel from Search or from commandline let's scroll the sidebar so the row for that panel is revealed and vertically centered on the list. Closes #2098 --- shell/cc-panel-list.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/shell/cc-panel-list.c b/shell/cc-panel-list.c index 299ba8015..7d37b59b6 100644 --- a/shell/cc-panel-list.c +++ b/shell/cc-panel-list.c @@ -968,6 +968,48 @@ cc_panel_list_add_panel (CcPanelList *self, gtk_widget_set_visible (GTK_WIDGET (self->privacy_row), TRUE); } +/* Scrolls sibebar so that @row is at middle of the visible part of list */ +static void +cc_panel_list_scroll_to_center_row (CcPanelList *self, + GtkWidget *row) +{ + double target_value; + graphene_point_t p; + GtkAdjustment *adj; + GtkWidget *scrolled_window; + + g_return_if_fail (GTK_IS_LIST_BOX_ROW (row)); + + scrolled_window = gtk_widget_get_ancestor (row, GTK_TYPE_SCROLLED_WINDOW); + adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)); + if (!adj) + return; + + if (!gtk_widget_compute_point (row, scrolled_window, &GRAPHENE_POINT_INIT (0, 0), &p)) + return; + + target_value = p.y + gtk_widget_get_height (row) / 2; + + gtk_adjustment_set_value (adj, target_value - gtk_adjustment_get_page_size (adj) / 2); +} + +typedef struct { + CcPanelList *panel_list; + GtkWidget *row; +} ScrollData; + +static gboolean +scroll_to_idle_cb (ScrollData *data) +{ + cc_panel_list_scroll_to_center_row (data->panel_list, data->row); + + g_object_unref (data->panel_list); + g_object_unref (data->row); + g_free (data); + + return FALSE; +} + /** * cc_panel_list_set_active_panel: * @self: a #CcPanelList @@ -981,6 +1023,7 @@ cc_panel_list_set_active_panel (CcPanelList *self, { GtkWidget *listbox; RowData *data; + ScrollData *sdata; g_return_if_fail (CC_IS_PANEL_LIST (self)); @@ -1031,6 +1074,14 @@ cc_panel_list_set_active_panel (CcPanelList *self, /* Store the current panel id */ g_clear_pointer (&self->current_panel_id, g_free); self->current_panel_id = g_strdup (id); + + /* Scroll the sidebar to the selected panel row, as that row may be + * out of view when panel is launched from a search or from cli */ + sdata = g_new (ScrollData, 1); + sdata->panel_list = g_object_ref (self); + sdata->row = g_object_ref (data->row); + + g_idle_add (G_SOURCE_FUNC (scroll_to_idle_cb), sdata); } /** -- cgit v1.2.1