[gnome-software/wip/cdavis/browsing-view] shell: Use AdwBrowsingView instead of AdwLeaflet




commit 8d5fa9851fdec71bafac6382c82696df1520dc15
Author: Christopher Davis <christopherdavis gnome org>
Date:   Tue Oct 11 23:30:57 2022 -0400

    shell: Use AdwBrowsingView instead of AdwLeaflet
    
    AdwBrowsingView is a new widget made to help developers
    implement the browsing pattern (see https://developer.gnome.org/hig/patterns/nav/browsing.html).
    AdwBrowsingView doesn't have the same limitations as AdwLeaflet,
    and handles a few things automatically, such as showing the back button.

 contrib/org.gnome.SoftwareDevel.json |  33 +++
 src/gs-shell.c                       | 113 ++------
 src/gs-shell.ui                      | 499 +++++++++++++++--------------------
 3 files changed, 268 insertions(+), 377 deletions(-)
---
diff --git a/contrib/org.gnome.SoftwareDevel.json b/contrib/org.gnome.SoftwareDevel.json
index 577aef740..261245080 100644
--- a/contrib/org.gnome.SoftwareDevel.json
+++ b/contrib/org.gnome.SoftwareDevel.json
@@ -186,6 +186,39 @@
                 }
             ]
         },
