[nautilus/wip/antoniof/gtk4-preparation-popovers: 6/17] toolbar: Use models for view and app menus




commit 3e0c4caadf6677adb090e636a9614dff6da4e944
Author: António Fernandes <antoniof gnome org>
Date:   Thu Dec 16 10:54:58 2021 +0000

    toolbar: Use models for view and app menus
    
    Building menus with regular widgets brings too much complexity. Also,
    it makes porting to GTK4 harder because GtkPopoverMenu as we know it
    and its GtkModelButtons are gone.
    
    Let's use a GMenuModel-built GtkPopover instead. While we are at it,
    also move Undo and Redo to the primary menu, where they belong.

 src/nautilus-files-view.c                      | 118 ++------
 src/nautilus-places-view.c                     |  13 +-
 src/nautilus-toolbar-menu-sections.h           |   7 +-
 src/nautilus-toolbar.c                         | 101 +++----
 src/nautilus-ui-utilities.c                    |  66 +++++
 src/nautilus-ui-utilities.h                    |   7 +
 src/resources/css/nautilus.css                 |   6 -
 src/resources/ui/nautilus-toolbar-view-menu.ui | 321 ++++-----------------
 src/resources/ui/nautilus-toolbar.ui           | 374 +++++++------------------
 9 files changed, 308 insertions(+), 705 deletions(-)
---
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 3ee33d107..572cd07c8 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -264,13 +264,6 @@ typedef struct
 
     /* Toolbar menu */
     NautilusToolbarMenuSections *toolbar_menu_sections;
-    GtkWidget *sort_menu;
-    GtkWidget *sort_trash_time;
-    GtkWidget *visible_columns;
-    GtkWidget *stop;
-    GtkWidget *reload;
-    GtkWidget *zoom_controls_box;
-    GtkWidget *zoom_level_label;
 
     /* Exposed menus, for the path bar etc. */
     GMenuModel *extensions_background_menu;
@@ -279,9 +272,6 @@ typedef struct
     /* Non exported menu, only for caching */
     GMenuModel *scripts_menu;
 
-    gulong stop_signal_handler;
-    gulong reload_signal_handler;
-
     GCancellable *starred_cancellable;
     NautilusTagManager *tag_manager;
 
@@ -3291,7 +3281,7 @@ nautilus_files_view_finalize (GObject *object)
     g_clear_object (&priv->background_menu_model);
     g_clear_object (&priv->selection_menu_model);
     g_clear_object (&priv->toolbar_menu_sections->zoom_section);
-    g_clear_object (&priv->toolbar_menu_sections->extended_section);
+    g_clear_object (&priv->toolbar_menu_sections->sort_section);
     g_clear_object (&priv->extensions_background_menu);
     g_clear_object (&priv->templates_menu);
     g_clear_object (&priv->rename_file_controller);
@@ -8182,34 +8172,32 @@ nautilus_files_view_update_context_menus (NautilusFilesView *view)
 static void
 nautilus_files_view_reset_view_menu (NautilusFilesView *view)
 {
-    NautilusFilesViewPrivate *priv;
-    GActionGroup *view_action_group;
-    gboolean sort_available;
-    g_autofree gchar *zoom_level_percent = NULL;
+    NautilusFilesViewPrivate *priv = nautilus_files_view_get_instance_private (view);
     NautilusFile *file;
+    GMenuModel *zoom_section = priv->toolbar_menu_sections->zoom_section;
+    GMenuModel *sort_section = priv->toolbar_menu_sections->sort_section;
+    g_autofree gchar *zoom_level_percent = NULL;
+    const gchar *trashed_action;
+    gint i;
 
-    view_action_group = nautilus_files_view_get_action_group (view);
-    priv = nautilus_files_view_get_instance_private (view);
     file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (view));
 
