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

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