You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
10 KiB
243 lines
10 KiB
2 years ago
|
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
|
||
|
|