-    gtk_widget_set_visible (priv->visible_columns,
-                            g_action_group_has_action (view_action_group, "visible-columns"));
-
-    sort_available = g_action_group_get_action_enabled (view_action_group, "sort");
-    gtk_widget_set_visible (priv->sort_menu, sort_available);
-    gtk_widget_set_visible (priv->sort_trash_time,
-                            nautilus_file_is_in_trash (file));
-
-    /* We want to make insensitive available actions but that are not current
-     * available due to the directory
-     */
-    gtk_widget_set_sensitive (priv->sort_menu,
-                              !nautilus_files_view_is_empty (view));
-    gtk_widget_set_sensitive (priv->zoom_controls_box,
-                              !nautilus_files_view_is_empty (view));
-
+    /* We want to show the percentage like this:    [ - | 100% | + ]   */
     zoom_level_percent = g_strdup_printf ("%.0f%%", nautilus_files_view_get_zoom_level_percentage (view) * 
100.0);
-    gtk_label_set_label (GTK_LABEL (priv->zoom_level_label), zoom_level_percent);
+    i = nautilus_g_menu_model_find_by_string (zoom_section, "action", "view.zoom-standard");
+    g_return_if_fail (i != -1);
+    nautilus_g_menu_replace_string_in_item (G_MENU (zoom_section), i,
+                                            "label", zoom_level_percent);
+
+    /* When not in Trash, set an inexistant action to hide the menu item. This
+     * works under the assumptiont that the menu item has its "hidden-when"
+     * attribute set to "action-disabled", and that an inexistant action is
+     * treated as a disabled action. */
+    trashed_action = nautilus_file_is_in_trash (file) ? "view.sort" : "doesnt-exist";
+    i = nautilus_g_menu_model_find_by_string (sort_section, "target", "trash-time");
+    g_return_if_fail (i != -1);
+    nautilus_g_menu_replace_string_in_item (G_MENU (sort_section), i,
+                                            "action", trashed_action);
 }
 
 /* Convenience function to reset the menus owned by the view but managed on
@@ -9214,32 +9202,6 @@ on_event (GtkWidget *widget,
     return GDK_EVENT_PROPAGATE;
 }
 
-static void
-action_reload_enabled_changed (GActionGroup      *action_group,
-                               gchar             *action_name,
-                               gboolean           enabled,
-                               NautilusFilesView *view)
-{
-    NautilusFilesViewPrivate *priv;
-
-    priv = nautilus_files_view_get_instance_private (view);
-
-    gtk_widget_set_visible (priv->reload, enabled);
-}
-
-static void
-action_stop_enabled_changed (GActionGroup      *action_group,
-                             gchar             *action_name,
-                             gboolean           enabled,
-                             NautilusFilesView *view)
-{
-    NautilusFilesViewPrivate *priv;
-
-    priv = nautilus_files_view_get_instance_private (view);
-
-    gtk_widget_set_visible (priv->stop, enabled);
-}
-
 static void
 on_parent_changed (GObject    *object,
                    GParamSpec *pspec,
@@ -9258,18 +9220,6 @@ on_parent_changed (GObject    *object,
     parent = gtk_widget_get_parent (widget);
     window = nautilus_files_view_get_window (view);
 
-    if (priv->stop_signal_handler > 0)
-    {
-        g_signal_handler_disconnect (window, priv->stop_signal_handler);
-        priv->stop_signal_handler = 0;
-    }
-
-    if (priv->reload_signal_handler > 0)
-    {
-        g_signal_handler_disconnect (window, priv->reload_signal_handler);
-        priv->reload_signal_handler = 0;
-    }
-
     if (parent != NULL)
     {
         if (priv->slot == nautilus_window_get_active_slot (window))
@@ -9279,17 +9229,6 @@ on_parent_changed (GObject    *object,
                                             "view",
                                             G_ACTION_GROUP (priv->view_action_group));
         }
-
-        priv->stop_signal_handler =
-            g_signal_connect (window,
-                              "action-enabled-changed::stop",
-                              G_CALLBACK (action_stop_enabled_changed),
-                              view);
-        priv->reload_signal_handler =
-            g_signal_connect (window,
-                              "action-enabled-changed::reload",
-                              G_CALLBACK (action_reload_enabled_changed),
-                              view);
     }
     else
     {
@@ -9643,17 +9582,8 @@ nautilus_files_view_init (NautilusFilesView *view)
     /* Toolbar menu */
     builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-toolbar-view-menu.ui");
     priv->toolbar_menu_sections = g_new0 (NautilusToolbarMenuSections, 1);
-    priv->toolbar_menu_sections->supports_undo_redo = TRUE;
-    priv->toolbar_menu_sections->zoom_section = GTK_WIDGET (g_object_ref_sink (gtk_builder_get_object 
(builder, "zoom_section")));
-    priv->toolbar_menu_sections->extended_section = GTK_WIDGET (g_object_ref_sink (gtk_builder_get_object 
(builder, "extended_section")));
-    priv->zoom_controls_box = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_controls_box"));
-    priv->zoom_level_label = GTK_WIDGET (gtk_builder_get_object (builder, "zoom_level_label"));
-
-    priv->sort_menu = GTK_WIDGET (gtk_builder_get_object (builder, "sort_menu"));
-    priv->sort_trash_time = GTK_WIDGET (gtk_builder_get_object (builder, "sort_trash_time"));
-    priv->visible_columns = GTK_WIDGET (gtk_builder_get_object (builder, "visible_columns"));
-    priv->reload = GTK_WIDGET (gtk_builder_get_object (builder, "reload"));
-    priv->stop = GTK_WIDGET (gtk_builder_get_object (builder, "stop"));
+    priv->toolbar_menu_sections->zoom_section = G_MENU_MODEL (g_object_ref (gtk_builder_get_object (builder, 
"zoom_section")));
+    priv->toolbar_menu_sections->sort_section = G_MENU_MODEL (g_object_ref (gtk_builder_get_object (builder, 
"sort_section")));
 
     g_signal_connect (view,
                       "end-file-changes",
diff --git a/src/nautilus-places-view.c b/src/nautilus-places-view.c
index d3137e495..a2edbfc85 100644
--- a/src/nautilus-places-view.c
+++ b/src/nautilus-places-view.c
@@ -32,7 +32,6 @@ typedef struct
 {
     GFile *location;
     NautilusQuery *search_query;
-    NautilusToolbarMenuSections *toolbar_menu_sections;
 
     GtkWidget *places_view;
 } NautilusPlacesViewPrivate;
@@ -150,8 +149,6 @@ nautilus_places_view_finalize (GObject *object)
     g_clear_object (&priv->location);
     g_clear_object (&priv->search_query);
 
-    g_free (priv->toolbar_menu_sections);
-
     G_OBJECT_CLASS (nautilus_places_view_parent_class)->finalize (object);
 }
 
