From 6b17559b8807cfb4a86fdb86a94d9ae58d3627cf Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 27 2022 13:56:38 +0000 Subject: import nautilus-3.28.1-20.el8 --- diff --git a/SOURCES/Add-actions-to-the-toolbar.patch b/SOURCES/Add-actions-to-the-toolbar.patch new file mode 100644 index 0000000..a3cfb98 --- /dev/null +++ b/SOURCES/Add-actions-to-the-toolbar.patch @@ -0,0 +1,1196 @@ +diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c +index 0c7380ae9..08107a64e 100644 +--- a/src/nautilus-files-view.c ++++ b/src/nautilus-files-view.c +@@ -146,6 +146,8 @@ enum + PROP_IS_LOADING, + PROP_LOCATION, + PROP_SEARCH_QUERY, ++ PROP_EXTENSIONS_BACKGROUND_MENU, ++ PROP_TEMPLATES_MENU, + NUM_PROPERTIES + }; + +@@ -264,6 +266,10 @@ typedef struct + GtkWidget *zoom_controls_box; + GtkWidget *zoom_level_label; + ++ /* Exposed menus, for the path bar etc. */ ++ GMenu *extensions_background_menu; ++ GMenu *templates_menu; ++ + gulong stop_signal_handler; + gulong reload_signal_handler; + +@@ -691,6 +697,98 @@ nautilus_files_view_get_toolbar_menu_sections (NautilusView *view) + return priv->toolbar_menu_sections; + } + ++static GMenu* ++nautilus_files_view_get_templates_menu (NautilusView *self) ++{ ++ GMenu *menu; ++ ++ g_object_get (self, "templates-menu", &menu, NULL); ++ ++ return menu; ++} ++ ++static GMenu* ++nautilus_files_view_get_extensions_background_menu (NautilusView *self) ++{ ++ GMenu *menu; ++ ++ g_object_get (self, "extensions-background-menu", &menu, NULL); ++ ++ return menu; ++} ++ ++static GMenu* ++real_get_extensions_background_menu (NautilusView *view) ++{ ++ NautilusFilesViewPrivate *priv; ++ ++ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL); ++ ++ priv = nautilus_files_view_get_instance_private (NAUTILUS_FILES_VIEW (view)); ++ ++ return priv->extensions_background_menu; ++} ++ ++static GMenu* ++real_get_templates_menu (NautilusView *view) ++{ ++ NautilusFilesViewPrivate *priv; ++ ++ g_return_val_if_fail (NAUTILUS_IS_FILES_VIEW (view), NULL); ++ ++ priv = nautilus_files_view_get_instance_private (NAUTILUS_FILES_VIEW (view)); ++ ++ return priv->templates_menu; ++} ++ ++static void ++nautilus_files_view_set_templates_menu (NautilusView *self, ++ GMenu *menu) ++{ ++ g_object_set (self, "templates-menu", menu, NULL); ++} ++ ++static void ++nautilus_files_view_set_extensions_background_menu (NautilusView *self, ++ GMenu *menu) ++{ ++ g_object_set (self, "extensions-background-menu", menu, NULL); ++} ++ ++static void ++real_set_extensions_background_menu (NautilusView *view, ++ GMenu *menu) ++{ ++ NautilusFilesViewPrivate *priv; ++ ++ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view)); ++ ++ priv = nautilus_files_view_get_instance_private (NAUTILUS_FILES_VIEW (view)); ++ ++ if (priv->extensions_background_menu != NULL) ++ { ++ g_clear_object (&priv->extensions_background_menu); ++ } ++ priv->extensions_background_menu = menu; ++} ++ ++static void ++real_set_templates_menu (NautilusView *view, ++ GMenu *menu) ++{ ++ NautilusFilesViewPrivate *priv; ++ ++ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (view)); ++ ++ priv = nautilus_files_view_get_instance_private (NAUTILUS_FILES_VIEW (view)); ++ ++ if (priv->templates_menu != NULL) ++ { ++ g_clear_object (&priv->templates_menu); ++ } ++ priv->templates_menu = menu; ++} ++ + static gboolean + showing_trash_directory (NautilusFilesView *view) + { +@@ -2446,6 +2544,30 @@ action_properties (GSimpleAction *action, + } + } + ++static void ++action_current_dir_properties (GSimpleAction *action, ++ GVariant *state, ++ gpointer user_data) ++{ ++ NautilusFilesView *view; ++ NautilusFilesViewPrivate *priv; ++ GList *files; ++ ++ g_return_if_fail (NAUTILUS_IS_FILES_VIEW (user_data)); ++ ++ view = NAUTILUS_FILES_VIEW (user_data); ++ priv = nautilus_files_view_get_instance_private (view); ++ ++ if (priv->directory_as_file != NULL) ++ { ++ files = g_list_append (NULL, nautilus_file_ref (priv->directory_as_file)); ++ ++ nautilus_properties_window_present (files, GTK_WIDGET (view), NULL, NULL, NULL); ++ ++ nautilus_file_list_free (files); ++ } ++} ++ + static void + nautilus_files_view_set_show_hidden_files (NautilusFilesView *view, + gboolean show_hidden) +@@ -3192,6 +3314,8 @@ nautilus_files_view_finalize (GObject *object) + g_clear_object (&priv->selection_menu); + g_clear_object (&priv->toolbar_menu_sections->zoom_section); + g_clear_object (&priv->toolbar_menu_sections->extended_section); ++ g_clear_object (&priv->extensions_background_menu); ++ g_clear_object (&priv->templates_menu); + g_clear_object (&priv->rename_file_controller); + g_clear_object (&priv->new_folder_controller); + g_clear_object (&priv->compress_controller); +@@ -4899,49 +5023,42 @@ build_menu_for_extension_menu_items (NautilusFilesView *view, + return gmenu; + } + +-static void +-add_extension_menu_items (NautilusFilesView *view, +- const gchar *extension_prefix, +- GList *menu_items, +- GMenu *insertion_menu) +-{ +- GMenu *menu; +- +- menu = build_menu_for_extension_menu_items (view, extension_prefix, menu_items); +- nautilus_gmenu_merge (insertion_menu, +- menu, +- "extensions", +- FALSE); +- +- g_object_unref (menu); +-} +- + static void + update_extensions_menus (NautilusFilesView *view) + { + NautilusFilesViewPrivate *priv; + GList *selection_items, *background_items; ++ g_autoptr (GMenu) background_menu = NULL; ++ g_autoptr (GMenu) selection_menu = NULL; + + priv = nautilus_files_view_get_instance_private (view); + selection_items = get_extension_selection_menu_items (view); + if (selection_items != NULL) + { +- add_extension_menu_items (view, +- "selection", +- selection_items, +- priv->selection_menu); ++ selection_menu = build_menu_for_extension_menu_items (view, "extensions", ++ selection_items); ++ ++ nautilus_gmenu_merge (priv->selection_menu, ++ selection_menu, ++ "extensions", ++ FALSE); + nautilus_menu_item_list_free (selection_items); + } + + background_items = get_extension_background_menu_items (view); + if (background_items != NULL) + { +- add_extension_menu_items (view, +- "background", +- background_items, +- priv->background_menu); ++ background_menu = build_menu_for_extension_menu_items (view, "extensions", ++ background_items); ++ ++ nautilus_gmenu_merge (priv->background_menu, ++ background_menu, ++ "extensions", ++ FALSE); + nautilus_menu_item_list_free (background_items); + } ++ ++ nautilus_view_set_extensions_background_menu (NAUTILUS_VIEW (view), background_menu); + } + + static char * +@@ -5646,7 +5763,7 @@ update_templates_menu (NautilusFilesView *view) + NautilusFilesViewPrivate *priv; + GList *sorted_copy, *node; + NautilusDirectory *directory; +- GMenu *submenu; ++ g_autoptr (GMenu) submenu = NULL; + char *uri; + char *templates_directory_uri; + +@@ -5687,9 +5804,10 @@ update_templates_menu (NautilusFilesView *view) + submenu, + "templates-submenu", + FALSE); +- g_object_unref (submenu); + } + ++ nautilus_view_set_templates_menu (NAUTILUS_VIEW (view), submenu); ++ + nautilus_directory_unref (directory); + + priv->templates_present = submenu != NULL; +@@ -6880,6 +6998,7 @@ const GActionEntry view_entries[] = + { "extract-to", action_extract_to }, + { "compress", action_compress }, + { "properties", action_properties}, ++ { "current-directory-properties", action_current_dir_properties}, + { "set-as-wallpaper", action_set_as_wallpaper }, + { "mount-volume", action_mount_volume }, + { "unmount-volume", action_unmount_volume }, +@@ -8871,8 +8990,25 @@ nautilus_files_view_get_property (GObject *object, + } + break; + ++ case PROP_EXTENSIONS_BACKGROUND_MENU: ++ { ++ g_value_set_object (value, ++ real_get_extensions_background_menu (NAUTILUS_VIEW (view))); ++ } ++ break; ++ ++ case PROP_TEMPLATES_MENU: ++ { ++ g_value_set_object (value, ++ real_get_templates_menu (NAUTILUS_VIEW (view))); ++ } ++ break; ++ + default: ++ { + g_assert_not_reached (); ++ } ++ break; + } + } + +@@ -8925,6 +9061,20 @@ nautilus_files_view_set_property (GObject *object, + } + break; + ++ case PROP_EXTENSIONS_BACKGROUND_MENU: ++ { ++ real_set_extensions_background_menu (NAUTILUS_VIEW (directory_view), ++ g_value_get_object (value)); ++ } ++ break; ++ ++ case PROP_TEMPLATES_MENU: ++ { ++ real_set_templates_menu (NAUTILUS_VIEW (directory_view), ++ g_value_get_object (value)); ++ } ++ break; ++ + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +@@ -9286,6 +9436,10 @@ nautilus_files_view_iface_init (NautilusViewInterface *iface) + iface->is_searching = nautilus_files_view_is_searching; + iface->is_loading = nautilus_files_view_is_loading; + iface->get_view_id = nautilus_files_view_get_view_id; ++ iface->get_templates_menu = nautilus_files_view_get_templates_menu; ++ iface->set_templates_menu = nautilus_files_view_set_templates_menu; ++ iface->get_extensions_background_menu = nautilus_files_view_get_extensions_background_menu; ++ iface->set_extensions_background_menu = nautilus_files_view_set_extensions_background_menu; + } + + static void +@@ -9410,6 +9564,8 @@ nautilus_files_view_class_init (NautilusFilesViewClass *klass) + g_object_class_override_property (oclass, PROP_IS_SEARCH, "is-searching"); + g_object_class_override_property (oclass, PROP_LOCATION, "location"); + g_object_class_override_property (oclass, PROP_SEARCH_QUERY, "search-query"); ++ g_object_class_override_property (oclass, PROP_EXTENSIONS_BACKGROUND_MENU, "extensions-background-menu"); ++ g_object_class_override_property (oclass, PROP_TEMPLATES_MENU, "templates-menu"); + } + + static void +diff --git a/src/nautilus-pathbar.c b/src/nautilus-pathbar.c +index 630b8ed33..3681ce2d8 100644 +--- a/src/nautilus-pathbar.c ++++ b/src/nautilus-pathbar.c +@@ -73,6 +73,7 @@ typedef struct + GtkWidget *image; + GtkWidget *label; + GtkWidget *bold_label; ++ GtkWidget *disclosure_arrow; + + guint ignore_changes : 1; + guint is_root : 1; +@@ -100,9 +101,13 @@ typedef struct + + GActionGroup *action_group; + +- GMenu *context_menu; + NautilusFile *context_menu_file; +- GdkEvent *context_menu_event; ++ GtkPopover *current_view_menu_popover; ++ GtkPopover *button_menu_popover; ++ GMenu *current_view_menu; ++ GMenu *button_menu; ++ GMenu *extensions_background_menu; ++ GMenu *templates_menu; + } NautilusPathBarPrivate; + + +@@ -120,8 +125,9 @@ static gboolean nautilus_path_bar_slider_button_release (GtkWidget *widget + NautilusPathBar *self); + static void nautilus_path_bar_check_icon_theme (NautilusPathBar *self); + static void nautilus_path_bar_update_button_appearance (ButtonData *button_data); +-static void nautilus_path_bar_update_button_state (ButtonData *button_data, +- gboolean current_dir); ++static void nautilus_path_bar_update_button_state (NautilusPathBar *self, ++ ButtonData *button_data, ++ gboolean current_dir); + static void nautilus_path_bar_update_path (NautilusPathBar *self, + GFile *file_path); + static void unschedule_pop_up_context_menu (NautilusPathBar *self); +@@ -134,6 +140,8 @@ static void action_pathbar_open_item_new_tab (GSimpleAction *action, + static void action_pathbar_properties (GSimpleAction *action, + GVariant *state, + gpointer user_data); ++static void pop_up_pathbar_context_menu (NautilusPathBar *self, ++ NautilusFile *file); + + const GActionEntry path_bar_actions[] = + { +@@ -333,7 +341,12 @@ nautilus_path_bar_init (NautilusPathBar *self) + + /* Context menu */ + builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-pathbar-context-menu.ui"); +- priv->context_menu = g_object_ref (G_MENU (gtk_builder_get_object (builder, "pathbar-menu"))); ++ priv->current_view_menu = g_object_ref_sink (G_MENU (gtk_builder_get_object (builder, "current-view-menu"))); ++ priv->button_menu = g_object_ref_sink (G_MENU (gtk_builder_get_object (builder, "button-menu"))); ++ priv->current_view_menu_popover = g_object_ref_sink (GTK_POPOVER (gtk_popover_new_from_model (NULL, ++ G_MENU_MODEL (priv->current_view_menu)))); ++ priv->button_menu_popover = g_object_ref_sink (GTK_POPOVER (gtk_popover_new_from_model (NULL, ++ G_MENU_MODEL (priv->button_menu)))); + g_object_unref (builder); + + gtk_widget_set_has_window (GTK_WIDGET (self), FALSE); +@@ -402,12 +415,12 @@ nautilus_path_bar_finalize (GObject *object) + } + + g_list_free (priv->button_list); ++ g_clear_object (&priv->current_view_menu); ++ g_clear_object (&priv->button_menu); ++ g_clear_object (&priv->button_menu_popover); ++ g_clear_object (&priv->current_view_menu_popover); + + unschedule_pop_up_context_menu (NAUTILUS_PATH_BAR (object)); +- if (priv->context_menu_event) +- { +- gdk_event_free ((GdkEvent *) priv->context_menu_event); +- } + + G_OBJECT_CLASS (nautilus_path_bar_parent_class)->finalize (object); + } +@@ -1293,6 +1306,81 @@ nautilus_path_bar_class_init (NautilusPathBarClass *path_bar_class) + gtk_container_class_handle_border_width (container_class); + } + ++static void ++update_current_view_menu (NautilusPathBar *self) ++{ ++ NautilusPathBarPrivate *priv; ++ ++ priv = nautilus_path_bar_get_instance_private (self); ++ if (priv->extensions_background_menu != NULL) ++ { ++ nautilus_gmenu_merge (priv->current_view_menu, ++ priv->extensions_background_menu, ++ "extensions", ++ TRUE); ++ } ++ ++ if (priv->templates_menu != NULL) ++ { ++ nautilus_gmenu_merge (priv->current_view_menu, priv->templates_menu, ++ "templates-submenu", TRUE); ++ } ++} ++ ++static void ++reset_current_view_menu (NautilusPathBar *self) ++{ ++ NautilusPathBarPrivate *priv; ++ g_autoptr (GtkBuilder) builder = NULL; ++ ++ priv = nautilus_path_bar_get_instance_private (self); ++ ++ g_clear_object (&priv->current_view_menu); ++ builder = gtk_builder_new_from_resource ("/org/gnome/nautilus/ui/nautilus-pathbar-context-menu.ui"); ++ priv->current_view_menu = g_object_ref_sink (G_MENU (gtk_builder_get_object (builder, ++ "current-view-menu"))); ++ gtk_popover_bind_model (priv->current_view_menu_popover, ++ G_MENU_MODEL (priv->current_view_menu), NULL); ++} ++ ++void ++nautilus_path_bar_set_extensions_background_menu (NautilusPathBar *self, ++ GMenu *menu) ++{ ++ NautilusPathBarPrivate *priv; ++ ++ g_return_if_fail (NAUTILUS_IS_PATH_BAR (self)); ++ ++ priv = nautilus_path_bar_get_instance_private (self); ++ reset_current_view_menu (self); ++ g_clear_object (&priv->extensions_background_menu); ++ if (menu != NULL) ++ { ++ priv->extensions_background_menu = g_object_ref (menu); ++ } ++ ++ update_current_view_menu (self); ++} ++ ++void ++nautilus_path_bar_set_templates_menu (NautilusPathBar *self, ++ GMenu *menu) ++{ ++ NautilusPathBarPrivate *priv; ++ ++ g_return_if_fail (NAUTILUS_IS_PATH_BAR (self)); ++ ++ priv = nautilus_path_bar_get_instance_private (self); ++ reset_current_view_menu (self); ++ g_clear_object (&priv->templates_menu); ++ if (menu != NULL) ++ { ++ priv->templates_menu = g_object_ref (menu); ++ } ++ ++ update_current_view_menu (self); ++} ++ + static void + nautilus_path_bar_scroll_down (NautilusPathBar *self) + { +@@ -1599,7 +1687,9 @@ button_clicked_cb (GtkWidget *button, + ButtonData *button_data; + NautilusPathBarPrivate *priv; + NautilusPathBar *self; +- GList *button_list; ++ GdkEvent *event; ++ GdkModifierType state; ++ gboolean current_dir; + + button_data = BUTTON_DATA (data); + if (button_data->ignore_changes) +@@ -1609,13 +1699,29 @@ button_clicked_cb (GtkWidget *button, + + self = NAUTILUS_PATH_BAR (gtk_widget_get_parent (button)); + priv = nautilus_path_bar_get_instance_private (self); ++ event = gtk_get_current_event (); ++ current_dir = g_file_equal (button_data->path, priv->current_path); + +- button_list = g_list_find (priv->button_list, button_data); +- g_assert (button_list != NULL); ++ gdk_event_get_state (event, &state); + +- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); ++ button_data->ignore_changes = TRUE; ++ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), current_dir); ++ button_data->ignore_changes = FALSE; + +- g_signal_emit (self, path_bar_signals [PATH_CLICKED], 0, button_data->path); ++ if ((state & GDK_CONTROL_MASK) != 0) ++ { ++ g_signal_emit (self, path_bar_signals[OPEN_LOCATION], 0, ++ button_data->path, ++ GTK_PLACES_OPEN_NEW_WINDOW); ++ } ++ else if (current_dir) ++ { ++ gtk_popover_popup (priv->current_view_menu_popover); ++ } ++ else ++ { ++ g_signal_emit (self, path_bar_signals [PATH_CLICKED], 0, button_data->path); ++ } + } + + +@@ -1626,9 +1732,7 @@ real_pop_up_pathbar_context_menu (NautilusPathBar *self) + + priv = nautilus_path_bar_get_instance_private (self); + +- nautilus_pop_up_context_menu_at_pointer (GTK_WIDGET (self), +- priv->context_menu, +- priv->context_menu_event); ++ gtk_popover_popup (priv->button_menu_popover); + } + + static void +@@ -1668,7 +1772,6 @@ unschedule_pop_up_context_menu (NautilusPathBar *self) + + static void + schedule_pop_up_context_menu (NautilusPathBar *self, +- GdkEventButton *event, + NautilusFile *file) + { + NautilusPathBarPrivate *priv; +@@ -1677,12 +1780,6 @@ schedule_pop_up_context_menu (NautilusPathBar *self, + + priv = nautilus_path_bar_get_instance_private (self); + +- if (priv->context_menu_event != NULL) +- { +- gdk_event_free ((GdkEvent *) priv->context_menu_event); +- } +- priv->context_menu_event = gdk_event_copy ((GdkEvent *) event); +- + if (file == priv->context_menu_file) + { + if (nautilus_file_check_if_ready (file, +@@ -1709,12 +1806,11 @@ schedule_pop_up_context_menu (NautilusPathBar *self, + + static void + pop_up_pathbar_context_menu (NautilusPathBar *self, +- GdkEventButton *event, + NautilusFile *file) + { + if (file) + { +- schedule_pop_up_context_menu (self, event, file); ++ schedule_pop_up_context_menu (self, file); + } + } + +@@ -1723,22 +1819,31 @@ button_event_cb (GtkWidget *button, + GdkEventButton *event, + gpointer data) + { +- GtkPlacesOpenFlags flags; + ButtonData *button_data; + NautilusPathBar *self; ++ NautilusPathBarPrivate *priv; + int mask; ++ gboolean current_dir; + + button_data = BUTTON_DATA (data); + self = NAUTILUS_PATH_BAR (gtk_widget_get_parent (button)); ++ priv = nautilus_path_bar_get_instance_private (self); + mask = event->state & gtk_accelerator_get_default_mod_mask (); + + if (event->type == GDK_BUTTON_PRESS) + { +- g_object_set_data (G_OBJECT (button), "handle-button-release", GINT_TO_POINTER (TRUE)); +- + if (event->button == GDK_BUTTON_SECONDARY) + { +- pop_up_pathbar_context_menu (self, event, button_data->file); ++ current_dir = g_file_equal (button_data->path, priv->current_path); ++ if (current_dir) ++ { ++ gtk_popover_popup (priv->current_view_menu_popover); ++ } ++ else ++ { ++ gtk_popover_set_relative_to (priv->button_menu_popover, button); ++ pop_up_pathbar_context_menu (self, button_data->file); ++ } + return GDK_EVENT_STOP; + } + else if (event->button == GDK_BUTTON_MIDDLE && mask == 0) +@@ -1751,27 +1856,6 @@ button_event_cb (GtkWidget *button, + return GDK_EVENT_STOP; + } + } +- else if (event->type == GDK_BUTTON_RELEASE) +- { +- flags = 0; +- +- if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button), "handle-button-release"))) +- { +- return GDK_EVENT_PROPAGATE; +- } +- +- if (event->button == GDK_BUTTON_PRIMARY && mask == GDK_CONTROL_MASK) +- { +- flags = GTK_PLACES_OPEN_NEW_WINDOW; +- } +- +- if (flags != 0) +- { +- g_signal_emit (self, path_bar_signals[OPEN_LOCATION], 0, button_data->path, flags); +- } +- +- return GDK_EVENT_PROPAGATE; +- } + + return GDK_EVENT_PROPAGATE; + } +@@ -1880,9 +1964,14 @@ nautilus_path_bar_update_button_appearance (ButtonData *button_data) + } + + static void +-nautilus_path_bar_update_button_state (ButtonData *button_data, +- gboolean current_dir) ++nautilus_path_bar_update_button_state (NautilusPathBar *self, ++ ButtonData *button_data, ++ gboolean current_dir) + { ++ NautilusPathBarPrivate *priv; ++ ++ priv = nautilus_path_bar_get_instance_private (self); ++ + if (button_data->label != NULL) + { + gtk_label_set_label (GTK_LABEL (button_data->label), NULL); +@@ -1898,6 +1987,12 @@ nautilus_path_bar_update_button_state (ButtonData *button_data, + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button_data->button), current_dir); + button_data->ignore_changes = FALSE; + } ++ ++ gtk_widget_set_visible (button_data->disclosure_arrow, current_dir); ++ if (current_dir) ++ { ++ gtk_popover_set_relative_to (priv->current_view_menu_popover, button_data->button); ++ } + } + + static void +@@ -2096,13 +2191,17 @@ make_button_data (NautilusPathBar *self, + /* TODO update button type when xdg directories change */ + + button_data->image = gtk_image_new (); ++ button_data->disclosure_arrow = gtk_image_new_from_icon_name ("pan-down-symbolic", ++ GTK_ICON_SIZE_MENU); + + switch (button_data->type) + { + case ROOT_BUTTON: + { +- child = button_data->image; + button_data->label = NULL; ++ child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); ++ gtk_box_pack_start (GTK_BOX (child), button_data->image, FALSE, FALSE, 0); ++ gtk_box_pack_start (GTK_BOX (child), button_data->disclosure_arrow, FALSE, FALSE, 0); + } + break; + +@@ -2115,10 +2214,13 @@ make_button_data (NautilusPathBar *self, + child = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2); + gtk_box_pack_start (GTK_BOX (child), button_data->image, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (child), button_data->label, FALSE, FALSE, 0); ++ gtk_box_pack_start (GTK_BOX (child), button_data->disclosure_arrow, FALSE, FALSE, 0); + } + break; + } + ++ gtk_widget_set_no_show_all (button_data->disclosure_arrow, TRUE); ++ + if (button_data->label != NULL) + { + gtk_label_set_ellipsize (GTK_LABEL (button_data->label), PANGO_ELLIPSIZE_MIDDLE); +@@ -2152,11 +2254,10 @@ make_button_data (NautilusPathBar *self, + gtk_container_add (GTK_CONTAINER (button_data->button), child); + gtk_widget_show_all (button_data->button); + +- nautilus_path_bar_update_button_state (button_data, current_dir); ++ nautilus_path_bar_update_button_state (self, button_data, current_dir); + + g_signal_connect (button_data->button, "clicked", G_CALLBACK (button_clicked_cb), button_data); + g_signal_connect (button_data->button, "button-press-event", G_CALLBACK (button_event_cb), button_data); +- g_signal_connect (button_data->button, "button-release-event", G_CALLBACK (button_event_cb), button_data); + g_object_weak_ref (G_OBJECT (button_data->button), (GWeakNotify) button_data_free, button_data); + + nautilus_drag_slot_proxy_init (button_data->button, button_data->file, NULL); +@@ -2198,7 +2299,7 @@ nautilus_path_bar_check_parent_path (NautilusPathBar *self, + is_active = FALSE; + } + +- nautilus_path_bar_update_button_state (button_data, is_active); ++ nautilus_path_bar_update_button_state (self, button_data, is_active); + } + + if (current_button_data != NULL) +diff --git a/src/nautilus-pathbar.h b/src/nautilus-pathbar.h +index 8651b7bc2..cbe427cf7 100644 +--- a/src/nautilus-pathbar.h ++++ b/src/nautilus-pathbar.h +@@ -36,5 +36,9 @@ struct _NautilusPathBarClass + GtkPlacesOpenFlags flags); + }; + void nautilus_path_bar_set_path (NautilusPathBar *self, GFile *file); ++void nautilus_path_bar_set_extensions_background_menu (NautilusPathBar *self, ++ GMenu *menu); ++void nautilus_path_bar_set_templates_menu (NautilusPathBar *self, ++ GMenu *menu); + + #endif /* NAUTILUS_PATHBAR_H */ +diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c +index 26a978e7d..18e0421de 100644 +--- a/src/nautilus-toolbar.c ++++ b/src/nautilus-toolbar.c +@@ -1199,6 +1199,24 @@ nautilus_toolbar_set_show_location_entry (NautilusToolbar *self, + } + } + ++static void ++slot_on_extensions_background_menu_changed (NautilusToolbar *self, ++ GParamSpec *param, ++ NautilusWindowSlot *slot) ++{ ++ nautilus_path_bar_set_extensions_background_menu (NAUTILUS_PATH_BAR (self->path_bar), ++ nautilus_window_slot_get_extensions_background_menu (slot)); ++} ++ ++static void ++slot_on_templates_menu_changed (NautilusToolbar *self, ++ GParamSpec *param, ++ NautilusWindowSlot *slot) ++{ ++ nautilus_path_bar_set_templates_menu (NAUTILUS_PATH_BAR (self->path_bar), ++ nautilus_window_slot_get_templates_menu (slot)); ++} ++ + static gboolean + nautilus_toolbar_view_toggle_icon_transform_to (GBinding *binding, + const GValue *from_value, +@@ -1304,6 +1322,10 @@ nautilus_toolbar_set_active_slot (NautilusToolbar *toolbar, + on_slot_toolbar_menu_sections_changed (toolbar, NULL, slot); + g_signal_connect_swapped (slot, "notify::toolbar-menu-sections", + G_CALLBACK (on_slot_toolbar_menu_sections_changed), toolbar); ++ g_signal_connect_swapped (slot, "notify::extensions-background-menu", ++ G_CALLBACK (slot_on_extensions_background_menu_changed), toolbar); ++ g_signal_connect_swapped (slot, "notify::templates-menu", ++ G_CALLBACK (slot_on_templates_menu_changed), toolbar); + } + } + } +diff --git a/src/nautilus-view.c b/src/nautilus-view.c +index 7b3a3c973..a1c32f248 100644 +--- a/src/nautilus-view.c ++++ b/src/nautilus-view.c +@@ -72,6 +72,29 @@ nautilus_view_default_init (NautilusViewInterface *iface) + "The search query being performed on the view", + NAUTILUS_TYPE_QUERY, + G_PARAM_READWRITE)); ++ ++ /** ++ * NautilusView::extensions-background-menu: ++ * ++ * Menu for the background click of extensions ++ */ ++ g_object_interface_install_property (iface, ++ g_param_spec_object ("extensions-background-menu", ++ "Menu for the background click of extensions", ++ "Menu for the background click of extensions", ++ G_TYPE_MENU, ++ G_PARAM_READWRITE)); ++ /** ++ * NautilusView::templates-menu: ++ * ++ * Menu of templates ++ */ ++ g_object_interface_install_property (iface, ++ g_param_spec_object ("templates-menu", ++ "Menu of templates", ++ "Menu of templates", ++ G_TYPE_MENU, ++ G_PARAM_READWRITE)); + } + + /** +@@ -137,6 +160,42 @@ nautilus_view_get_toolbar_menu_sections (NautilusView *view) + return NAUTILUS_VIEW_GET_IFACE (view)->get_toolbar_menu_sections (view); + } + ++GMenu * ++nautilus_view_get_extensions_background_menu (NautilusView *view) ++{ ++ g_return_val_if_fail (NAUTILUS_VIEW_GET_IFACE (view)->get_extensions_background_menu, NULL); ++ ++ return NAUTILUS_VIEW_GET_IFACE (view)->get_extensions_background_menu (view); ++} ++ ++/* Protected */ ++void ++nautilus_view_set_extensions_background_menu (NautilusView *view, ++ GMenu *menu) ++{ ++ g_return_if_fail (NAUTILUS_VIEW_GET_IFACE (view)->set_extensions_background_menu); ++ ++ NAUTILUS_VIEW_GET_IFACE (view)->set_extensions_background_menu (view, menu); ++} ++ ++GMenu * ++nautilus_view_get_templates_menu (NautilusView *view) ++{ ++ g_return_val_if_fail (NAUTILUS_VIEW_GET_IFACE (view)->get_templates_menu, NULL); ++ ++ return NAUTILUS_VIEW_GET_IFACE (view)->get_templates_menu (view); ++} ++ ++/* Protected */ ++void ++nautilus_view_set_templates_menu (NautilusView *view, ++ GMenu *menu) ++{ ++ g_return_if_fail (NAUTILUS_VIEW_GET_IFACE (view)->set_templates_menu); ++ ++ NAUTILUS_VIEW_GET_IFACE (view)->set_templates_menu (view, menu); ++} ++ + /** + * nautilus_view_get_search_query: + * @view: a #NautilusView +diff --git a/src/nautilus-view.h b/src/nautilus-view.h +index dcd39e0ad..c3042bebd 100644 +--- a/src/nautilus-view.h ++++ b/src/nautilus-view.h +@@ -52,6 +52,20 @@ struct _NautilusViewInterface + */ + NautilusToolbarMenuSections * (*get_toolbar_menu_sections) (NautilusView *view); + ++ /* ++ * Returns the menu for the background click of extensions. ++ */ ++ GMenu * (*get_extensions_background_menu) (NautilusView *view); ++ ++ void (*set_extensions_background_menu) (NautilusView *view, ++ GMenu *menu); ++ /* ++ * Returns the menu for templates. ++ */ ++ GMenu * (*get_templates_menu) (NautilusView *view); ++ ++ void (*set_templates_menu) (NautilusView *view, ++ GMenu *menu); + /* Current location of the view */ + GFile* (*get_location) (NautilusView *view); + void (*set_location) (NautilusView *view, +@@ -99,6 +113,13 @@ gboolean nautilus_view_is_loading (Nautilus + + gboolean nautilus_view_is_searching (NautilusView *view); + ++void nautilus_view_set_templates_menu (NautilusView *view, ++ GMenu *menu); ++GMenu* nautilus_view_get_templates_menu (NautilusView *view); ++void nautilus_view_set_extensions_background_menu (NautilusView *view, ++ GMenu *menu); ++GMenu* nautilus_view_get_extensions_background_menu (NautilusView *view); ++ + G_END_DECLS + + #endif /* NAUTILUS_VIEW_H */ +diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c +index c3260aeb0..ea2197849 100644 +--- a/src/nautilus-window-slot.c ++++ b/src/nautilus-window-slot.c +@@ -60,6 +60,8 @@ enum + PROP_WINDOW, + PROP_ICON, + PROP_TOOLBAR_MENU_SECTIONS, ++ PROP_EXTENSIONS_BACKGROUND_MENU, ++ PROP_TEMPLATES_MENU, + PROP_LOADING, + PROP_LOCATION, + NUM_PROPERTIES +@@ -124,6 +126,14 @@ typedef struct + GError *mount_error; + gboolean tried_mount; + gint view_mode_before_search; ++ ++ /* Menus */ ++ GMenu *extensions_background_menu; ++ GMenu *templates_menu; ++ ++ /* View bindings */ ++ GBinding *extensions_background_menu_binding; ++ GBinding *templates_menu_binding; + } NautilusWindowSlotPrivate; + + G_DEFINE_TYPE_WITH_PRIVATE (NautilusWindowSlot, nautilus_window_slot, GTK_TYPE_BOX); +@@ -154,6 +164,12 @@ static void nautilus_window_slot_set_location (NautilusWindowSlot *self, + static void trash_state_changed_cb (NautilusTrashMonitor *monitor, + gboolean is_empty, + gpointer user_data); ++static void real_set_extensions_background_menu (NautilusWindowSlot *self, ++ GMenu *menu); ++static GMenu* real_get_extensions_background_menu (NautilusWindowSlot *self); ++static void real_set_templates_menu (NautilusWindowSlot *self, ++ GMenu *menu); ++static GMenu* real_get_templates_menu (NautilusWindowSlot *self); + + void + free_navigation_state (gpointer data) +@@ -727,6 +743,26 @@ nautilus_window_slot_add_extra_location_widget (NautilusWindowSlot *self, + gtk_widget_show (priv->extra_location_widgets); + } + ++static void ++real_set_extensions_background_menu (NautilusWindowSlot *self, ++ GMenu *menu) ++{ ++ NautilusWindowSlotPrivate *priv; ++ priv = nautilus_window_slot_get_instance_private (self); ++ ++ priv->extensions_background_menu = menu != NULL ? g_object_ref (menu) : NULL; ++} ++ ++static void ++real_set_templates_menu (NautilusWindowSlot *self, ++ GMenu *menu) ++{ ++ NautilusWindowSlotPrivate *priv; ++ priv = nautilus_window_slot_get_instance_private (self); ++ ++ priv->templates_menu = menu != NULL ? g_object_ref (menu) : NULL; ++} ++ + static void + nautilus_window_slot_set_property (GObject *object, + guint property_id, +@@ -755,6 +791,18 @@ nautilus_window_slot_set_property (GObject *object, + } + break; + ++ case PROP_EXTENSIONS_BACKGROUND_MENU: ++ { ++ real_set_extensions_background_menu (self, g_value_get_object (value)); ++ } ++ break; ++ ++ case PROP_TEMPLATES_MENU: ++ { ++ real_set_templates_menu (self, g_value_get_object (value)); ++ } ++ break; ++ + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +@@ -763,6 +811,44 @@ nautilus_window_slot_set_property (GObject *object, + } + } + ++static GMenu* ++real_get_extensions_background_menu (NautilusWindowSlot *self) ++{ ++ NautilusWindowSlotPrivate *priv; ++ ++ priv = nautilus_window_slot_get_instance_private (self); ++ return priv->extensions_background_menu; ++} ++ ++GMenu* ++nautilus_window_slot_get_extensions_background_menu (NautilusWindowSlot *self) ++{ ++ GMenu *menu = NULL; ++ ++ g_object_get (self, "extensions-background-menu", &menu, NULL); ++ ++ return menu; ++} ++ ++static GMenu* ++real_get_templates_menu (NautilusWindowSlot *self) ++{ ++ NautilusWindowSlotPrivate *priv; ++ ++ priv = nautilus_window_slot_get_instance_private (self); ++ return priv->templates_menu; ++} ++ ++GMenu* ++nautilus_window_slot_get_templates_menu (NautilusWindowSlot *self) ++{ ++ GMenu *menu = NULL; ++ ++ g_object_get (self, "templates-menu", &menu, NULL); ++ ++ return menu; ++} ++ + static void + nautilus_window_slot_get_property (GObject *object, + guint property_id, +@@ -796,7 +882,19 @@ nautilus_window_slot_get_property (GObject *object, + + case PROP_TOOLBAR_MENU_SECTIONS: + { +- g_value_set_pointer (value, nautilus_window_slot_get_toolbar_menu_sections (self)); ++ g_value_set_object (value, nautilus_window_slot_get_toolbar_menu_sections (self)); ++ } ++ break; ++ ++ case PROP_EXTENSIONS_BACKGROUND_MENU: ++ { ++ g_value_set_object (value, real_get_extensions_background_menu (self)); ++ } ++ break; ++ ++ case PROP_TEMPLATES_MENU: ++ { ++ g_value_set_object (value, real_get_templates_menu (self)); + } + break; + +@@ -2717,6 +2815,9 @@ nautilus_window_slot_switch_new_content_view (NautilusWindowSlot *self) + + if (priv->content_view != NULL) + { ++ g_binding_unbind (priv->extensions_background_menu_binding); ++ g_binding_unbind (priv->templates_menu_binding); ++ + widget = GTK_WIDGET (priv->content_view); + gtk_widget_destroy (widget); + g_object_unref (priv->content_view); +@@ -2733,8 +2834,17 @@ nautilus_window_slot_switch_new_content_view (NautilusWindowSlot *self) + gtk_widget_set_vexpand (widget, TRUE); + gtk_widget_show (widget); + ++ priv->extensions_background_menu_binding = g_object_bind_property (priv->content_view, "extensions-background-menu", ++ self, "extensions-background-menu", ++ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); ++ priv->templates_menu_binding = g_object_bind_property (priv->content_view, "templates-menu", ++ self, "templates-menu", ++ G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); ++ + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ICON]); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TOOLBAR_MENU_SECTIONS]); ++ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EXTENSIONS_BACKGROUND_MENU]); ++ g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TEMPLATES_MENU]); + } + + done: +@@ -2786,6 +2896,9 @@ nautilus_window_slot_dispose (GObject *object) + + nautilus_window_slot_remove_extra_location_widgets (self); + ++ g_clear_pointer (&priv->extensions_background_menu_binding, g_binding_unbind); ++ g_clear_pointer (&priv->templates_menu_binding, g_binding_unbind); ++ + if (priv->content_view) + { + gtk_widget_destroy (GTK_WIDGET (priv->content_view)); +@@ -2924,6 +3037,20 @@ nautilus_window_slot_class_init (NautilusWindowSlotClass *klass) + "The menu sections to add to the toolbar menu for this slot", + G_PARAM_READABLE); + ++ properties[PROP_EXTENSIONS_BACKGROUND_MENU] = ++ g_param_spec_object ("extensions-background-menu", ++ "Background menu of extensions", ++ "Proxy property from the view for the background menu for extensions", ++ G_TYPE_MENU, ++ G_PARAM_READWRITE); ++ ++ properties[PROP_TEMPLATES_MENU] = ++ g_param_spec_object ("templates-menu", ++ "Templates menu", ++ "Proxy property from the view for the templates menu", ++ G_TYPE_MENU, ++ G_PARAM_READWRITE); ++ + properties[PROP_LOCATION] = + g_param_spec_object ("location", + "Current location visible on the slot", +diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h +index 573357d9b..9be645aa4 100644 +--- a/src/nautilus-window-slot.h ++++ b/src/nautilus-window-slot.h +@@ -105,6 +105,10 @@ GIcon* nautilus_window_slot_get_icon (NautilusWindowSlot * + + NautilusToolbarMenuSections * nautilus_window_slot_get_toolbar_menu_sections (NautilusWindowSlot *slot); + ++GMenu* nautilus_window_slot_get_templates_menu (NautilusWindowSlot *self); ++ ++GMenu* nautilus_window_slot_get_extensions_background_menu (NautilusWindowSlot *self); ++ + gboolean nautilus_window_slot_get_active (NautilusWindowSlot *slot); + + void nautilus_window_slot_set_active (NautilusWindowSlot *slot, +diff --git a/src/resources/ui/nautilus-pathbar-context-menu.ui b/src/resources/ui/nautilus-pathbar-context-menu.ui +index 11b68857d..403cf71f6 100644 +--- a/src/resources/ui/nautilus-pathbar-context-menu.ui ++++ b/src/resources/ui/nautilus-pathbar-context-menu.ui +@@ -1,23 +1,54 @@ + ++ + +- ++ ++ ++ New _Folder ++ view.new-folder ++ ++ ++ templates-submenu ++ New _Document ++ view.new-document ++ action-disabled ++ ++ ++ Add to _Bookmarks ++ view.bookmark ++ +
+ +- Open In New _Tab +- pathbar.open-item-new-tab +- action-disabled ++ _Paste ++ view.paste + + +- Open In New _Window +- pathbar.open-item-new-window +- action-disabled ++ Select _All ++ view.select-all + +
++
++ extensions ++
+
+ + P_roperties +- pathbar.properties ++ view.current-directory-properties ++ action-disabled + +
+
++ ++ ++ Open in New _Window ++ pathbar.open-item-new-window ++ ++ ++ Open in New _Tab ++ pathbar.open-item-new-tab ++ ++ ++ _Properties ++ pathbar.properties ++ ++ + +-- +2.36.0 + diff --git a/SOURCES/files-view-Add-menu-item-to-copy-current-path.patch b/SOURCES/files-view-Add-menu-item-to-copy-current-path.patch new file mode 100644 index 0000000..0cd5d5a --- /dev/null +++ b/SOURCES/files-view-Add-menu-item-to-copy-current-path.patch @@ -0,0 +1,77 @@ +diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c +index 08107a64e..d808b04ff 100644 +--- a/src/nautilus-files-view.c ++++ b/src/nautilus-files-view.c +@@ -6078,6 +6078,33 @@ action_cut (GSimpleAction *action, + nautilus_file_list_free (selection); + } + ++static void ++action_copy_current_location (GSimpleAction *action, ++ GVariant *state, ++ gpointer user_data) ++{ ++ NautilusFilesView *view; ++ GtkClipboard *clipboard; ++ GFile *file; ++ gchar *path; ++ NautilusFilesViewPrivate *priv; ++ ++ view = NAUTILUS_FILES_VIEW (user_data); ++ priv = nautilus_files_view_get_instance_private (view); ++ ++ if (priv->directory_as_file != NULL) ++ { ++ file = nautilus_file_get_location (priv->directory_as_file); ++ ++ clipboard = nautilus_clipboard_get (GTK_WIDGET (view)); ++ path = g_file_get_parse_name (file); ++ gtk_clipboard_set_text (clipboard, path, -1); ++ ++ g_object_unref (file); ++ g_free (path); ++ } ++} ++ + static void + action_create_links_in_place (GSimpleAction *action, + GVariant *state, +@@ -6958,6 +6985,7 @@ const GActionEntry view_entries[] = + { "new-folder", action_new_folder }, + { "select-all", action_select_all }, + { "paste", action_paste_files }, ++ { "copy-current-location", action_copy_current_location }, + { "create-link", action_create_links }, + { "new-document" }, + /* Selection menu */ +@@ -7590,6 +7618,10 @@ real_update_actions_state (NautilusFilesView *view) + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), + can_move_files && !selection_contains_recent && + !selection_contains_starred); ++ action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group), ++ "copy-current-location"); ++ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), ++ !selection_contains_search); + + /* Drive menu */ + show_mount = (selection != NULL); +diff --git a/src/resources/ui/nautilus-pathbar-context-menu.ui b/src/resources/ui/nautilus-pathbar-context-menu.ui +index 403cf71f6..4d32c1e8e 100644 +--- a/src/resources/ui/nautilus-pathbar-context-menu.ui ++++ b/src/resources/ui/nautilus-pathbar-context-menu.ui +@@ -16,6 +16,12 @@ + Add to _Bookmarks + view.bookmark + ++
++ ++ _Copy Location ++ view.copy-current-location ++ ++
+
+ + _Paste +-- +2.36.1 + diff --git a/SOURCES/files-view-Backport-translations.patch b/SOURCES/files-view-Backport-translations.patch new file mode 100644 index 0000000..e177a7c --- /dev/null +++ b/SOURCES/files-view-Backport-translations.patch @@ -0,0 +1,156 @@ +diff -ruN nautilus-3.28.1/po/ca.po nautilus-3.28.1.translations/po/ca.po +--- nautilus-3.28.1/po/ca.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/ca.po 2022-06-20 17:02:58.239093717 +0200 +@@ -7061,3 +7061,7 @@ + #~ "Amb el Nautilus heu d'haver rebut una còpia de la Llicència Pública " + #~ "General de GNU; si no és així, escriviu a la Free Software Foundation, " + #~ "Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:24 ++msgid "_Copy Location" ++msgstr "_Copia la ubicació" +diff -ruN nautilus-3.28.1/po/de.po nautilus-3.28.1.translations/po/de.po +--- nautilus-3.28.1/po/de.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/de.po 2022-06-20 17:02:58.276093695 +0200 +@@ -5716,3 +5716,7 @@ + + #~ msgid "org.gnome.Nautilus" + #~ msgstr "org.gnome.Nautilus" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:24 ++msgid "_Copy Location" ++msgstr "Ort _kopieren" +diff -ruN nautilus-3.28.1/po/es.po nautilus-3.28.1.translations/po/es.po +--- nautilus-3.28.1/po/es.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/es.po 2022-06-20 17:02:58.309093676 +0200 +@@ -10830,3 +10830,8 @@ + #~ msgstr "" + #~ "Nautilus es un shell gráfico para GNOME que facilita la administración de " + #~ "sus archivos y el resto de su sistema." ++ ++# src/nautilus-location-bar.c:401 ++#: src/resources/ui/nautilus-files-view-context-menus.ui:24 ++msgid "_Copy Location" ++msgstr "Copiar _ubicación" +diff -ruN nautilus-3.28.1/po/fa.po nautilus-3.28.1.translations/po/fa.po +--- nautilus-3.28.1/po/fa.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/fa.po 2022-06-20 17:02:58.327093666 +0200 +@@ -10082,3 +10082,7 @@ + + #~ msgid "C_ancel Remove" + #~ msgstr "ان_صراف از حذف" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:24 ++msgid "_Copy Location" ++msgstr "_رونوشت از مکان" +diff -ruN nautilus-3.28.1/po/fr.po nautilus-3.28.1.translations/po/fr.po +--- nautilus-3.28.1/po/fr.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/fr.po 2022-06-20 17:02:58.339093659 +0200 +@@ -5975,3 +5975,7 @@ + + #~ msgid "Copying “%B” to “%B”" + #~ msgstr "Copie de « %B » vers « %B »" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:34 ++msgid "_Copy Location" ++msgstr "Co_pier l’emplacement" +diff -ruN nautilus-3.28.1/po/fur.po nautilus-3.28.1.translations/po/fur.po +--- nautilus-3.28.1/po/fur.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/fur.po 2022-06-20 17:02:58.348093654 +0200 +@@ -7711,3 +7711,7 @@ + + #~ msgid "Set the zoom level of the current view" + #~ msgstr "Imposte il nivel di zoom de viodude atuâl" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:24 ++msgid "_Copy Location" ++msgstr "_Copie posizion" +diff -ruN nautilus-3.28.1/po/gl.po nautilus-3.28.1.translations/po/gl.po +--- nautilus-3.28.1/po/gl.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/gl.po 2022-06-20 17:02:58.366093644 +0200 +@@ -7429,3 +7429,8 @@ + + #~ msgid "Error autorunning software" + #~ msgstr "Produciuse un erro ao autoexecutar o software" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:24 ++#| msgid "Location" ++msgid "_Copy Location" ++msgstr "_Copiar localización" +diff -ruN nautilus-3.28.1/po/he.po nautilus-3.28.1.translations/po/he.po +--- nautilus-3.28.1/po/he.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/he.po 2022-06-20 17:02:58.387093632 +0200 +@@ -10468,3 +10468,7 @@ + + #~ msgid "Question" + #~ msgstr "שאלה" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:34 ++msgid "_Copy Location" ++msgstr "ה_עתקת מיקום" +diff -ruN nautilus-3.28.1/po/oc.po nautilus-3.28.1.translations/po/oc.po +--- nautilus-3.28.1/po/oc.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/oc.po 2022-06-20 17:02:58.523093554 +0200 +@@ -6999,3 +6999,7 @@ + + #~ msgid "Rename “%s”" + #~ msgstr "Renomenar lo fichièr « %s »" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:34 ++msgid "_Copy Location" ++msgstr "_Copiar l'emplaçament" +diff -ruN nautilus-3.28.1/po/pt.po nautilus-3.28.1.translations/po/pt.po +--- nautilus-3.28.1/po/pt.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/pt.po 2022-06-20 17:02:58.627093494 +0200 +@@ -5944,3 +5944,7 @@ + + #~ msgid "Whether the row represents a network location" + #~ msgstr "Se a linha representa uma localização de rede" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:34 ++msgid "_Copy Location" ++msgstr "_Copiar localização" +diff -ruN nautilus-3.28.1/po/ru.po nautilus-3.28.1.translations/po/ru.po +--- nautilus-3.28.1/po/ru.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/ru.po 2022-06-20 17:02:58.652093480 +0200 +@@ -6177,3 +6177,7 @@ + #~ msgctxt "Bookmark" + #~ msgid "_Name" + #~ msgstr "_Имя" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:34 ++msgid "_Copy Location" ++msgstr "_Копировать адрес" +diff -ruN nautilus-3.28.1/po/tr.po nautilus-3.28.1.translations/po/tr.po +--- nautilus-3.28.1/po/tr.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/tr.po 2022-06-20 17:02:58.776093409 +0200 +@@ -6188,3 +6188,7 @@ + + #~ msgid "D_efault zoom level:" + #~ msgstr "Ön_tanımlı yaklaştırma seviyesi:" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:24 ++msgid "_Copy Location" ++msgstr "Konumu _Kopyala" +diff -ruN nautilus-3.28.1/po/uk.po nautilus-3.28.1.translations/po/uk.po +--- nautilus-3.28.1/po/uk.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/uk.po 2022-06-20 17:02:58.808093390 +0200 +@@ -7967,3 +7967,7 @@ + + #~ msgid "Set the zoom level of the current view" + #~ msgstr "Встановити рівень масштабування поточного вікна" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:34 ++msgid "_Copy Location" ++msgstr "_Копіювати адресу" +diff -ruN nautilus-3.28.1/po/zh_CN.po nautilus-3.28.1.translations/po/zh_CN.po +--- nautilus-3.28.1/po/zh_CN.po 2018-04-09 22:02:06.000000000 +0200 ++++ nautilus-3.28.1.translations/po/zh_CN.po 2022-06-20 17:02:58.865093358 +0200 +@@ -5495,3 +5495,7 @@ + + #~ msgid "Zoom In" + #~ msgstr "放大" ++ ++#: src/resources/ui/nautilus-files-view-context-menus.ui:34 ++msgid "_Copy Location" ++msgstr "复制位置(_C)" diff --git a/SOURCES/nautilus-canvas-container-Remove-the-include-visible.patch b/SOURCES/nautilus-canvas-container-Remove-the-include-visible.patch new file mode 100644 index 0000000..4ecda1d --- /dev/null +++ b/SOURCES/nautilus-canvas-container-Remove-the-include-visible.patch @@ -0,0 +1,189 @@ +From a7a31137aee8c4af81d7d447ceb83ccdb2ddadc0 Mon Sep 17 00:00:00 2001 +From: Xiang Fan +Date: Fri, 13 Jul 2018 11:49:09 -0700 +Subject: [PATCH] nautilus-canvas-container: Remove the "include visible area" + logic. + +canvas_set_scroll_region_include_visible_area() was added in +ec054c80981e26b71c8bb2e6853b035dc2063e7d to fix +https://bugzilla.gnome.org/show_bug.cgi?id=42068 ("Dragging icons +adjusts scroll area in a way that causes immediate scrolling"). This is +no longer the case, because now icons remain in place when being dragged +and are not allowed to be rearranged. + +ec054c80981e26b71c8bb2e6853b035dc2063e7d causes issues relating to extra +scrolling space (#340), hence the removal. + +Fixes #340. +--- + src/nautilus-canvas-container.c | 79 +-------------------------------- + src/nautilus-canvas-container.h | 1 - + src/nautilus-canvas-private.h | 3 -- + src/nautilus-canvas-view.c | 6 --- + 4 files changed, 1 insertion(+), 88 deletions(-) + +diff --git a/src/nautilus-canvas-container.c b/src/nautilus-canvas-container.c +index 09acd47fc..bd05a3a2d 100644 +--- a/src/nautilus-canvas-container.c ++++ b/src/nautilus-canvas-container.c +@@ -968,45 +968,6 @@ get_all_icon_bounds (NautilusCanvasContainer *container, + x1, y1, x2, y2, usage); + } + +-/* Don't preserve visible white space the next time the scroll region +- * is recomputed when the container is not empty. */ +-void +-nautilus_canvas_container_reset_scroll_region (NautilusCanvasContainer *container) +-{ +- container->details->reset_scroll_region_trigger = TRUE; +-} +- +-/* Set a new scroll region without eliminating any of the currently-visible area. */ +-static void +-canvas_set_scroll_region_include_visible_area (EelCanvas *canvas, +- double x1, +- double y1, +- double x2, +- double y2) +-{ +- double old_x1, old_y1, old_x2, old_y2; +- double old_scroll_x, old_scroll_y; +- double height, width; +- GtkAllocation allocation; +- +- eel_canvas_get_scroll_region (canvas, &old_x1, &old_y1, &old_x2, &old_y2); +- gtk_widget_get_allocation (GTK_WIDGET (canvas), &allocation); +- +- width = (allocation.width) / canvas->pixels_per_unit; +- height = (allocation.height) / canvas->pixels_per_unit; +- +- old_scroll_x = gtk_adjustment_get_value (gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (canvas))); +- old_scroll_y = gtk_adjustment_get_value (gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (canvas))); +- +- x1 = MIN (x1, old_x1 + old_scroll_x); +- y1 = MIN (y1, old_y1 + old_scroll_y); +- x2 = MAX (x2, old_x1 + old_scroll_x + width); +- y2 = MAX (y2, old_y1 + old_scroll_y + height); +- +- eel_canvas_set_scroll_region +- (canvas, x1, y1, x2, y2); +-} +- + void + nautilus_canvas_container_update_scroll_region (NautilusCanvasContainer *container) + { +@@ -1014,24 +975,10 @@ nautilus_canvas_container_update_scroll_region (NautilusCanvasContainer *contain + double pixels_per_unit; + GtkAdjustment *hadj, *vadj; + float step_increment; +- gboolean reset_scroll_region; + GtkAllocation allocation; + + pixels_per_unit = EEL_CANVAS (container)->pixels_per_unit; + +- reset_scroll_region = container->details->reset_scroll_region_trigger +- || nautilus_canvas_container_is_empty (container); +- +- /* The trigger is only cleared when container is non-empty, so +- * callers can reliably reset the scroll region when an item +- * is added even if extraneous relayouts are called when the +- * window is still empty. +- */ +- if (!nautilus_canvas_container_is_empty (container)) +- { +- container->details->reset_scroll_region_trigger = FALSE; +- } +- + get_all_icon_bounds (container, &x1, &y1, &x2, &y2, BOUNDS_USAGE_FOR_ENTIRE_ITEM); + + /* Add border at the "end"of the layout (i.e. after the icons), to +@@ -1053,18 +1000,7 @@ nautilus_canvas_container_update_scroll_region (NautilusCanvasContainer *contain + y2 -= 1; + y2 = MAX (y1, y2); + +- if (reset_scroll_region) +- { +- eel_canvas_set_scroll_region +- (EEL_CANVAS (container), +- x1, y1, x2, y2); +- } +- else +- { +- canvas_set_scroll_region_include_visible_area +- (EEL_CANVAS (container), +- x1, y1, x2, y2); +- } ++ eel_canvas_set_scroll_region (EEL_CANVAS (container), x1, y1, x2, y2); + + hadj = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (container)); + vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (container)); +@@ -5722,23 +5658,10 @@ nautilus_canvas_container_get_icon_drop_target_uri (NautilusCanvasContainer *con + return uri; + } + +-/* Call to reset the scroll region only if the container is not empty, +- * to avoid having the flag linger until the next file is added. +- */ +-static void +-reset_scroll_region_if_not_empty (NautilusCanvasContainer *container) +-{ +- if (!nautilus_canvas_container_is_empty (container)) +- { +- nautilus_canvas_container_reset_scroll_region (container); +- } +-} +- + /* Re-sort, switching to automatic layout if it was in manual layout. */ + void + nautilus_canvas_container_sort (NautilusCanvasContainer *container) + { +- reset_scroll_region_if_not_empty (container); + container->details->needs_resort = TRUE; + redo_layout (container); + } +diff --git a/src/nautilus-canvas-container.h b/src/nautilus-canvas-container.h +index a370bba26..33929375d 100644 +--- a/src/nautilus-canvas-container.h ++++ b/src/nautilus-canvas-container.h +@@ -271,7 +271,6 @@ void nautilus_canvas_container_set_single_click_mode (Nauti + gboolean single_click_mode); + void nautilus_canvas_container_enable_linger_selection (NautilusCanvasContainer *view, + gboolean enable); +-void nautilus_canvas_container_reset_scroll_region (NautilusCanvasContainer *container); + void nautilus_canvas_container_set_font (NautilusCanvasContainer *container, + const char *font); + void nautilus_canvas_container_set_margins (NautilusCanvasContainer *container, +diff --git a/src/nautilus-canvas-private.h b/src/nautilus-canvas-private.h +index dd5e79060..e60e86299 100644 +--- a/src/nautilus-canvas-private.h ++++ b/src/nautilus-canvas-private.h +@@ -192,9 +192,6 @@ struct NautilusCanvasContainerDetails { + + int size_allocation_count; + guint size_allocation_count_id; +- +- /* Ignore the visible area the next time the scroll region is recomputed */ +- gboolean reset_scroll_region_trigger; + + /* a11y items used by canvas items */ + guint a11y_item_action_idle_handler; +diff --git a/src/nautilus-canvas-view.c b/src/nautilus-canvas-view.c +index f74ea06db..bd3a7ae5d 100644 +--- a/src/nautilus-canvas-view.c ++++ b/src/nautilus-canvas-view.c +@@ -355,12 +355,6 @@ nautilus_canvas_view_add_files (NautilusFilesView *view, + canvas_view = NAUTILUS_CANVAS_VIEW (view); + canvas_container = get_canvas_container (canvas_view); + +- /* Reset scroll region for the first canvas added when loading a directory. */ +- if (nautilus_files_view_get_loading (view) && nautilus_canvas_container_is_empty (canvas_container)) +- { +- nautilus_canvas_container_reset_scroll_region (canvas_container); +- } +- + for (l = files; l != NULL; l = l->next) + { + if (nautilus_canvas_container_add (canvas_container, +-- +2.37.1 + diff --git a/SOURCES/window-Streamline-RestoreTabData-memory-management.patch b/SOURCES/window-Streamline-RestoreTabData-memory-management.patch new file mode 100644 index 0000000..4223c38 --- /dev/null +++ b/SOURCES/window-Streamline-RestoreTabData-memory-management.patch @@ -0,0 +1,118 @@ +From 4bdd3fad8d51e50e3539c8e04bc91538467bd236 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ant=C3=B3nio=20Fernandes?= +Date: Wed, 8 Jul 2020 14:44:38 +0100 +Subject: [PATCH] window: Streamline RestoreTabData memory management + +When restoring the back and forward lists, we make a deep copy only to +free the data immediately afterwards. + +Instead of reallocating the lists unnecessarily, let's just steal them. + +Also, use g_queue_free_full() to make free_restore_tab_data() a proper +GDestroyNotify; also define it in window-slot.c, where it belongs. +--- + src/nautilus-window-slot.c | 16 ++++++++++++++-- + src/nautilus-window-slot.h | 1 + + src/nautilus-window.c | 20 ++------------------ + 3 files changed, 17 insertions(+), 20 deletions(-) + +diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c +index c3260aeb0..bf040bff2 100644 +--- a/src/nautilus-window-slot.c ++++ b/src/nautilus-window-slot.c +@@ -155,6 +155,18 @@ static void trash_state_changed_cb (NautilusTrashMonitor *monitor, + gboolean is_empty, + gpointer user_data); + ++void ++free_restore_tab_data (gpointer data) ++{ ++ RestoreTabData *tab_data = data; ++ ++ g_list_free_full (tab_data->back_list, g_object_unref); ++ g_list_free_full (tab_data->forward_list, g_object_unref); ++ nautilus_file_unref (tab_data->file); ++ ++ g_free (tab_data); ++} ++ + void + nautilus_window_slot_restore_from_data (NautilusWindowSlot *self, + RestoreTabData *data) +@@ -163,9 +175,9 @@ nautilus_window_slot_restore_from_data (NautilusWindowSlot *self, + + priv = nautilus_window_slot_get_instance_private (self); + +- priv->back_list = g_list_copy_deep (data->back_list, (GCopyFunc) g_object_ref, NULL); ++ priv->back_list = g_steal_pointer (&data->back_list); + +- priv->forward_list = g_list_copy_deep (data->forward_list, (GCopyFunc) g_object_ref, NULL); ++ priv->forward_list = g_steal_pointer (&data->forward_list); + + priv->view_mode_before_search = data->view_before_search; + +diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h +index 573357d9b..bda1a920f 100644 +--- a/src/nautilus-window-slot.h ++++ b/src/nautilus-window-slot.h +@@ -125,4 +125,5 @@ RestoreTabData* nautilus_window_slot_get_restore_tab_data (NautilusWindowSlot *s + /* Only used by slot-dnd */ + NautilusView* nautilus_window_slot_get_current_view (NautilusWindowSlot *slot); + ++void free_restore_tab_data (gpointer data); + #endif /* NAUTILUS_WINDOW_SLOT_H */ +diff --git a/src/nautilus-window.c b/src/nautilus-window.c +index 1f8d5208e..175da6fce 100644 +--- a/src/nautilus-window.c ++++ b/src/nautilus-window.c +@@ -79,8 +79,6 @@ static GtkWidget *nautilus_window_ensure_location_entry (NautilusWindow *window) + static void close_slot (NautilusWindow *window, + NautilusWindowSlot *slot, + gboolean remove_from_notebook); +-static void free_restore_tab_data (gpointer data, +- gpointer user_data); + + /* Sanity check: highest mouse button value I could find was 14. 5 is our + * lower threshold (well-documented to be the one of the button events for the +@@ -1374,7 +1372,7 @@ action_restore_tab (GSimpleAction *action, + nautilus_window_slot_open_location_full (slot, location, flags, NULL); + nautilus_window_slot_restore_from_data (slot, data); + +- free_restore_tab_data (data, NULL); ++ free_restore_tab_data (data); + } + + static void +@@ -2501,19 +2499,6 @@ nautilus_window_destroy (GtkWidget *object) + GTK_WIDGET_CLASS (nautilus_window_parent_class)->destroy (object); + } + +-static void +-free_restore_tab_data (gpointer data, +- gpointer user_data) +-{ +- RestoreTabData *tab_data = data; +- +- g_list_free_full (tab_data->back_list, g_object_unref); +- g_list_free_full (tab_data->forward_list, g_object_unref); +- nautilus_file_unref (tab_data->file); +- +- g_free (tab_data); +-} +- + static void + nautilus_window_finalize (GObject *object) + { +@@ -2548,8 +2533,7 @@ nautilus_window_finalize (GObject *object) + G_CALLBACK (nautilus_window_on_undo_changed), + window); + +- g_queue_foreach (priv->tab_data_queue, (GFunc) free_restore_tab_data, NULL); +- g_queue_free (priv->tab_data_queue); ++ g_queue_free_full (priv->tab_data_queue, free_restore_tab_data); + + g_object_unref (priv->pad_controller); + +-- +2.35.1 + diff --git a/SOURCES/window-slot-Rename-RestoreTabData-to-NautilusNavigat.patch b/SOURCES/window-slot-Rename-RestoreTabData-to-NautilusNavigat.patch new file mode 100644 index 0000000..5a18665 --- /dev/null +++ b/SOURCES/window-slot-Rename-RestoreTabData-to-NautilusNavigat.patch @@ -0,0 +1,170 @@ +From 148559bc6809aac40be4aff64b7d3a4e5ac3c59a Mon Sep 17 00:00:00 2001 +From: Sachin Daluja <30343-sachindaluja@users.noreply.gitlab.gnome.org> +Date: Sun, 24 May 2020 13:29:49 -0400 +Subject: [PATCH] window-slot: Rename RestoreTabData to NautilusNavigationState + +This struct is going to be used to also restore navigation state when +replacing the active window slot in order to handle other-locations:// + +Also enhance it to also save and restore the current location bookmark. +--- + src/nautilus-window-slot.c | 28 ++++++++++++++++------------ + src/nautilus-window-slot.h | 11 ++++++----- + src/nautilus-window.c | 12 ++++++------ + 3 files changed, 28 insertions(+), 23 deletions(-) + +diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c +index bf040bff2..e688f0716 100644 +--- a/src/nautilus-window-slot.c ++++ b/src/nautilus-window-slot.c +@@ -156,20 +156,21 @@ static void trash_state_changed_cb (NautilusTrashMonitor *monitor, + gpointer user_data); + + void +-free_restore_tab_data (gpointer data) ++free_navigation_state (gpointer data) + { +- RestoreTabData *tab_data = data; ++ NautilusNavigationState *navigation_state = data; + +- g_list_free_full (tab_data->back_list, g_object_unref); +- g_list_free_full (tab_data->forward_list, g_object_unref); +- nautilus_file_unref (tab_data->file); ++ g_list_free_full (navigation_state->back_list, g_object_unref); ++ g_list_free_full (navigation_state->forward_list, g_object_unref); ++ nautilus_file_unref (navigation_state->file); ++ g_clear_object (&navigation_state->current_location_bookmark); + +- g_free (tab_data); ++ g_free (navigation_state); + } + + void +-nautilus_window_slot_restore_from_data (NautilusWindowSlot *self, +- RestoreTabData *data) ++nautilus_window_slot_restore_navigation_state (NautilusWindowSlot *self, ++ NautilusNavigationState *data) + { + NautilusWindowSlotPrivate *priv; + +@@ -181,14 +182,16 @@ nautilus_window_slot_restore_from_data (NautilusWindowSlot *self, + + priv->view_mode_before_search = data->view_before_search; + ++ g_set_object (&priv->current_location_bookmark, data->current_location_bookmark); ++ + priv->location_change_type = NAUTILUS_LOCATION_CHANGE_RELOAD; + } + +-RestoreTabData * +-nautilus_window_slot_get_restore_tab_data (NautilusWindowSlot *self) ++NautilusNavigationState * ++nautilus_window_slot_get_navigation_state (NautilusWindowSlot *self) + { + NautilusWindowSlotPrivate *priv; +- RestoreTabData *data; ++ NautilusNavigationState *data; + GList *back_list; + GList *forward_list; + +@@ -211,11 +214,12 @@ nautilus_window_slot_get_restore_tab_data (NautilusWindowSlot *self) + * the view mode before search and a reference to the file. + * A GFile isn't enough, as the NautilusFile also keeps a + * reference to the search directory */ +- data = g_new0 (RestoreTabData, 1); ++ data = g_new0 (NautilusNavigationState, 1); + data->back_list = back_list; + data->forward_list = forward_list; + data->file = nautilus_file_get (priv->location); + data->view_before_search = priv->view_mode_before_search; ++ g_set_object (&data->current_location_bookmark, priv->current_location_bookmark); + + return data; + } +diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h +index bda1a920f..2edc96786 100644 +--- a/src/nautilus-window-slot.h ++++ b/src/nautilus-window-slot.h +@@ -48,7 +48,8 @@ typedef struct + gint view_before_search; + GList *back_list; + GList *forward_list; +-} RestoreTabData; ++ NautilusBookmark *current_location_bookmark; ++} NautilusNavigationState; + + struct _NautilusWindowSlotClass { + GtkBoxClass parent_class; +@@ -117,13 +118,13 @@ void nautilus_window_slot_search (NautilusWindowSlot * + gboolean nautilus_window_slot_handles_location (NautilusWindowSlot *self, + GFile *location); + +-void nautilus_window_slot_restore_from_data (NautilusWindowSlot *self, +- RestoreTabData *data); ++void nautilus_window_slot_restore_navigation_state (NautilusWindowSlot *self, ++ NautilusNavigationState *data); + +-RestoreTabData* nautilus_window_slot_get_restore_tab_data (NautilusWindowSlot *self); ++NautilusNavigationState* nautilus_window_slot_get_navigation_state (NautilusWindowSlot *self); + + /* Only used by slot-dnd */ + NautilusView* nautilus_window_slot_get_current_view (NautilusWindowSlot *slot); + +-void free_restore_tab_data (gpointer data); ++void free_navigation_state (gpointer data); + #endif /* NAUTILUS_WINDOW_SLOT_H */ +diff --git a/src/nautilus-window.c b/src/nautilus-window.c +index 175da6fce..900239cb8 100644 +--- a/src/nautilus-window.c ++++ b/src/nautilus-window.c +@@ -1349,7 +1349,7 @@ action_restore_tab (GSimpleAction *action, + NautilusWindowOpenFlags flags; + g_autoptr (GFile) location = NULL; + NautilusWindowSlot *slot; +- RestoreTabData *data; ++ NautilusNavigationState *data; + + priv = nautilus_window_get_instance_private (window); + +@@ -1370,9 +1370,9 @@ action_restore_tab (GSimpleAction *action, + slot = nautilus_window_create_and_init_slot (window, location, flags); + + nautilus_window_slot_open_location_full (slot, location, flags, NULL); +- nautilus_window_slot_restore_from_data (slot, data); ++ nautilus_window_slot_restore_navigation_state (slot, data); + +- free_restore_tab_data (data); ++ free_navigation_state (data); + } + + static void +@@ -1579,7 +1579,7 @@ nautilus_window_slot_close (NautilusWindow *window, + { + NautilusWindowPrivate *priv; + NautilusWindowSlot *next_slot; +- RestoreTabData *data; ++ NautilusNavigationState *data; + + DEBUG ("Requesting to remove slot %p from window %p", slot, window); + if (window == NULL) +@@ -1595,7 +1595,7 @@ nautilus_window_slot_close (NautilusWindow *window, + nautilus_window_set_active_slot (window, next_slot); + } + +- data = nautilus_window_slot_get_restore_tab_data (slot); ++ data = nautilus_window_slot_get_navigation_state (slot); + if (data != NULL) + { + g_queue_push_head (priv->tab_data_queue, data); +@@ -2533,7 +2533,7 @@ nautilus_window_finalize (GObject *object) + G_CALLBACK (nautilus_window_on_undo_changed), + window); + +- g_queue_free_full (priv->tab_data_queue, free_restore_tab_data); ++ g_queue_free_full (priv->tab_data_queue, free_navigation_state); + + g_object_unref (priv->pad_controller); + +-- +2.35.1 + diff --git a/SOURCES/window-window-slot-Save-and-restore-navigation-histo.patch b/SOURCES/window-window-slot-Save-and-restore-navigation-histo.patch new file mode 100644 index 0000000..01c25ed --- /dev/null +++ b/SOURCES/window-window-slot-Save-and-restore-navigation-histo.patch @@ -0,0 +1,242 @@ +From fe7533b0b82e2ebc7767006ee9768572700a91df Mon Sep 17 00:00:00 2001 +From: Sachin Daluja <30343-sachindaluja@users.noreply.gitlab.gnome.org> +Date: Sun, 10 May 2020 22:30:03 -0400 +Subject: [PATCH] window, window-slot: Save and restore navigation history + +When a new window slot instance replaces the existing one to handle the new +location. + +This allows back and forward history lists to be preserved when the window +switches between instances of different window slot classes. + +Closes https://gitlab.gnome.org/GNOME/nautilus/-/issues/32 +--- + src/nautilus-window-slot.c | 48 +++++++++++++++++++--- + src/nautilus-window-slot.h | 13 ++++++ + src/nautilus-window.c | 84 +++++++++++++++++++++++++++++++++++++- + 3 files changed, 138 insertions(+), 7 deletions(-) + +diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c +index e688f0716..69040fc44 100644 +--- a/src/nautilus-window-slot.c ++++ b/src/nautilus-window-slot.c +@@ -176,6 +176,9 @@ nautilus_window_slot_restore_navigation_state (NautilusWindowSlot *self, + + priv = nautilus_window_slot_get_instance_private (self); + ++ /* We are restoring saved history to newly created slot with no history. */ ++ g_warn_if_fail (priv->back_list == NULL && priv->forward_list == NULL); ++ + priv->back_list = g_steal_pointer (&data->back_list); + + priv->forward_list = g_steal_pointer (&data->forward_list); +@@ -2003,12 +2006,11 @@ nautilus_window_slot_set_content_view (NautilusWindowSlot *self, + } + + void +-nautilus_window_back_or_forward (NautilusWindow *window, +- gboolean back, +- guint distance, +- NautilusWindowOpenFlags flags) ++nautilus_window_slot_back_or_forward (NautilusWindowSlot *self, ++ gboolean back, ++ guint distance, ++ NautilusWindowOpenFlags flags) + { +- NautilusWindowSlot *self; + GList *list; + GFile *location; + guint len; +@@ -2016,7 +2018,6 @@ nautilus_window_back_or_forward (NautilusWindow *window, + GFile *old_location; + NautilusWindowSlotPrivate *priv; + +- self = nautilus_window_get_active_slot (window); + priv = nautilus_window_slot_get_instance_private (self); + list = back ? priv->back_list : priv->forward_list; + +@@ -3308,3 +3309,38 @@ nautilus_window_slot_get_loading (NautilusWindowSlot *self) + + return priv->loading; + } ++ ++/* ++ * Open the specified location and set up the navigation history including the ++ * back and forward lists. This function is intended to be called when switching ++ * between NautilusWindowSlot and NautilusOtherLocationsWindowSlot. It allows ++ * the navigation history accumulated in the slot being replaced to be loaded ++ * into the replacing slot. ++ * ++ * The 'location' member variable is set to the new location before calling ++ * begin_location_change() to ensure that it matches the ++ * 'current_location_bookmark' member as expected by the location change ++ * pipeline. ++ */ ++void ++nautilus_window_slot_open_location_set_navigation_state (NautilusWindowSlot *self, ++ GFile *location, ++ NautilusWindowOpenFlags flags, ++ GList *new_selection, ++ NautilusLocationChangeType change_type, ++ NautilusNavigationState *navigation_state, ++ guint distance) ++{ ++ NautilusWindowSlotPrivate *priv; ++ ++ priv = nautilus_window_slot_get_instance_private (self); ++ ++ nautilus_window_slot_restore_navigation_state (self, navigation_state); ++ ++ g_clear_object (&priv->location); ++ ++ priv->location = nautilus_file_get_location (navigation_state->file); ++ ++ begin_location_change (self, location, NULL, new_selection, ++ change_type, distance, NULL); ++} +diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h +index 2edc96786..cbd3454ce 100644 +--- a/src/nautilus-window-slot.h ++++ b/src/nautilus-window-slot.h +@@ -82,6 +82,14 @@ void nautilus_window_slot_open_location_full (NautilusWindowSlot + NautilusWindowOpenFlags flags, + GList *new_selection); + ++void nautilus_window_slot_open_location_set_navigation_state (NautilusWindowSlot *slot, ++ GFile *location, ++ NautilusWindowOpenFlags flags, ++ GList *new_selection, ++ NautilusLocationChangeType change_type, ++ NautilusNavigationState *navigation_state, ++ guint distance); ++ + GFile * nautilus_window_slot_get_location (NautilusWindowSlot *slot); + + NautilusBookmark *nautilus_window_slot_get_bookmark (NautilusWindowSlot *slot); +@@ -126,5 +134,10 @@ NautilusNavigationState* nautilus_window_slot_get_navigation_state (NautilusWind + /* Only used by slot-dnd */ + NautilusView* nautilus_window_slot_get_current_view (NautilusWindowSlot *slot); + ++void nautilus_window_slot_back_or_forward (NautilusWindowSlot *slot, ++ gboolean back, ++ guint distance, ++ NautilusWindowOpenFlags flags); ++ + void free_navigation_state (gpointer data); + #endif /* NAUTILUS_WINDOW_SLOT_H */ +diff --git a/src/nautilus-window.c b/src/nautilus-window.c +index 900239cb8..af01b43e7 100644 +--- a/src/nautilus-window.c ++++ b/src/nautilus-window.c +@@ -613,6 +613,7 @@ nautilus_window_open_location_full (NautilusWindow *window, + { + NautilusWindowSlot *active_slot; + gboolean new_tab_at_end; ++ NautilusNavigationState *navigation_state = NULL; + + /* The location owner can be one of the slots requesting to handle an + * unhandled location. But this slot can be destroyed when switching to +@@ -644,6 +645,8 @@ nautilus_window_open_location_full (NautilusWindow *window, + } + else if (!nautilus_window_slot_handles_location (target_slot, location)) + { ++ navigation_state = nautilus_window_slot_get_navigation_state (active_slot); ++ + target_slot = replace_active_slot (window, location, flags); + } + +@@ -655,7 +658,19 @@ nautilus_window_open_location_full (NautilusWindow *window, + nautilus_window_set_active_slot (window, target_slot); + } + +- nautilus_window_slot_open_location_full (target_slot, location, flags, selection); ++ if (navigation_state != NULL) ++ { ++ nautilus_window_slot_open_location_set_navigation_state (target_slot, ++ location, flags, selection, ++ NAUTILUS_LOCATION_CHANGE_STANDARD, ++ navigation_state, 0); ++ ++ free_navigation_state (navigation_state); ++ } ++ else ++ { ++ nautilus_window_slot_open_location_full (target_slot, location, flags, selection); ++ } + + g_object_unref (location); + } +@@ -3099,3 +3114,70 @@ nautilus_window_search (NautilusWindow *window, + g_warning ("Trying search on a slot but no active slot present"); + } + } ++ ++/* Ideally, this method should be a simple wrapper for the slot method. However, ++ * going back or forward can result in a new slot (or another subclass), so we ++ * workaround that by duplicating part of nautilus_window_slot_back_or_forward() ++ */ ++void ++nautilus_window_back_or_forward (NautilusWindow *window, ++ gboolean back, ++ guint distance, ++ NautilusWindowOpenFlags flags) ++{ ++ NautilusWindowSlot *slot; ++ GList *next_location_list, *back_list, *forward_list; ++ GFile *next_location; ++ guint len; ++ NautilusBookmark *next_location_bookmark; ++ gboolean active_slot_handles_location; ++ ++ slot = nautilus_window_get_active_slot (window); ++ back_list = nautilus_window_slot_get_back_history (slot); ++ forward_list = nautilus_window_slot_get_forward_history (slot); ++ ++ next_location_list = back ? back_list : forward_list; ++ ++ len = (guint) g_list_length (next_location_list); ++ ++ /* If we can't move in the direction at all, just return. */ ++ if (len == 0) ++ { ++ return; ++ } ++ ++ /* If the distance to move is off the end of the list, go to the end ++ * of the list. */ ++ if (distance >= len) ++ { ++ distance = len - 1; ++ } ++ ++ next_location_bookmark = g_list_nth_data (next_location_list, distance); ++ next_location = nautilus_bookmark_get_location (next_location_bookmark); ++ ++ active_slot_handles_location = nautilus_window_slot_handles_location (slot, next_location); ++ ++ if (!active_slot_handles_location) ++ { ++ NautilusNavigationState *navigation_state; ++ NautilusLocationChangeType location_change_type; ++ ++ navigation_state = nautilus_window_slot_get_navigation_state (slot); ++ ++ location_change_type = back ? NAUTILUS_LOCATION_CHANGE_BACK : NAUTILUS_LOCATION_CHANGE_FORWARD; ++ ++ slot = replace_active_slot (window, next_location, flags); ++ ++ nautilus_window_slot_open_location_set_navigation_state (slot, ++ next_location, flags, NULL, ++ location_change_type, ++ navigation_state, distance); ++ ++ free_navigation_state (navigation_state); ++ } ++ else ++ { ++ nautilus_window_slot_back_or_forward (slot, back, distance, flags); ++ } ++} +-- +2.35.1 + diff --git a/SPECS/nautilus.spec b/SPECS/nautilus.spec index 1eece52..6cef126 100644 --- a/SPECS/nautilus.spec +++ b/SPECS/nautilus.spec @@ -8,7 +8,7 @@ Name: nautilus Version: 3.28.1 -Release: 15%{?dist} +Release: 20%{?dist} Summary: File manager for GNOME License: GPLv3+ @@ -69,6 +69,21 @@ Patch33: search-engine-tracker-Expand-macro-as-string.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1906499 Patch34: nautilus-file.c-Fix-open-writable-file-in-recent-tab.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2068092 +Patch35: window-Streamline-RestoreTabData-memory-management.patch +Patch36: window-slot-Rename-RestoreTabData-to-NautilusNavigat.patch +Patch37: window-window-slot-Save-and-restore-navigation-histo.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=2068089 +Patch38: Add-actions-to-the-toolbar.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=2094431 +Patch39: files-view-Add-menu-item-to-copy-current-path.patch +Patch40: files-view-Backport-translations.patch + +# https://bugzilla.redhat.com/show_bug.cgi?id=2106241 +Patch41: nautilus-canvas-container-Remove-the-include-visible.patch + BuildRequires: gtk-doc BuildRequires: meson BuildRequires: gcc @@ -181,6 +196,21 @@ desktop-file-validate $RPM_BUILD_ROOT%{_datadir}/applications/*.desktop %{_datadir}/gir-1.0/*.gir %changelog +* Tue Aug 9 2022 Ondrej Holy - 3.28.1-20 +- Fix scrolling issues in the icon view on focus changes (#2106241) + +* Fri Jul 29 2022 Ondrej Holy - 3.28.1-19 +- Fix the "Copy Location" action to copy just the plain path (#2094431) + +* Mon Jun 20 2022 Ondrej Holy - 3.28.1-18 +- Add toolbar action to copy current location (#2094431) + +* Mon Jun 6 2022 Ondrej Holy - 3.28.1-17 +- Add actions to the toolbar (#2068089) + +* Wed Apr 13 2022 Ondrej Holy - 3.28.1-16 +- Save and restore navigation history when changing window slot (#2068092) + * Wed Jan 6 2021 Ondrej Holy - 3.28.1-15 - Fix activation_uri handling to prevent invalid bookmarks (rhbz#1906499)