+        {
+            "name" : "libsass",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                  "type" : "git",
+                  "url" : "https://github.com/lazka/libsass.git";,
+                  "branch" : "meson"
+                }
+            ]
+        },
+        {
+            "name" : "sassc",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                  "type" : "git",
+                  "url" : "https://github.com/lazka/sassc.git";,
+                  "branch" : "meson"
+                }
+            ]
+        },
+        {
+            "name" : "libadwaita",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://gitlab.gnome.org/GNOME/libadwaita.git";,
+                    "branch" : "wip/exalm/browsing-view"
+                }
+            ]
+        },
         {
             "buildsystem": "meson",
             "builddir": true,
diff --git a/src/gs-shell.c b/src/gs-shell.c
index 91946ee07..0d3cc9223 100644
--- a/src/gs-shell.c
+++ b/src/gs-shell.c
@@ -74,15 +74,13 @@ struct _GsShell
        GQueue                  *back_entry_stack;
        GPtrArray               *modal_dialogs;
        gchar                   *events_info_uri;
-       AdwLeaflet              *main_leaflet;
-       AdwLeaflet              *details_leaflet;
+       AdwBrowsingView         *browsing_view;
+       AdwBrowsingViewChild    *main_child;
        AdwViewStack            *stack_loading;
        AdwViewStack            *stack_main;
        AdwViewStack            *stack_sub;
        GsPage                  *page;
 
-       GBinding                *sub_page_header_title_binding;
-
 #ifdef HAVE_MOGWAI
        MwscScheduler           *scheduler;
        gboolean                 scheduler_held;
@@ -90,13 +88,10 @@ struct _GsShell
 #endif  /* HAVE_MOGWAI */
 
        GtkWidget               *main_header;
-       GtkWidget               *details_header;
        GtkWidget               *metered_updates_bar;
        GtkWidget               *search_button;
        GtkWidget               *entry_search;
        GtkWidget               *search_bar;
-       GtkWidget               *button_back;
-       GtkWidget               *button_back2;
        GtkWidget               *notification_event;
        GtkWidget               *button_events_sources;
        GtkWidget               *button_events_no_space;
@@ -106,7 +101,6 @@ struct _GsShell
        GtkWidget               *button_events_dismiss;
        GtkWidget               *label_events;
        GtkWidget               *primary_menu;
-       GtkWidget               *sub_page_header_title;
 
        gboolean                 activate_after_setup;
        gboolean                 is_narrow;
@@ -132,6 +126,12 @@ static GParamSpec *obj_props[PROP_ALLOCATION_WIDTH + 1] = { NULL, };
 
 static guint signals [SIGNAL_LAST] = { 0 };
 
+static char *
+page_name_or_empty (GsShell *shell, const char *name)
+{
+       return g_strdup (name != NULL ? name: "");
+}
+
 static void
 modal_dialog_unmapped_cb (GtkWidget *dialog,
                           GsShell *shell)
@@ -541,11 +541,6 @@ stack_notify_visible_child_cb (GObject    *object,
                break;
        }
 
-       g_clear_object (&shell->sub_page_header_title_binding);
-       shell->sub_page_header_title_binding = g_object_bind_property (adw_view_stack_get_visible_child 
(shell->stack_sub), "title",
-                                                                      shell->sub_page_header_title, "label",
-                                                                      G_BINDING_SYNC_CREATE);
-
        /* refresh the updates bar when moving out of the loading mode, but only
         * if the Mogwai scheduler state is already known, to avoid spuriously
         * showing the updates bar */
@@ -597,15 +592,16 @@ gs_shell_change_mode (GsShell *shell,
 
        adw_view_stack_set_visible_child_name (shell->stack_loading, "main");
        if (mode == GS_SHELL_MODE_DETAILS) {
-               adw_leaflet_set_visible_child_name (shell->details_leaflet, "details");
+               adw_browsing_view_push_by_name (shell->browsing_view, "details", TRUE);
        } else {
-               adw_leaflet_set_visible_child_name (shell->details_leaflet, "main");
-               /* We only change the main leaflet when not reaching the details
-                * page to preserve the navigation history in the UI's state.
-                * First change the page, then the leaflet, to avoid load of
-                * the previously shown page, which will be changed shortly after. */
+               while (adw_browsing_view_get_visible_child (shell->browsing_view) != shell->main_child) {
+                       adw_browsing_view_pop (shell->browsing_view, TRUE);
+               }
+
                adw_view_stack_set_visible_child_name (mode_is_main ? shell->stack_main : shell->stack_sub, 
page_name[mode]);
-               adw_leaflet_set_visible_child_name (shell->main_leaflet, mode_is_main ? "main" : "sub");
+               /* AdwBrowsingView doesn't like it when we push pages already in the hierarchy. */
+               if (!mode_is_main)
+                       adw_browsing_view_push_by_name (shell->browsing_view, "sub", TRUE);
        }
 
        /* do any mode-specific actions */
@@ -837,18 +833,6 @@ gs_shell_go_back (GsShell *shell)
        free_back_entry (entry);
 }
 
-static void
-gs_shell_details_back_button_cb (GtkWidget *widget, GsShell *shell)
-{
-       gs_shell_go_back (shell);
-}
-
-static void
-gs_shell_back_button_cb (GtkWidget *widget, GsShell *shell)
-{
-       gs_shell_go_back (shell);
-}
-
 static void
 gs_shell_reload_cb (GsPluginLoader *plugin_loader, GsShell *shell)
 {
@@ -1000,49 +984,6 @@ search_bar_search_mode_enabled_changed_cb (GtkSearchBar *search_bar,
                gs_shell_go_back (shell);
 }
 
-static void
-go_back (GsShell *shell)
-{
-       if (adw_leaflet_get_adjacent_child (shell->details_leaflet,
-                                           ADW_NAVIGATION_DIRECTION_BACK)) {
-               gtk_widget_activate (shell->button_back2);
-       } else {
-               gtk_widget_activate (shell->button_back);
-       }
-}
-
-static gboolean
-window_key_pressed_cb (GtkEventControllerKey *key_controller,
-                       guint                  keyval,
-                       guint                  keycode,
-                       GdkModifierType        state,
-                       GsShell               *shell)
-{
-       gboolean is_rtl = gtk_widget_get_direction (shell->button_back) == GTK_TEXT_DIR_RTL;
-       gboolean is_alt = (state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_ALT_MASK)) == GDK_ALT_MASK;
-
-       if ((!is_rtl && is_alt && keyval == GDK_KEY_Left) ||
-           (is_rtl && is_alt && keyval == GDK_KEY_Right) ||
-           keyval == GDK_KEY_Back) {
-               go_back (shell);
-               return GDK_EVENT_STOP;
-       }
-
-       return GDK_EVENT_PROPAGATE;
-}
-
-static void
-window_button_pressed_cb (GtkGestureClick *click_gesture,
-                          gint             n_press,
-                          gdouble          x,
-                          gdouble          y,
-                          GsShell         *shell)
-{
-       go_back (shell);
-
-       gtk_gesture_set_state (GTK_GESTURE (click_gesture), GTK_EVENT_SEQUENCE_CLAIMED);
-}
-
 static gboolean
 main_window_closed_cb (GtkWidget *dialog, gpointer user_data)
 {
@@ -2281,15 +2222,16 @@ gs_shell_set_mode (GsShell *shell, GsShellMode mode)
 GsShellMode
 gs_shell_get_mode (GsShell *shell)
 {
-       const gchar *name;
+       AdwBrowsingViewChild *child = adw_browsing_view_get_visible_child (shell->browsing_view);
+       const gchar *name = adw_browsing_view_child_get_child_name (child);
 
        if (g_strcmp0 (adw_view_stack_get_visible_child_name (shell->stack_loading), "loading") == 0)
                return GS_SHELL_MODE_LOADING;
 
-       if (g_strcmp0 (adw_leaflet_get_visible_child_name (shell->details_leaflet), "details") == 0)
+       if (g_strcmp0 (name, "details") == 0)
                return GS_SHELL_MODE_DETAILS;
 
-       if (g_strcmp0 (adw_leaflet_get_visible_child_name (shell->main_leaflet), "main") == 0)
+       if (g_strcmp0 (name, "main") == 0)
                name = adw_view_stack_get_visible_child_name (shell->stack_main);
        else
                name = adw_view_stack_get_visible_child_name (shell->stack_sub);
@@ -2504,8 +2446,6 @@ gs_shell_dispose (GObject *object)
 {
        GsShell *shell = GS_SHELL (object);
 
-       g_clear_object (&shell->sub_page_header_title_binding);
-
        if (shell->back_entry_stack != NULL) {
                g_queue_free_full (shell->back_entry_stack, (GDestroyNotify) free_back_entry);
                shell->back_entry_stack = NULL;
@@ -2645,9 +2585,8 @@ gs_shell_class_init (GsShellClass *klass)
        gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-shell.ui");
 
        gtk_widget_class_bind_template_child (widget_class, GsShell, main_header);
-       gtk_widget_class_bind_template_child (widget_class, GsShell, main_leaflet);
-       gtk_widget_class_bind_template_child (widget_class, GsShell, details_header);
-       gtk_widget_class_bind_template_child (widget_class, GsShell, details_leaflet);
+       gtk_widget_class_bind_template_child (widget_class, GsShell, browsing_view);
+       gtk_widget_class_bind_template_child (widget_class, GsShell, main_child);
        gtk_widget_class_bind_template_child (widget_class, GsShell, stack_loading);
        gtk_widget_class_bind_template_child (widget_class, GsShell, stack_main);
        gtk_widget_class_bind_template_child (widget_class, GsShell, stack_sub);
@@ -2655,8 +2594,6 @@ gs_shell_class_init (GsShellClass *klass)
        gtk_widget_class_bind_template_child (widget_class, GsShell, search_button);
        gtk_widget_class_bind_template_child (widget_class, GsShell, entry_search);
        gtk_widget_class_bind_template_child (widget_class, GsShell, search_bar);
-       gtk_widget_class_bind_template_child (widget_class, GsShell, button_back);
-       gtk_widget_class_bind_template_child (widget_class, GsShell, button_back2);
        gtk_widget_class_bind_template_child (widget_class, GsShell, notification_event);
        gtk_widget_class_bind_template_child (widget_class, GsShell, button_events_sources);
        gtk_widget_class_bind_template_child (widget_class, GsShell, button_events_no_space);
@@ -2666,7 +2603,6 @@ gs_shell_class_init (GsShellClass *klass)
        gtk_widget_class_bind_template_child (widget_class, GsShell, button_events_dismiss);
        gtk_widget_class_bind_template_child (widget_class, GsShell, label_events);
        gtk_widget_class_bind_template_child (widget_class, GsShell, primary_menu);
-       gtk_widget_class_bind_template_child (widget_class, GsShell, sub_page_header_title);
 
        gtk_widget_class_bind_template_child_full (widget_class, "overview_page", FALSE, G_STRUCT_OFFSET 
(GsShell, pages[GS_SHELL_MODE_OVERVIEW]));
        gtk_widget_class_bind_template_child_full (widget_class, "updates_page", FALSE, G_STRUCT_OFFSET 
(GsShell, pages[GS_SHELL_MODE_UPDATES]));
@@ -2681,11 +2617,7 @@ gs_shell_class_init (GsShellClass *klass)
        gtk_widget_class_bind_template_callback (widget_class, gs_shell_main_window_mapped_cb);
        gtk_widget_class_bind_template_callback (widget_class, gs_shell_main_window_realized_cb);
        gtk_widget_class_bind_template_callback (widget_class, main_window_closed_cb);
-       gtk_widget_class_bind_template_callback (widget_class, window_key_pressed_cb);
        gtk_widget_class_bind_template_callback (widget_class, window_keypress_handler);
-       gtk_widget_class_bind_template_callback (widget_class, window_button_pressed_cb);
-       gtk_widget_class_bind_template_callback (widget_class, gs_shell_details_back_button_cb);
-       gtk_widget_class_bind_template_callback (widget_class, gs_shell_back_button_cb);
        gtk_widget_class_bind_template_callback (widget_class, gs_overview_page_button_cb);
        gtk_widget_class_bind_template_callback (widget_class, updates_page_notify_counter_cb);
        gtk_widget_class_bind_template_callback (widget_class, category_page_app_clicked_cb);
@@ -2703,6 +2635,7 @@ gs_shell_class_init (GsShellClass *klass)
        gtk_widget_class_bind_template_callback (widget_class, overlay_get_child_position_cb);
        gtk_widget_class_bind_template_callback (widget_class, gs_shell_details_page_metainfo_loaded_cb);
        gtk_widget_class_bind_template_callback (widget_class, details_page_app_clicked_cb);
+       gtk_widget_class_bind_template_callback (widget_class, page_name_or_empty);
 
        gtk_widget_class_add_binding_action (widget_class, GDK_KEY_q, GDK_CONTROL_MASK, "window.close", NULL);
 }
diff --git a/src/gs-shell.ui b/src/gs-shell.ui
index 52e4a43f0..bd310b334 100644
--- a/src/gs-shell.ui
+++ b/src/gs-shell.ui
@@ -29,18 +29,6 @@
         <signal name="key-pressed" handler="window_keypress_handler"/>
       </object>
     </child>
-    <child>
-      <object class="GtkEventControllerKey">
-        <signal name="key-pressed" handler="window_key_pressed_cb"/>
-      </object>
-    </child>
-    <child>
-      <object class="GtkGestureClick">
-        <!-- Mouse hardware back button -->
-        <property name="button">8</property>
-        <signal name="pressed" handler="window_button_pressed_cb"/>
-      </object>
-    </child>
     <child>
       <object class="AdwViewStack" id="stack_loading">
         <property name="width-request">360</property>
@@ -154,322 +142,260 @@
                   </object>
                 </child>
                 <child>
-                  <object class="AdwLeaflet" id="details_leaflet">
-                    <property name="can-navigate-back">True</property>
-                    <property name="can-unfold">False</property>
+                  <object class="AdwBrowsingView" id="browsing_view">
                     <signal name="notify::visible-child" handler="stack_notify_visible_child_cb"/>
 
-
                     <child>
-                      <object class="AdwLeafletPage">
-                        <property name="name">main</property>
+                      <object class="AdwBrowsingViewChild" id="main_child">
+                        <property name="child-name">main</property>
+                        <property name="title" translatable="yes">Software</property>
                         <property name="child">
-                          <object class="AdwLeaflet" id="main_leaflet">
-                            <property name="can-navigate-back">True</property>
-                            <property name="can-unfold">False</property>
-                            <signal name="notify::visible-child" handler="stack_notify_visible_child_cb"/>
-
+                          <object class="GtkBox" id="main_box">
+                            <property name="orientation">vertical</property>
                             <child>
-                              <object class="AdwLeafletPage">
-                                <property name="name">main</property>
-                                <property name="child">
-                                  <object class="GtkBox" id="main_box">
-                                    <property name="orientation">vertical</property>
-                                    <child>
-                                      <object class="AdwHeaderBar" id="main_header">
-                                        <property name="hexpand">True</property>
-                                        <property name="show-end-title-buttons">True</property>
-                                        <property name="centering-policy">strict</property>
-                                        <child type="start">
-                                          <object class="GtkToggleButton" id="search_button">
-                                            <property name="can_focus">True</property>
-                                            <property name="icon_name">edit-find-symbolic</property>
-                                            <property name="active" bind-source="search_bar" 
bind-property="search-mode-enabled" bind-flags="sync-create|bidirectional"/>
-                                            <accessibility>
-                                              <property name="label" translatable="yes">Search</property>
-                                            </accessibility>
-                                            <style>
-                                              <class name="image-button"/>
-                                            </style>
-                                          </object>
-                                        </child>
-                                        <child type="end">
-                                          <object class="GtkMenuButton" id="menu_button">
-                                            <property name="can_focus">True</property>
-                                            <property name="sensitive">True</property>
-                                            <property name="primary">True</property>
-                                            <property name="icon_name">open-menu-symbolic</property>
-                                            <property name="menu_model">primary_menu</property>
-                                            <accessibility>
-                                              <property name="label" translatable="yes">Primary 
Menu</property>
-                                            </accessibility>
-                                            <style>
-                                              <class name="image-button"/>
-                                            </style>
-                                          </object>
-                                        </child>
-                                        <child type="title">
-                                          <object class="AdwViewSwitcherTitle" id="title_switcher">
-                                            <property name="stack">stack_main</property>
-                                            <property name="title" bind-source="GsShell" 
bind-property="title" bind-flags="sync-create"/>
-                                          </object>
-                                        </child>
-                                      </object>
-                                    </child>
+                              <object class="AdwHeaderBar" id="main_header">
+                                <property name="centering-policy">strict</property>
+                                <child type="start">
+                                  <object class="GtkToggleButton" id="search_button">
+                                    <property name="can_focus">True</property>
+                                    <property name="icon_name">edit-find-symbolic</property>
+                                    <property name="active" bind-source="search_bar" 
bind-property="search-mode-enabled" bind-flags="sync-create|bidirectional"/>
+                                    <accessibility>
+                                      <property name="label" translatable="yes">Search</property>
+                                    </accessibility>
+                                    <style>
+                                      <class name="image-button"/>
+                                    </style>
+                                  </object>
+                                </child>
+                                <child type="end">
+                                  <object class="GtkMenuButton" id="menu_button">
+                                    <property name="can_focus">True</property>
+                                    <property name="sensitive">True</property>
+                                    <property name="primary">True</property>
+                                    <property name="icon_name">open-menu-symbolic</property>
+                                    <property name="menu_model">primary_menu</property>
+                                    <accessibility>
+                                      <property name="label" translatable="yes">Primary Menu</property>
+                                    </accessibility>
+                                    <style>
+                                      <class name="image-button"/>
+                                    </style>
+                                  </object>
+                                </child>
+                                <child type="title">
+                                  <object class="AdwViewSwitcherTitle" id="title_switcher">
+                                    <property name="stack">stack_main</property>
+                                    <property name="title" bind-source="GsShell" bind-property="title" 
bind-flags="sync-create"/>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
 
+                            <child>
+                              <object class="GtkSearchBar" id="search_bar">
+                                <property name="key-capture-widget">GsShell</property>
+                                <signal name="notify::search-mode-enabled" 
handler="search_bar_search_mode_enabled_changed_cb"/>
+                                <child>
+                                  <object class="AdwClamp">
+                                    <property name="hexpand">True</property>
+                                    <property name="maximum_size">500</property>
+                                    <property name="tightening_threshold">500</property>
                                     <child>
-                                      <object class="GtkSearchBar" id="search_bar">
-                                        <property name="key-capture-widget">GsShell</property>
-                                        <signal name="notify::search-mode-enabled" 
handler="search_bar_search_mode_enabled_changed_cb"/>
-                                        <child>
-                                          <object class="AdwClamp">
-                                            <property name="hexpand">True</property>
-                                            <property name="maximum_size">500</property>
-                                            <property name="tightening_threshold">500</property>
-                                            <child>
-                                              <object class="GtkSearchEntry" id="entry_search">
-                                                <property name="can_focus">True</property>
-                                                <property name="activates_default">True</property>
-                                                <signal name="search-changed" 
handler="search_changed_handler"/>
-                                              </object>
-                                            </child>
-                                          </object>
-                                        </child>
-                                      </object>
-                                    </child>
-                                    <child>
-                                      <object class="GtkInfoBar" id="metered_updates_bar">
-                                        <property name="message-type">GTK_MESSAGE_INFO</property>
-                                        <property name="show-close-button">False</property>
-                                        <property name="revealed">False</property>
-                                        <signal name="response" 
handler="gs_shell_metered_updates_bar_response_cb"/>
-                                        <child>
-                                          <object class="GtkBox">
-                                            <property name="orientation">vertical</property>
-                                            <property name="spacing">6</property>
-                                            <property name="margin_top">6</property>
-                                            <property name="margin_start">6</property>
-                                            <property name="margin_bottom">6</property>
-                                            <child>
-                                              <object class="GtkLabel">
-                                                <property name="can_focus">False</property>
-                                                <property name="label" translatable="yes">Automatic Updates 
Paused</property>
-                                                <property name="vexpand">True</property>
-                                                <property name="xalign">0.0</property>
-                                                <property name="wrap">True</property>
-                                                <attributes>
-                                                  <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
-                                                </attributes>
-                                              </object>
-                                            </child>
-                                          </object>
-                                        </child>
-                                        <child type="action">
-                                          <object class="GtkBox">
-                                            <property name="margin_end">6</property>
-                                            <child>
-                                              <object class="GtkButton" id="metered_updates_button">
-                                                <property name="can_focus">True</property>
-                                                <property name="use_underline">True</property>
-                                                <property name="label" translatable="yes">Find Out 
_More</property>
-                                              </object>
-                                            </child>
-                                          </object>
-                                        </child>
-                                        <action-widgets>
-                                          <action-widget 
response="GTK_RESPONSE_OK">metered_updates_button</action-widget>
-                                        </action-widgets>
+                                      <object class="GtkSearchEntry" id="entry_search">
+                                        <property name="can_focus">True</property>
+                                        <property name="activates_default">True</property>
+                                        <signal name="search-changed" handler="search_changed_handler"/>
                                       </object>
                                     </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkInfoBar" id="metered_updates_bar">
+                                <property name="message-type">GTK_MESSAGE_INFO</property>
+                                <property name="show-close-button">False</property>
+                                <property name="revealed">False</property>
+                                <signal name="response" handler="gs_shell_metered_updates_bar_response_cb"/>
+                                <child>
+                                  <object class="GtkBox">
+                                    <property name="orientation">vertical</property>
+                                    <property name="spacing">6</property>
+                                    <property name="margin_top">6</property>
+                                    <property name="margin_start">6</property>
+                                    <property name="margin_bottom">6</property>
                                     <child>
-                                      <object class="AdwViewStack" id="stack_main">
-                                        <property name="hexpand">True</property>
+                                      <object class="GtkLabel">
+                                        <property name="can_focus">False</property>
+                                        <property name="label" translatable="yes">Automatic Updates 
Paused</property>
                                         <property name="vexpand">True</property>
-                                        <property name="hhomogeneous">False</property>
-                                        <property name="vhomogeneous">False</property>
-                                        <signal name="notify::visible-child" 
handler="stack_notify_visible_child_cb"/>
-                                        <child>
-                                          <object class="AdwViewStackPage">
-                                            <property name="name">overview</property>
-                                            <property name="title" translatable="yes" comments="Translators: 
A label for a button to show all available software.">Explore</property>
-                                            <property name="icon-name">explore-symbolic</property>
-                                            <property name="child">
-                                              <object class="GsOverviewPage" id="overview_page">
-                                              </object>
-                                            </property>
-                                          </object>
-                                        </child>
-                                        <child>
-                                          <object class="AdwViewStackPage">
-                                            <property name="name">installed</property>
-                                            <!-- FIXME: Add mnemonics support when it’s supported in GTK 
(same for the other pages).
-                                                 See https://gitlab.gnome.org/GNOME/gtk/-/issues/3134 -->
-                                            <property name="title" translatable="yes" comments="Translators: 
A label for a button to show only software which is already installed." context="List of installed 
apps">Installed</property>
-                                            <property name="icon-name">app-installed-symbolic</property>
-                                            <property name="child">
-                                              <object class="GsInstalledPage" id="installed_page">
-                                                <property name="is-narrow" bind-source="GsShell" 
bind-property="is-narrow" bind-flags="sync-create"/>
-                                              </object>
-                                            </property>
-                                          </object>
-                                        </child>
-                                        <child>
-                                          <object class="AdwViewStackPage">
-                                            <property name="name">search</property>
-                                            <property name="child">
-                                              <object class="GsSearchPage" id="search_page">
-                                              </object>
-                                            </property>
-                                          </object>
-                                        </child>
-                                        <child>
-                                          <object class="AdwViewStackPage">
-                                            <property name="name">updates</property>
-                                            <property name="title" translatable="yes" comments="Translators: 
A label for a button to show only updates which are available to install." context="Header bar button for 
list of apps to be updated">Updates</property>
-                                            <property 
name="icon-name">emblem-synchronizing-symbolic</property>
-                                            <property name="badge-number" bind-source="updates_page" 
bind-property="counter" bind-flags="sync-create"/>
-                                            <property name="child">
-                                              <object class="GsUpdatesPage" id="updates_page">
-                                                <property name="is-narrow" bind-source="GsShell" 
bind-property="is-narrow" bind-flags="sync-create"/>
-                                                <signal name="notify::counter" 
handler="updates_page_notify_counter_cb"/>
-                                              </object>
-                                            </property>
-                                          </object>
-                                        </child>
+                                        <property name="xalign">0.0</property>
+                                        <property name="wrap">True</property>
+                                        <attributes>
+                                          <attribute name="weight" value="PANGO_WEIGHT_BOLD"/>
+                                        </attributes>
                                       </object>
                                     </child>
+                                  </object>
+                                </child>
+                                <child type="action">
+                                  <object class="GtkBox">
+                                    <property name="margin_end">6</property>
                                     <child>
-                                      <object class="AdwViewSwitcherBar" id="sidebar_switcher">
-                                        <property name="reveal" bind-source="title_switcher" 
bind-property="title-visible" bind-flags="sync-create"/>
-                                        <property name="stack">stack_main</property>
+                                      <object class="GtkButton" id="metered_updates_button">
+                                        <property name="can_focus">True</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="label" translatable="yes">Find Out _More</property>
                                       </object>
                                     </child>
                                   </object>
-                                </property>
+                                </child>
+                                <action-widgets>
+                                  <action-widget 
response="GTK_RESPONSE_OK">metered_updates_button</action-widget>
+                                </action-widgets>
                               </object>
                             </child>
-
                             <child>
-                              <object class="AdwLeafletPage">
-                                <property name="name">sub</property>
-                                <property name="child">
-                                  <object class="GtkBox" id="sub_box">
-                                    <property name="orientation">vertical</property>
-                                    <child>
-                                      <object class="AdwHeaderBar" id="sub_header">
-                                        <property name="show-end-title-buttons">True</property>
-                                        <property name="hexpand">True</property>
-                                        <child>
-                                          <object class="GtkButton" id="button_back">
-                                            <property name="can_focus">True</property>
-                                            <signal name="clicked" handler="gs_shell_back_button_cb"/>
-                                            <accessibility>
-                                              <property name="label" translatable="yes">Go back</property>
-                                            </accessibility>
-                                            <style>
-                                              <class name="image-button"/>
-                                            </style>
-                                            <child>
-                                              <object class="GtkImage" id="back_image">
-                                                <property name="icon_name">go-previous-symbolic</property>
-                                                <property name="icon-size">normal</property>
-                                              </object>
-                                            </child>
-                                          </object>
-                                        </child>
-                                        <child type="title">
-                                          <object class="GtkLabel" id="sub_page_header_title">
-                                            <property name="selectable">False</property>
-                                            <property name="ellipsize">end</property>
-                                            <style>
-                                              <class name="title"/>
-                                            </style>
-                                          </object>
-                                        </child>
+                              <object class="AdwViewStack" id="stack_main">
+                                <property name="hexpand">True</property>
+                                <property name="vexpand">True</property>
+                                <property name="hhomogeneous">False</property>
+                                <property name="vhomogeneous">False</property>
+                                <signal name="notify::visible-child" 
handler="stack_notify_visible_child_cb"/>
+                                <child>
+                                  <object class="AdwViewStackPage">
+                                    <property name="name">overview</property>
+                                    <property name="title" translatable="yes" comments="Translators: A label 
for a button to show all available software.">Explore</property>
+                                    <property name="icon-name">explore-symbolic</property>
+                                    <property name="child">
+                                      <object class="GsOverviewPage" id="overview_page">
                                       </object>
-                                    </child>
-                                    <child>
-                                      <object class="AdwViewStack" id="stack_sub">
-                                        <property name="hexpand">True</property>
-                                        <property name="vexpand">True</property>
-                                        <property name="hhomogeneous">False</property>
-                                        <property name="vhomogeneous">False</property>
-                                        <signal name="notify::visible-child" 
handler="stack_notify_visible_child_cb"/>
-                                        <child>
-                                          <object class="AdwViewStackPage">
-                                            <property name="name">moderate</property>
-                                            <property name="child">
-                                              <object class="GsModeratePage" id="moderate_page">
-                                              </object>
-                                            </property>
-                                          </object>
-                                        </child>
-                                        <child>
-                                          <object class="AdwViewStackPage">
-                                            <property name="name">category</property>
-                                            <property name="child">
-                                              <object class="GsCategoryPage" id="category_page">
-                                                <signal name="app-clicked" 
handler="category_page_app_clicked_cb"/>
-                                              </object>
-                                            </property>
-                                          </object>
-                                        </child>
-                                        <child>
-                                          <object class="AdwViewStackPage">
-                                            <property name="name">extras</property>
-                                            <property name="child">
-                                              <object class="GsExtrasPage" id="extras_page">
-                                              </object>
-                                            </property>
-                                          </object>
-                                        </child>
+                                    </property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="AdwViewStackPage">
+                                    <property name="name">installed</property>
+                                    <!-- FIXME: Add mnemonics support when it’s supported in GTK (same for 
the other pages).
+                                         See https://gitlab.gnome.org/GNOME/gtk/-/issues/3134 -->
+                                    <property name="title" translatable="yes" comments="Translators: A label 
for a button to show only software which is already installed." context="List of installed 
apps">Installed</property>
+                                    <property name="icon-name">app-installed-symbolic</property>
+                                    <property name="child">
+                                      <object class="GsInstalledPage" id="installed_page">
+                                        <property name="is-narrow" bind-source="GsShell" 
bind-property="is-narrow" bind-flags="sync-create"/>
                                       </object>
-                                    </child>
+                                    </property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="AdwViewStackPage">
+                                    <property name="name">search</property>
+                                    <property name="child">
+                                      <object class="GsSearchPage" id="search_page">
+                                      </object>
+                                    </property>
                                   </object>
-                                </property>
+                                </child>
+                                <child>
+                                  <object class="AdwViewStackPage">
+                                    <property name="name">updates</property>
+                                    <property name="title" translatable="yes" comments="Translators: A label 
for a button to show only updates which are available to install." context="Header bar button for list of 
apps to be updated">Updates</property>
+                                    <property name="icon-name">emblem-synchronizing-symbolic</property>
+                                    <property name="badge-number" bind-source="updates_page" 
bind-property="counter" bind-flags="sync-create"/>
+                                    <property name="child">
+                                      <object class="GsUpdatesPage" id="updates_page">
+                                        <property name="is-narrow" bind-source="GsShell" 
bind-property="is-narrow" bind-flags="sync-create"/>
+                                        <signal name="notify::counter" 
handler="updates_page_notify_counter_cb"/>
+                                      </object>
+                                    </property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="AdwViewSwitcherBar" id="sidebar_switcher">
+                                <property name="reveal" bind-source="title_switcher" 
bind-property="title-visible" bind-flags="sync-create"/>
+                                <property name="stack">stack_main</property>
                               </object>
                             </child>
-
                           </object>
                         </property>
                       </object>
                     </child>
 
                     <child>
-                      <object class="AdwLeafletPage">
-                        <property name="name">details</property>
+                      <object class="AdwBrowsingViewChild">
+                        <property name="child-name">sub</property>
+                        <binding name="title">
+                          <closure type="gchararray" function="page_name_or_empty">
+                            <lookup type="GsPage" name="title">
+                              <lookup type="AdwViewStack" name="visible-child">stack_sub</lookup>
+                            </lookup>
+                          </closure>
+                        </binding>
                         <property name="child">
-                          <object class="GtkBox" id="details_box">
+                          <object class="GtkBox" id="sub_box">
                             <property name="orientation">vertical</property>
                             <child>
-                              <object class="AdwHeaderBar" id="details_header">
+                              <object class="AdwHeaderBar"/>
+                            </child>
+                            <child>
+                              <object class="AdwViewStack" id="stack_sub">
                                 <property name="hexpand">True</property>
-                                <property name="show-end-title-buttons">True</property>
-                                <property name="title-widget">
-                                  <object class="AdwWindowTitle">
-                                    <property name="title" bind-source="details_page" bind-property="title" 
bind-flags="sync-create"/>
+                                <property name="vexpand">True</property>
+                                <property name="hhomogeneous">False</property>
+                                <property name="vhomogeneous">False</property>
+                                <signal name="notify::visible-child" 
handler="stack_notify_visible_child_cb"/>
+                                <child>
+                                  <object class="AdwViewStackPage">
+                                    <property name="name">moderate</property>
+                                    <property name="child">
+                                      <object class="GsModeratePage" id="moderate_page">
+                                      </object>
+                                    </property>
                                   </object>
-                                </property>
+                                </child>
                                 <child>
-                                  <object class="GtkButton" id="button_back2">
-                                    <property name="can_focus">True</property>
-                                    <signal name="clicked" handler="gs_shell_details_back_button_cb"/>
-                                    <accessibility>
-                                      <property name="label" translatable="yes">Go back</property>
-                                    </accessibility>
-                                    <style>
-                                      <class name="image-button"/>
-                                    </style>
-                                    <child>
-                                      <object class="GtkImage">
-                                        <property name="icon_name">go-previous-symbolic</property>
-                                        <property name="icon-size">normal</property>
+                                  <object class="AdwViewStackPage">
+                                    <property name="name">category</property>
+                                    <property name="child">
+                                      <object class="GsCategoryPage" id="category_page">
+                                        <signal name="app-clicked" handler="category_page_app_clicked_cb"/>
                                       </object>
-                                    </child>
+                                    </property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="AdwViewStackPage">
+                                    <property name="name">extras</property>
+                                    <property name="child">
+                                      <object class="GsExtrasPage" id="extras_page">
+                                      </object>
+                                    </property>
                                   </object>
                                 </child>
                               </object>
                             </child>
+                          </object>
+                        </property>
+                      </object>
+                    </child>
+
+                    <child>
+                      <object class="AdwBrowsingViewChild">
+                        <property name="child-name">details</property>
+                        <binding name="title">
+                          <closure type="gchararray" function="page_name_or_empty">
+                            <lookup type="GsDetailsPage" name="title">details_page</lookup>
+                          </closure>
+                        </binding>
+                        <property name="child">
+                          <object class="GtkBox" id="details_box">
+                            <property name="orientation">vertical</property>
+                            <child>
+                              <object class="AdwHeaderBar" id="details_header"/>
+                            </child>
                             <child>
                               <object class="GsDetailsPage" id="details_page">
                                 <property name="is-narrow" bind-source="GsShell" bind-property="is-narrow" 
bind-flags="sync-create"/>
@@ -481,7 +407,6 @@
                         </property>
                       </object>
                     </child>
-
                   </object>
                 </child>
               </object>


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