@@ -310,11 +307,7 @@ nautilus_places_view_set_search_query (NautilusView  *view,
 static NautilusToolbarMenuSections *
 nautilus_places_view_get_toolbar_menu_sections (NautilusView *view)
 {
-    NautilusPlacesViewPrivate *priv;
-
-    priv = nautilus_places_view_get_instance_private (NAUTILUS_PLACES_VIEW (view));
-
-    return priv->toolbar_menu_sections;
+    return NULL;
 }
 
 static gboolean
@@ -413,10 +406,6 @@ nautilus_places_view_init (NautilusPlacesView *self)
                               "show-error-message",
                               G_CALLBACK (show_error_message_cb),
                               self);
-
-    /* Toolbar menu */
-    priv->toolbar_menu_sections = g_new0 (NautilusToolbarMenuSections, 1);
-    priv->toolbar_menu_sections->supports_undo_redo = FALSE;
 }
 
 NautilusPlacesView *
diff --git a/src/nautilus-toolbar-menu-sections.h b/src/nautilus-toolbar-menu-sections.h
index c7864eac8..9b5c136fb 100644
--- a/src/nautilus-toolbar-menu-sections.h
+++ b/src/nautilus-toolbar-menu-sections.h
@@ -24,9 +24,8 @@ G_BEGIN_DECLS
 typedef struct _NautilusToolbarMenuSections NautilusToolbarMenuSections;
 
 struct _NautilusToolbarMenuSections {
-        GtkWidget *zoom_section;
-        GtkWidget *extended_section;
-        gboolean   supports_undo_redo;
+        GMenuModel *sort_section;
+        GMenuModel *zoom_section;
 };
 
-G_END_DECLS
\ No newline at end of file
+G_END_DECLS
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c
index 54959559b..4cfa50c56 100644
--- a/src/nautilus-toolbar.c
+++ b/src/nautilus-toolbar.c
@@ -73,23 +73,20 @@ struct _NautilusToolbar
     guint operations_button_attention_timeout_id;
 
     GtkWidget *operations_button;
-    GtkWidget *view_button;
-    GtkWidget *view_menu_zoom_section;
-    GtkWidget *view_menu_undo_redo_section;
-    GtkWidget *view_menu_extended_section;
-    GtkWidget *undo_button;
-    GtkWidget *redo_button;
-    GtkWidget *view_toggle_button;
-    GtkWidget *view_toggle_icon;
-
-    GtkWidget *app_menu;
-
     GtkWidget *operations_popover;
     GtkWidget *operations_list;
     GListStore *progress_infos_model;
     GtkWidget *operations_revealer;
     GtkWidget *operations_icon;
 
+    GtkWidget *view_toggle_button;
+    GtkWidget *view_toggle_icon;
+    GtkWidget *view_button;
+    GMenuModel *view_menu;
+
+    GtkWidget *app_button;
+    GMenuModel *undo_redo_section;
+
     GtkWidget *forward_button;
     GtkWidget *forward_menu;
     GtkGesture *forward_button_longpress_gesture;
@@ -687,28 +684,15 @@ on_progress_has_viewers_changed (NautilusProgressInfoManager *manager,
 }
 
 static void
-update_menu_item (GtkWidget       *menu_item,
-                  NautilusToolbar *self,
-                  const char      *action_name,
-                  gboolean         enabled,
-                  char            *label)
+update_action (NautilusToolbar *self,
+               const char      *action_name,
+               gboolean         enabled)
 {
     GAction *action;
-    GValue val = G_VALUE_INIT;
 
     /* Activate/deactivate */
     action = g_action_map_lookup_action (G_ACTION_MAP (self->window), action_name);
     g_simple_action_set_enabled (G_SIMPLE_ACTION (action), enabled);
-
-    /* Set the text of the menu item. Can't use gtk_button_set_label here as
-     * we need to set the text property, not the label. There's no equivalent
-     * gtk_model_button_set_text function (refer to #766083 for discussion
-     * on adding a set_text function)
-     */
-    g_value_init (&val, G_TYPE_STRING);
-    g_value_set_string (&val, label);
-    g_object_set_property (G_OBJECT (menu_item), "text", &val);
-    g_value_unset (&val);
 }
 
 static void
@@ -723,6 +707,8 @@ undo_manager_changed (NautilusToolbar *self)
     g_autofree gchar *undo_description = NULL;
     g_autofree gchar *redo_description = NULL;
     gboolean is_undo;
