Blame SOURCES/window-window-slot-Save-and-restore-navigation-histo.patch

6b1755
From fe7533b0b82e2ebc7767006ee9768572700a91df Mon Sep 17 00:00:00 2001
6b1755
From: Sachin Daluja <30343-sachindaluja@users.noreply.gitlab.gnome.org>
6b1755
Date: Sun, 10 May 2020 22:30:03 -0400
6b1755
Subject: [PATCH] window, window-slot: Save and restore navigation history
6b1755
6b1755
When a new window slot instance replaces the existing one to handle the new
6b1755
location.
6b1755
6b1755
This allows back and forward history lists to be preserved when the window
6b1755
switches between instances of different window slot classes.
6b1755
6b1755
Closes https://gitlab.gnome.org/GNOME/nautilus/-/issues/32
6b1755
---
6b1755
 src/nautilus-window-slot.c | 48 +++++++++++++++++++---
6b1755
 src/nautilus-window-slot.h | 13 ++++++
6b1755
 src/nautilus-window.c      | 84 +++++++++++++++++++++++++++++++++++++-
6b1755
 3 files changed, 138 insertions(+), 7 deletions(-)
6b1755
6b1755
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
6b1755
index e688f0716..69040fc44 100644
6b1755
--- a/src/nautilus-window-slot.c
6b1755
+++ b/src/nautilus-window-slot.c
6b1755
@@ -176,6 +176,9 @@ nautilus_window_slot_restore_navigation_state (NautilusWindowSlot      *self,
6b1755
 
6b1755
     priv = nautilus_window_slot_get_instance_private (self);
6b1755
 
6b1755
+    /* We are restoring saved history to newly created slot with no history. */
6b1755
+    g_warn_if_fail (priv->back_list == NULL && priv->forward_list == NULL);
6b1755
+
6b1755
     priv->back_list = g_steal_pointer (&data->back_list);
6b1755
 
6b1755
     priv->forward_list = g_steal_pointer (&data->forward_list);
6b1755
@@ -2003,12 +2006,11 @@ nautilus_window_slot_set_content_view (NautilusWindowSlot *self,
6b1755
 }
6b1755
 
6b1755
 void
6b1755
-nautilus_window_back_or_forward (NautilusWindow          *window,
6b1755
-                                 gboolean                 back,
6b1755
-                                 guint                    distance,
6b1755
-                                 NautilusWindowOpenFlags  flags)
6b1755
+nautilus_window_slot_back_or_forward (NautilusWindowSlot      *self,
6b1755
+                                      gboolean                 back,
6b1755
+                                      guint                    distance,
6b1755
+                                      NautilusWindowOpenFlags  flags)
6b1755
 {
6b1755
-    NautilusWindowSlot *self;
6b1755
     GList *list;
6b1755
     GFile *location;
6b1755
     guint len;
6b1755
@@ -2016,7 +2018,6 @@ nautilus_window_back_or_forward (NautilusWindow          *window,
6b1755
     GFile *old_location;
6b1755
     NautilusWindowSlotPrivate *priv;
6b1755
 
6b1755
-    self = nautilus_window_get_active_slot (window);
6b1755
     priv = nautilus_window_slot_get_instance_private (self);
6b1755
     list = back ? priv->back_list : priv->forward_list;
6b1755
 
6b1755
@@ -3308,3 +3309,38 @@ nautilus_window_slot_get_loading (NautilusWindowSlot *self)
6b1755
 
6b1755
     return priv->loading;
6b1755
 }
6b1755
+
6b1755
+/*
6b1755
+ * Open the specified location and set up the navigation history including the
6b1755
+ * back and forward lists. This function is intended to be called when switching
6b1755
+ * between NautilusWindowSlot and NautilusOtherLocationsWindowSlot. It allows
6b1755
+ * the navigation history accumulated in the slot being replaced to be loaded
6b1755
+ * into the replacing slot.
6b1755
+ *
6b1755
+ * The 'location' member variable is set to the new location before calling
6b1755
+ * begin_location_change() to ensure that it matches the
6b1755
+ * 'current_location_bookmark' member as expected by the location change
6b1755
+ * pipeline.
6b1755
+ */
6b1755
+void
6b1755
+nautilus_window_slot_open_location_set_navigation_state (NautilusWindowSlot         *self,
6b1755
+                                                         GFile                      *location,
6b1755
+                                                         NautilusWindowOpenFlags     flags,
6b1755
+                                                         GList                      *new_selection,
6b1755
+                                                         NautilusLocationChangeType  change_type,
6b1755
+                                                         NautilusNavigationState    *navigation_state,
6b1755
+                                                         guint                       distance)
6b1755
+{
6b1755
+    NautilusWindowSlotPrivate *priv;
6b1755
+
6b1755
+    priv = nautilus_window_slot_get_instance_private (self);
6b1755
+
6b1755
+    nautilus_window_slot_restore_navigation_state (self, navigation_state);
6b1755
+
6b1755
+    g_clear_object (&priv->location);
6b1755
+
6b1755
+    priv->location = nautilus_file_get_location (navigation_state->file);
6b1755
+
6b1755
+    begin_location_change (self, location, NULL, new_selection,
6b1755
+                           change_type, distance, NULL);
6b1755
+}
6b1755
diff --git a/src/nautilus-window-slot.h b/src/nautilus-window-slot.h
6b1755
index 2edc96786..cbd3454ce 100644
6b1755
--- a/src/nautilus-window-slot.h
6b1755
+++ b/src/nautilus-window-slot.h
6b1755
@@ -82,6 +82,14 @@ void nautilus_window_slot_open_location_full              (NautilusWindowSlot
6b1755
                                                            NautilusWindowOpenFlags  flags,
6b1755
                                                            GList                   *new_selection);
6b1755
 
6b1755
+void nautilus_window_slot_open_location_set_navigation_state (NautilusWindowSlot         *slot,
6b1755
+                                                              GFile                      *location,
6b1755
+                                                              NautilusWindowOpenFlags     flags,
6b1755
+                                                              GList                      *new_selection,
6b1755
+                                                              NautilusLocationChangeType  change_type,
6b1755
+                                                              NautilusNavigationState    *navigation_state,
6b1755
+                                                              guint                       distance);
6b1755
+
6b1755
 GFile * nautilus_window_slot_get_location		   (NautilusWindowSlot *slot);
6b1755
 
6b1755
 NautilusBookmark *nautilus_window_slot_get_bookmark        (NautilusWindowSlot *slot);
6b1755
@@ -126,5 +134,10 @@ NautilusNavigationState* nautilus_window_slot_get_navigation_state (NautilusWind
6b1755
 /* Only used by slot-dnd */
6b1755
 NautilusView*  nautilus_window_slot_get_current_view       (NautilusWindowSlot *slot);
6b1755
 
6b1755
+void nautilus_window_slot_back_or_forward                  (NautilusWindowSlot     *slot,
6b1755
+                                                            gboolean                back,
6b1755
+                                                            guint                   distance,
6b1755
+                                                            NautilusWindowOpenFlags flags);
6b1755
+
6b1755
 void free_navigation_state                                 (gpointer data);
6b1755
 #endif /* NAUTILUS_WINDOW_SLOT_H */
6b1755
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
6b1755
index 900239cb8..af01b43e7 100644
6b1755
--- a/src/nautilus-window.c
6b1755
+++ b/src/nautilus-window.c
6b1755
@@ -613,6 +613,7 @@ nautilus_window_open_location_full (NautilusWindow          *window,
6b1755
 {
6b1755
     NautilusWindowSlot *active_slot;
6b1755
     gboolean new_tab_at_end;
6b1755
+    NautilusNavigationState *navigation_state = NULL;
6b1755
 
6b1755
     /* The location owner can be one of the slots requesting to handle an
6b1755
      * unhandled location. But this slot can be destroyed when switching to
6b1755
@@ -644,6 +645,8 @@ nautilus_window_open_location_full (NautilusWindow          *window,
6b1755
     }
6b1755
     else if (!nautilus_window_slot_handles_location (target_slot, location))
6b1755
     {
6b1755
+        navigation_state = nautilus_window_slot_get_navigation_state (active_slot);
6b1755
+
6b1755
         target_slot = replace_active_slot (window, location, flags);
6b1755
     }
6b1755
 
6b1755
@@ -655,7 +658,19 @@ nautilus_window_open_location_full (NautilusWindow          *window,
6b1755
         nautilus_window_set_active_slot (window, target_slot);
6b1755
     }
6b1755
 
6b1755
-    nautilus_window_slot_open_location_full (target_slot, location, flags, selection);
6b1755
+    if (navigation_state != NULL)
6b1755
+    {
6b1755
+        nautilus_window_slot_open_location_set_navigation_state (target_slot,
6b1755
+                                                                 location, flags, selection,
6b1755
+                                                                 NAUTILUS_LOCATION_CHANGE_STANDARD,
6b1755
+                                                                 navigation_state, 0);
6b1755
+
6b1755
+        free_navigation_state (navigation_state);
6b1755
+    }
6b1755
+    else
6b1755
+    {
6b1755
+        nautilus_window_slot_open_location_full (target_slot, location, flags, selection);
6b1755
+    }
6b1755
 
6b1755
     g_object_unref (location);
6b1755
 }
6b1755
@@ -3099,3 +3114,70 @@ nautilus_window_search (NautilusWindow *window,
6b1755
         g_warning ("Trying search on a slot but no active slot present");
6b1755
     }
6b1755
 }
6b1755
+
6b1755
+/* Ideally, this method should be a simple wrapper for the slot method. However,
6b1755
+ * going back or forward can result in a new slot (or another subclass), so we
6b1755
+ * workaround that by duplicating part of nautilus_window_slot_back_or_forward()
6b1755
+ */
6b1755
+void
6b1755
+nautilus_window_back_or_forward (NautilusWindow          *window,
6b1755
+                                 gboolean                 back,
6b1755
+                                 guint                    distance,
6b1755
+                                 NautilusWindowOpenFlags  flags)
6b1755
+{
6b1755
+    NautilusWindowSlot *slot;
6b1755
+    GList *next_location_list, *back_list, *forward_list;
6b1755
+    GFile *next_location;
6b1755
+    guint len;
6b1755
+    NautilusBookmark *next_location_bookmark;
6b1755
+    gboolean active_slot_handles_location;
6b1755
+
6b1755
+    slot = nautilus_window_get_active_slot (window);
6b1755
+    back_list = nautilus_window_slot_get_back_history (slot);
6b1755
+    forward_list = nautilus_window_slot_get_forward_history (slot);
6b1755
+
6b1755
+    next_location_list = back ? back_list : forward_list;
6b1755
+
6b1755
+    len = (guint) g_list_length (next_location_list);
6b1755
+
6b1755
+    /* If we can't move in the direction at all, just return. */
6b1755
+    if (len == 0)
6b1755
+    {
6b1755
+        return;
6b1755
+    }
6b1755
+
6b1755
+    /* If the distance to move is off the end of the list, go to the end
6b1755
+     *  of the list. */
6b1755
+    if (distance >= len)
6b1755
+    {
6b1755
+        distance = len - 1;
6b1755
+    }
6b1755
+
6b1755
+    next_location_bookmark = g_list_nth_data (next_location_list, distance);
6b1755
+    next_location = nautilus_bookmark_get_location (next_location_bookmark);
6b1755
+
6b1755
+    active_slot_handles_location = nautilus_window_slot_handles_location (slot, next_location);
6b1755
+
6b1755
+    if (!active_slot_handles_location)
6b1755
+    {
6b1755
+        NautilusNavigationState *navigation_state;
6b1755
+        NautilusLocationChangeType location_change_type;
6b1755
+
6b1755
+        navigation_state = nautilus_window_slot_get_navigation_state (slot);
6b1755
+
6b1755
+        location_change_type = back ? NAUTILUS_LOCATION_CHANGE_BACK : NAUTILUS_LOCATION_CHANGE_FORWARD;
6b1755
+
6b1755
+        slot = replace_active_slot (window, next_location, flags);
6b1755
+
6b1755
+        nautilus_window_slot_open_location_set_navigation_state (slot,
6b1755
+                                                                 next_location, flags, NULL,
6b1755
+                                                                 location_change_type,
6b1755
+                                                                 navigation_state, distance);
6b1755
+
6b1755
+        free_navigation_state (navigation_state);
6b1755
+    }
6b1755
+    else
6b1755
+    {
6b1755
+        nautilus_window_slot_back_or_forward (slot, back, distance, flags);
6b1755
+    }
6b1755
+}
6b1755
-- 
6b1755
2.35.1
6b1755