+    g_autoptr (GMenu) updated_section = g_menu_new ();
+    g_autoptr (GMenuItem) menu_item = NULL;
 
     /* Look up the last action from the undo manager, and get the text that
      * describes it, e.g. "Undo Create Folder"/"Redo Create Folder"
@@ -750,14 +736,21 @@ undo_manager_changed (NautilusToolbar *self)
         g_free (undo_label);
         undo_label = g_strdup (_("_Undo"));
     }
-    update_menu_item (self->undo_button, self, "undo", undo_active, undo_label);
+    g_set_object (&menu_item, g_menu_item_new (undo_label, "win.undo"));
+    g_menu_append_item (updated_section, menu_item);
+    update_action (self, "undo", undo_active);
 
     if (!redo_active || redo_label == NULL)
     {
         g_free (redo_label);
         redo_label = g_strdup (_("_Redo"));
     }
-    update_menu_item (self->redo_button, self, "redo", redo_active, redo_label);
+    g_set_object (&menu_item, g_menu_item_new (redo_label, "win.redo"));
+    g_menu_append_item (updated_section, menu_item);
+    update_action (self, "redo", redo_active);
+
+    nautilus_gmenu_set_from_model (G_MENU (self->undo_redo_section),
+                                   G_MENU_MODEL (updated_section));
 }
 
 static void
@@ -1148,9 +1141,11 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_list);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, operations_revealer);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_button);
+    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_menu);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_toggle_button);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_toggle_icon);
-    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, app_menu);
+    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, app_button);
+    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, undo_redo_section);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, back_button);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, back_menu);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, forward_button);
@@ -1160,12 +1155,6 @@ nautilus_toolbar_class_init (NautilusToolbarClass *klass)
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, path_bar_container);
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, location_entry_container);
 
-    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_menu_zoom_section);
-    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_menu_undo_redo_section);
-    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, view_menu_extended_section);
-    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, undo_button);
-    gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, redo_button);
-
     gtk_widget_class_bind_template_child (widget_class, NautilusToolbar, search_button);
 
     gtk_widget_class_bind_template_callback (widget_class, on_operations_icon_draw);
@@ -1244,34 +1233,29 @@ on_slot_toolbar_menu_sections_changed (NautilusToolbar    *self,
                                        NautilusWindowSlot *slot)
 {
     NautilusToolbarMenuSections *new_sections;
-
-    box_remove_all_children (GTK_BOX (self->view_menu_zoom_section));
-    box_remove_all_children (GTK_BOX (self->view_menu_extended_section));
+    g_autoptr (GMenuItem) zoom_item = NULL;
+    g_autoptr (GMenuItem) sort_item = NULL;
 
     new_sections = nautilus_window_slot_get_toolbar_menu_sections (slot);
+
+    gtk_widget_set_sensitive (self->view_button, (new_sections != NULL));
     if (new_sections == NULL)
     {
         return;
     }
 
-    gtk_widget_set_visible (self->view_menu_undo_redo_section,
-                            new_sections->supports_undo_redo);
+    /* Let's assume that zoom and sort sections are the first and second items
+     * in view_menu, as per nautilus-toolbar.ui. */
 
-    if (new_sections->zoom_section != NULL)
-    {
-        gtk_box_pack_start (GTK_BOX (self->view_menu_zoom_section),
-                            new_sections->zoom_section, FALSE, FALSE, 0);
-    }
+    zoom_item = g_menu_item_new_from_model (self->view_menu, 0);
+    g_menu_remove (G_MENU (self->view_menu), 0);
+    g_menu_item_set_section (zoom_item, new_sections->zoom_section);
+    g_menu_insert_item (G_MENU (self->view_menu), 0, zoom_item);
 
-    if (new_sections->extended_section != NULL)
-    {
-        gtk_box_pack_start (GTK_BOX (self->view_menu_extended_section),
-                            new_sections->extended_section, FALSE, FALSE, 0);
-    }
-
-    gtk_widget_set_sensitive (self->view_button, (new_sections->extended_section != NULL ||
-                                                  new_sections->zoom_section != NULL ||
-                                                  new_sections->supports_undo_redo));
+    sort_item = g_menu_item_new_from_model (self->view_menu, 1);
+    g_menu_remove (G_MENU (self->view_menu), 1);
+    g_menu_item_set_section (sort_item, new_sections->sort_section);
+    g_menu_insert_item (G_MENU (self->view_menu), 1, sort_item);
 }
 
 
@@ -1419,9 +1403,14 @@ nautilus_toolbar_set_window_slot (NautilusToolbar    *self,
 gboolean
 nautilus_toolbar_is_menu_visible (NautilusToolbar *self)
 {
+    GtkWidget *menu;
+
     g_return_val_if_fail (NAUTILUS_IS_TOOLBAR (self), FALSE);
 
-    return gtk_widget_is_visible (self->app_menu);
+    menu = GTK_WIDGET (gtk_menu_button_get_popover (GTK_MENU_BUTTON (self->app_button)));
+    g_return_val_if_fail (menu != NULL, FALSE);
+
+    return gtk_widget_is_visible (menu);
 }
 
 gboolean
diff --git a/src/nautilus-ui-utilities.c b/src/nautilus-ui-utilities.c
index 79a624a14..60d667a57 100644
--- a/src/nautilus-ui-utilities.c
+++ b/src/nautilus-ui-utilities.c
@@ -67,6 +67,72 @@ nautilus_gmenu_set_from_model (GMenu      *target_menu,
     }
 }
 
+/**
+ * nautilus_g_menu_model_find_by_string:
+ * @model: the #GMenuModel with items to search
+ * @attribute: the menu item attribute to compare with
+ * @string: the string to match the value of @attribute
+ *
+ * This will search for an item in the model which has got the @attribute and
+ * whose value is equal to @string.
+ *
+ * It is assumed that @attribute has the a GVariant format string "s".
+ *
+ * Returns: The index of the first match in the model, or -1 if no item matches.
+ */
+gint
+nautilus_g_menu_model_find_by_string (GMenuModel  *model,
+                                      const gchar *attribute,
+                                      const gchar *string)
+{
+    gint item_index = -1;
+    gint n_items;
+
+    n_items = g_menu_model_get_n_items (model);
+    for (gint i = 0; i < n_items; i++)
+    {
+        g_autofree gchar *value = NULL;
+        if (g_menu_model_get_item_attribute (model, i, attribute, "s", &value) &&
+            g_strcmp0 (value, string) == 0)
+        {
+            item_index = i;
+            break;
+        }
+    }
+    return item_index;
+}
+
+/**
+ * nautilus_g_menu_replace_string_in_item:
+ * @menu: the #GMenu to modify
+ * @i: the position of the item to change
+ * @attribute: the menu item attribute to change
+ * @string: the string to change the value of @attribute to
+ *
+ * This will replace the item at @position with a new item which is identical
+ * except that it has @attribute set to @string.
+ *
+ * This is useful e.g. when want to change the menu model of a #GtkPopover and
+ * you have a pointer to its menu model but not to the popover itself, so you
+ * can't just set a new model. With this method, the GtkPopover is notified of
+ * changes in its model and updates its contents accordingly.
+ *
+ * It is assumed that @attribute has the a GVariant format string "s".
+ */
+void
+nautilus_g_menu_replace_string_in_item (GMenu       *menu,
+                                        gint         i,
+                                        const gchar *attribute,
+                                        const gchar *string)
+{
+    g_autoptr (GMenuItem) item = NULL;
+
+    item = g_menu_item_new_from_model (G_MENU_MODEL (menu), i);
+    g_menu_item_set_attribute (item, attribute, "s", string);
+    g_menu_remove (menu, i);
+    g_menu_insert_item (menu, i, item);
+}
+
 static GdkPixbuf *filmholes_left = NULL;
 static GdkPixbuf *filmholes_right = NULL;
 
diff --git a/src/nautilus-ui-utilities.h b/src/nautilus-ui-utilities.h
index ed00f5fc7..d59d453e1 100644
--- a/src/nautilus-ui-utilities.h
+++ b/src/nautilus-ui-utilities.h
@@ -27,6 +27,13 @@
 
 void        nautilus_gmenu_set_from_model           (GMenu             *target_menu,
                                                      GMenuModel        *source_model);
+gint        nautilus_g_menu_model_find_by_string    (GMenuModel        *model,
+                                                     const gchar       *attribute,
+                                                     const gchar       *string);
+void        nautilus_g_menu_replace_string_in_item  (GMenu             *menu,
+                                                     gint               i,
+                                                     const gchar       *attribute,
+                                                     const gchar       *string);
 
 void        nautilus_ui_frame_video                 (GdkPixbuf        **pixbuf);
 
diff --git a/src/resources/css/nautilus.css b/src/resources/css/nautilus.css
index ee25a36a8..82dc1d4a2 100644
--- a/src/resources/css/nautilus.css
+++ b/src/resources/css/nautilus.css
@@ -1,9 +1,3 @@
-.nautilus-menu-sort-heading {
-    min-height: 26px;
-    padding-left: 5px;
-    padding-right: 5px;
-}
-
 label.encrypted_zip,
 row.encrypted_zip label.title {
     background-image: -gtk-icontheme('system-lock-screen-symbolic');
diff --git a/src/resources/ui/nautilus-toolbar-view-menu.ui b/src/resources/ui/nautilus-toolbar-view-menu.ui
index 760820f40..265aec606 100644
--- a/src/resources/ui/nautilus-toolbar-view-menu.ui
+++ b/src/resources/ui/nautilus-toolbar-view-menu.ui
@@ -1,263 +1,66 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!-- Generated with glade 3.22.0 -->
 <interface>
-  <requires lib="gtk+" version="3.16"/>
-  <object class="GtkBox" id="extended_section">
-    <property name="width_request">160</property>
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="orientation">vertical</property>
-    <child>
-      <object class="GtkBox" id="sort_menu">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="GtkSeparator">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="margin_top">6</property>
-            <property name="margin_bottom">6</property>
-          </object>
-          <packing>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel">
-            <property name="visible">True</property>
-            <property name="sensitive">False</property>
-            <property name="can_focus">False</property>
-            <property name="label" translatable="yes" context="menu item" comments="Translators: a menu item 
in a group of sorting options in a toolbar menu, with criterions such as &quot;A-Z&quot; or &quot;Last 
Modified&quot;.">Sort</property>
-            <property name="xalign">0</property>
-            <style>
-              <class name="nautilus-menu-sort-heading"/>
-            </style>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="sort_name">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="action_name">view.sort</property>
-            <property name="action_target">'name'</property>
-            <property name="text" translatable="yes" context="Sort Criterion" comments="This is used to sort 
by name in the toolbar view menu">_A-Z</property>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="sort_name_desc">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="action_name">view.sort</property>
-            <property name="action_target">'name-desc'</property>
-            <property name="text" translatable="yes" context="Sort Criterion" comments="This is used to sort 
by name, in descending order in the toolbar view menu">_Z-A</property>
-          </object>
-          <packing>
-            <property name="position">3</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="sort_modification_date_desc">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="action_name">view.sort</property>
-            <property name="action_target">'modification-date-desc'</property>
-            <property name="text" translatable="yes">Last _Modified</property>
-          </object>
-          <packing>
-            <property name="position">4</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="sort_modification_date">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="action_name">view.sort</property>
-            <property name="action_target">'modification-date'</property>
-            <property name="text" translatable="yes">_First Modified</property>
-          </object>
-          <packing>
-            <property name="position">5</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="sort_size">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="action_name">view.sort</property>
-            <property name="action_target">'size'</property>
-            <property name="text" translatable="yes">_Size</property>
-          </object>
-          <packing>
-            <property name="position">6</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="sort_type">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="action_name">view.sort</property>
-            <property name="action_target">'type'</property>
-            <property name="text" translatable="yes">_Type</property>
-          </object>
-          <packing>
-            <property name="position">7</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="sort_trash_time">
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="action_name">view.sort</property>
-            <property name="action_target">'trash-time'</property>
-            <property name="text" translatable="yes">Last _Trashed</property>
-          </object>
-          <packing>
-            <property name="position">8</property>
-          </packing>
-        </child>
-      </object>
-      <packing>
-        <property name="position">0</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkSeparator">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="margin_top">6</property>
-        <property name="margin_bottom">6</property>
-      </object>
-      <packing>
-        <property name="position">1</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkModelButton" id="visible_columns">
-        <property name="can_focus">True</property>
-        <property name="receives_default">False</property>
-        <property name="action_name">view.visible-columns</property>
-        <property name="text" translatable="yes">_Visible Columns…</property>
-      </object>
-      <packing>
-        <property name="position">2</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkModelButton" id="reload">
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="receives_default">False</property>
-        <property name="action_name">win.reload</property>
-        <property name="text" translatable="yes">R_eload</property>
-      </object>
-      <packing>
-        <property name="position">4</property>
-      </packing>
-    </child>
-    <child>
-      <object class="GtkModelButton" id="stop">
-        <property name="can_focus">True</property>
-        <property name="receives_default">False</property>
-        <property name="action_name">win.stop</property>
-        <property name="text" translatable="yes">St_op</property>
-      </object>
-      <packing>
-        <property name="position">5</property>
-      </packing>
-    </child>
-  </object>
-  <object class="GtkBox" id="zoom_section">
-    <property name="width_request">160</property>
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="orientation">vertical</property>
-    <child>
-      <object class="GtkBox" id="zoom_controls_box">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="homogeneous">True</property>
-        <child>
-          <object class="GtkButton" id="zoom-out">
-            <property name="hexpand">True</property>
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="receives_default">False</property>
-            <property name="tooltip_text" translatable="yes">Zoom out</property>
-            <property name="action_name">view.zoom-out</property>
-            <child>
-              <object class="GtkImage">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="icon_name">zoom-out-symbolic</property>
-                <property name="icon_size">1</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="zoom-default">
-            <property name="hexpand">True</property>
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="receives_default">False</property>
-            <property name="tooltip_text" translatable="yes">Reset zoom</property>
-            <property name="action_name">view.zoom-standard</property>
-            <child>
-              <object class="GtkLabel" id="zoom_level_label">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="width_chars">5</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkButton" id="zoom-in">
-            <property name="hexpand">True</property>
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="receives_default">False</property>
-            <property name="tooltip_text" translatable="yes">Zoom in</property>
-            <property name="action_name">view.zoom-in</property>
-            <child>
-              <object class="GtkImage">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="icon_name">zoom-in-symbolic</property>
-                <property name="icon_size">1</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <style>
-          <class name="linked"/>
-        </style>
-      </object>
-      <packing>
-        <property name="position">0</property>
-      </packing>
-    </child>
-  </object>
+  <menu id="zoom_section">
+    <item>
+      <attribute name="label" translatable="yes">Zoom out</attribute>
+      <attribute name="action">view.zoom-out</attribute>
+      <attribute name="verb-icon">zoom-out-symbolic</attribute>
+    </item>
+    <item>
+      <!-- This label is a placeholder. The view is going to replace it with a
+           percentage, like this:   [ - | 100% | + ]                       -->
+      <attribute name="label" translatable="yes">Reset zoom</attribute>
+      <attribute name="action">view.zoom-standard</attribute>
+    </item>
+    <item>
+      <attribute name="label" translatable="yes">Zoom in</attribute>
+      <attribute name="action">view.zoom-in</attribute>
+      <attribute name="verb-icon">zoom-in-symbolic</attribute>
+    </item>
+  </menu>
+  <menu id="sort_section">
+    <item>
+      <attribute name="action">view.sort</attribute>
+      <attribute name="target">name</attribute>
+      <attribute name="label" translatable="yes" context="Sort Criterion" comments="This is used to sort by 
name in the toolbar view menu">_A-Z</attribute>
+      <attribute name="hidden-when">action-disabled</attribute>
+    </item>
+    <item>
+      <attribute name="action">view.sort</attribute>
+      <attribute name="target">name-desc</attribute>
+      <attribute name="label" translatable="yes" context="Sort Criterion" comments="This is used to sort by 
name, in descending order in the toolbar view menu">_Z-A</attribute>
+      <attribute name="hidden-when">action-disabled</attribute>
+    </item>
+    <item>
+      <attribute name="action">view.sort</attribute>
+      <attribute name="target">modification-date-desc</attribute>
+      <attribute name="label" translatable="yes">Last _Modified</attribute>
+      <attribute name="hidden-when">action-disabled</attribute>
+    </item>
+    <item>
+      <attribute name="action">view.sort</attribute>
+      <attribute name="target">modification-date</attribute>
+      <attribute name="label" translatable="yes">_First Modified</attribute>
+      <attribute name="hidden-when">action-disabled</attribute>
+    </item>
+    <item>
+      <attribute name="action">view.sort</attribute>
+      <attribute name="target">size</attribute>
+      <attribute name="label" translatable="yes">_Size</attribute>
+      <attribute name="hidden-when">action-disabled</attribute>
+    </item>
+    <item>
+      <attribute name="action">view.sort</attribute>
+      <attribute name="target">type</attribute>
+      <attribute name="label" translatable="yes">_Type</attribute>
+      <attribute name="hidden-when">action-disabled</attribute>
+    </item>
+    <item>
+      <attribute name="action">view.sort</attribute>
+      <attribute name="target">trash-time</attribute>
+      <attribute name="label" translatable="yes">Last _Trashed</attribute>
+      <attribute name="hidden-when">action-disabled</attribute>
+    </item>
+  </menu>
 </interface>
diff --git a/src/resources/ui/nautilus-toolbar.ui b/src/resources/ui/nautilus-toolbar.ui
index bd39f7b4a..fe95facfd 100644
--- a/src/resources/ui/nautilus-toolbar.ui
+++ b/src/resources/ui/nautilus-toolbar.ui
@@ -10,278 +10,104 @@
     <property name="position">bottom</property>
     <property name="relative-to">forward_button</property>
   </object>
-  <object class="GtkPopoverMenu" id="app_menu">
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkBox">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="margin_start">10</property>
-        <property name="margin_end">10</property>
-        <property name="margin_top">10</property>
-        <property name="margin_bottom">10</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="GtkBox">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="margin_bottom">6</property>
-            <property name="spacing">6</property>
-            <child>
-              <object class="GtkButton">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="tooltip_text" translatable="yes">New Window</property>
-                <property name="hexpand">True</property>
-                <property name="action_name">app.new-window</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">window-new-symbolic</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="tooltip_text" translatable="yes">New Tab</property>
-                <property name="hexpand">True</property>
-                <property name="action_name">win.new-tab</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">tab-new-symbolic</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="tooltip_text" translatable="yes">New Folder</property>
-                <property name="hexpand">True</property>
-                <property name="action_name">view.new-folder</property>
-                <child>
-                  <object class="GtkImage">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">folder-new-symbolic</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkSeparator">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-          </object>
-          <packing>
-            <property name="position">5</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton" id="show_hidden_files">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">False</property>
-            <property name="margin_top">6</property>
-            <property name="action_name">view.show-hidden-files</property>
-            <property name="text" translatable="yes">Show _Hidden Files</property>
-          </object>
-          <packing>
-            <property name="position">6</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="margin_bottom">6</property>
-            <property name="action_name">app.show-hide-sidebar</property>
-            <property name="text" translatable="yes">Show _Sidebar</property>
-          </object>
-          <packing>
-            <property name="position">7</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkSeparator">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-          </object>
-          <packing>
-            <property name="position">8</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="margin_top">6</property>
-            <property name="action_name">app.preferences</property>
-            <property name="text" translatable="yes">_Preferences</property>
-          </object>
-          <packing>
-            <property name="position">9</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="action_name">app.show-help-overlay</property>
-            <property name="text" translatable="yes">_Keyboard Shortcuts</property>
-          </object>
-          <packing>
-            <property name="position">10</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="action_name">app.help</property>
-            <property name="text" translatable="yes">_Help</property>
-          </object>
-          <packing>
-            <property name="position">11</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkModelButton">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="receives_default">True</property>
-            <property name="action_name">app.about</property>
-            <property name="text" translatable="yes">_About Files</property>
-          </object>
-          <packing>
-            <property name="position">12</property>
-          </packing>
-        </child>
-      </object>
-      <packing>
-        <property name="submenu">main</property>
-        <property name="position">1</property>
-      </packing>
-    </child>
-  </object>
-  <object class="GtkPopoverMenu" id="menu_popover">
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkBox">
-        <property name="width_request">160</property>
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="margin-top">9</property>
-        <property name="margin-bottom">9</property>
-        <property name="margin-start">9</property>
-        <property name="margin-end">9</property>
-        <property name="orientation">vertical</property>
-        <child>
-          <object class="GtkBox" id="view_menu_zoom_section">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <placeholder/>
-            </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkBox" id="view_menu_undo_redo_section">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <object class="GtkSeparator">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="margin_top">6</property>
-                <property name="margin_bottom">6</property>
-              </object>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkModelButton" id="undo_button">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="action_name">win.undo</property>
-                <property name="text" translatable="yes">_Undo</property>
-              </object>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkModelButton" id="redo_button">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="action_name">win.redo</property>
-                <property name="text" translatable="yes">_Redo</property>
-              </object>
-              <packing>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkBox" id="view_menu_extended_section">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <placeholder/>
-            </child>
-          </object>
-          <packing>
-            <property name="position">3</property>
-          </packing>
-        </child>
-      </object>
-      <packing>
-        <property name="submenu">main</property>
-        <property name="position">1</property>
-      </packing>
-    </child>
-  </object>
+  <menu id="view_menu">
+    <section>
+      <attribute name="display-hint">horizontal-buttons</attribute>
+      <!--
+           Zoom section.
+
+           The toolbar code assumes this is the first item of this menu model.
+           Its contents is provided by the view.
+      -->
+    </section>
+    <section>
+      <attribute name="label" translatable="yes" context="menu item" comments="Translators: a menu item in a 
group of sorting options in a toolbar menu, with criterions such as &quot;A-Z&quot; or &quot;Last 
Modified&quot;.">Sort</attribute>
+      <!--
+           Sort section.
+
+           The toolbar code assumes this is the second item of this menu model.
+           Its contents is provided by the view.
+      -->
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Visible Columns…</attribute>
+        <attribute name="action">view.visible-columns</attribute>
+        <attribute name="hidden-when">action-missing</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">R_eload</attribute>
+        <attribute name="action">win.reload</attribute>
+        <attribute name="hidden-when">action-disabled</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">St_op</attribute>
+        <attribute name="action">win.stop</attribute>
+        <attribute name="hidden-when">action-disabled</attribute>
+      </item>
+    </section>
+  </menu>
+  <menu id="app_menu">
+    <section>
+      <attribute name="display-hint">horizontal-buttons</attribute>
+      <item>
+        <attribute name="label" translatable="yes">New Window</attribute>
+        <attribute name="action">app.new-window</attribute>
+        <attribute name="verb-icon">window-new-symbolic</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">New Tab</attribute>
+        <attribute name="action">win.new-tab</attribute>
+        <attribute name="verb-icon">tab-new-symbolic</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">New Folder</attribute>
+        <attribute name="action">view.new-folder</attribute>
+        <attribute name="verb-icon">folder-new-symbolic</attribute>
+      </item>
+    </section>
+    <section id="undo_redo_section">
+      <!-- Note: This section is often recreated by undo_manager_changed() to
+           change the labels of the actions. If you change anything here,
+           remember to change in the code as well. -->
+      <item>
+        <attribute name="label" translatable="yes">_Undo</attribute>
+        <attribute name="action">win.undo</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Redo</attribute>
+        <attribute name="action">win.undo</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">Show _Hidden Files</attribute>
+        <attribute name="action">view.show-hidden-files</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">Show _Sidebar</attribute>
+        <attribute name="action">app.show-hide-sidebar</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Preferences</attribute>
+        <attribute name="action">app.preferences</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
+        <attribute name="action">app.show-help-overlay</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_Help</attribute>
+        <attribute name="action">app.help</attribute>
+      </item>
+      <item>
+        <attribute name="label" translatable="yes">_About Files</attribute>
+        <attribute name="action">app.about</attribute>
+      </item>
+    </section>
+  </menu>
   <object class="GtkPopover" id="operations_popover">
     <property name="can_focus">False</property>
     <child>
@@ -525,7 +351,7 @@
                 <property name="tooltip_text" translatable="yes" comments="“View” is a noun">View 
options</property>
                 <property name="halign">start</property>
                 <property name="action_name">win.view-menu</property>
-                <property name="popover">menu_popover</property>
+                <property name="menu-model">view_menu</property>
                 <child>
                   <object class="GtkImage">
                     <property name="visible">True</property>
@@ -556,7 +382,7 @@
             <property name="receives_default">False</property>
             <property name="halign">center</property>
             <property name="valign">center</property>
-            <property name="popover">app_menu</property>
+            <property name="menu-model">app_menu</property>
             <child>
               <object class="GtkImage">
                 <property name="visible">True</property>


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