diff --git a/gresources/nemo-file-management-properties.glade b/gresources/nemo-file-management-properties.glade
index 02b8e4cb4..7bb4fffbe 100644
--- a/gresources/nemo-file-management-properties.glade
+++ b/gresources/nemo-file-management-properties.glade
@@ -1256,6 +1256,23 @@ along with . If not, see .
3
+
+
+
+ False
+ False
+ 3
+ 4
+
+
diff --git a/libnemo-private/nemo-global-preferences.h b/libnemo-private/nemo-global-preferences.h
index 576a4616d..91f404854 100644
--- a/libnemo-private/nemo-global-preferences.h
+++ b/libnemo-private/nemo-global-preferences.h
@@ -122,6 +122,13 @@ typedef enum
#define NEMO_WINDOW_STATE_DEVICES_EXPANDED "devices-expanded"
#define NEMO_WINDOW_STATE_NETWORK_EXPANDED "network-expanded"
+/* Saved session (last closed window) */
+#define NEMO_WINDOW_STATE_SAVED_SPLIT_VIEW "saved-split-view"
+#define NEMO_WINDOW_STATE_SAVED_TABS_LEFT "saved-tabs-left"
+#define NEMO_WINDOW_STATE_SAVED_TABS_RIGHT "saved-tabs-right"
+#define NEMO_WINDOW_STATE_SAVED_ACTIVE_TAB_LEFT "saved-active-tab-left"
+#define NEMO_WINDOW_STATE_SAVED_ACTIVE_TAB_RIGHT "saved-active-tab-right"
+
/* Sorting order */
#define NEMO_PREFERENCES_SORT_DIRECTORIES_FIRST "sort-directories-first"
#define NEMO_PREFERENCES_SORT_FAVORITES_FIRST "sort-favorites-first"
@@ -137,6 +144,7 @@ typedef enum
#define NEMO_PREFERENCES_CLOSE_DEVICE_VIEW_ON_EJECT "close-device-view-on-device-eject"
#define NEMO_PREFERENCES_START_WITH_DUAL_PANE "start-with-dual-pane"
+#define NEMO_PREFERENCES_RESTORE_TABS_ON_STARTUP "restore-tabs-on-startup"
#define NEMO_PREFERENCES_IGNORE_VIEW_METADATA "ignore-view-metadata"
#define NEMO_PREFERENCES_SHOW_BOOKMARKS_IN_TO_MENUS "show-bookmarks-in-to-menus"
#define NEMO_PREFERENCES_SHOW_PLACES_IN_TO_MENUS "show-places-in-to-menus"
diff --git a/libnemo-private/org.nemo.gschema.xml b/libnemo-private/org.nemo.gschema.xml
index a43065d35..abc2814d4 100644
--- a/libnemo-private/org.nemo.gschema.xml
+++ b/libnemo-private/org.nemo.gschema.xml
@@ -346,6 +346,11 @@
Whether to default to showing dual-pane view when a new window is opened
If set to true, new Nemo windows will default to showing two panes
+
+ false
+ Restore the previous window tabs on startup
+ If set to true, Nemo will restore the last saved window tab state when launched without explicit locations.
+
false
Whether to ignore folder metadata for view zoom levels and layouts
@@ -702,6 +707,33 @@
Side pane view
The side pane view to show in newly opened windows.
+
+
+
+ false
+ Whether split view was enabled when the last window was closed
+ Internal setting used to restore the last closed window's split view and tabs.
+
+
+ []
+ Saved tab URIs for the left pane
+ Internal setting used to restore the last closed window's tabs for the left pane.
+
+
+ []
+ Saved tab URIs for the right pane
+ Internal setting used to restore the last closed window's tabs for the right pane.
+
+
+ 0
+ Index of the active tab in the left pane
+ Internal setting used to restore which tab was active in the left pane.
+
+
+ 0
+ Index of the active tab in the right pane
+ Internal setting used to restore which tab was active in the right pane.
+
diff --git a/src/nemo-application.c b/src/nemo-application.c
index 5366afb2e..38a8db767 100644
--- a/src/nemo-application.c
+++ b/src/nemo-application.c
@@ -534,6 +534,34 @@ nemo_application_quit (NemoApplication *self)
GList *windows;
windows = gtk_application_get_windows (GTK_APPLICATION (app));
+
+ /* Save session state once, before we destroy all windows.
+ * Save the last non-desktop window we find. */
+ {
+ NemoWindow *last_window = NULL;
+
+ for (GList *l = windows; l != NULL; l = l->next) {
+ GtkWindow *w = GTK_WINDOW (l->data);
+
+ if (!NEMO_IS_WINDOW (w)) {
+ continue;
+ }
+
+ NemoWindow *nw = NEMO_WINDOW (w);
+
+ /* Avoid saving the desktop window */
+ if (nw->details != NULL && nw->details->disable_chrome) {
+ continue;
+ }
+
+ last_window = nw;
+ }
+
+ if (last_window != NULL) {
+ nemo_window_save_session_state (last_window);
+ }
+ }
+
g_list_foreach (windows, (GFunc) gtk_widget_destroy, NULL);
/* we have been asked to force quit */
diff --git a/src/nemo-file-management-properties.c b/src/nemo-file-management-properties.c
index d0a1958e1..1566a467f 100644
--- a/src/nemo-file-management-properties.c
+++ b/src/nemo-file-management-properties.c
@@ -99,6 +99,7 @@
#define NEMO_FILE_MANAGEMENT_PROPERTIES_DETECT_CONTENT_MEDIA_WIDGET "media_detect_content_checkbutton"
#define NEMO_FILE_MANAGEMENT_PROPERTIES_SHOW_ADVANCED_PERMISSIONS_WIDGET "show_advanced_permissions_checkbutton"
#define NEMO_FILE_MANAGEMENT_PROPERTIES_START_WITH_DUAL_PANE_WIDGET "start_with_dual_pane_checkbutton"
+#define NEMO_FILE_MANAGEMENT_PROPERTIES_RESTORE_TABS_ON_STARTUP_WIDGET "restore_tabs_on_startup_checkbutton"
#define NEMO_FILE_MANAGEMENT_PROPERTIES_IGNORE_VIEW_METADATA_WIDGET "ignore_view_metadata_checkbutton"
#define NEMO_FILE_MANAGEMENT_PROPERTIES_BOOKMARKS_IN_TO_MENUS_WIDGET "bookmarks_in_to_checkbutton"
#define NEMO_FILE_MANAGEMENT_PROPERTIES_PLACES_IN_TO_MENUS_WIDGET "places_in_to_checkbutton"
@@ -1067,6 +1068,10 @@ nemo_file_management_properties_dialog_setup (GtkBuilder *builder,
NEMO_FILE_MANAGEMENT_PROPERTIES_START_WITH_DUAL_PANE_WIDGET,
NEMO_PREFERENCES_START_WITH_DUAL_PANE);
+ bind_builder_bool (builder, nemo_preferences,
+ NEMO_FILE_MANAGEMENT_PROPERTIES_RESTORE_TABS_ON_STARTUP_WIDGET,
+ NEMO_PREFERENCES_RESTORE_TABS_ON_STARTUP);
+
bind_builder_bool (builder, nemo_preferences,
NEMO_FILE_MANAGEMENT_PROPERTIES_IGNORE_VIEW_METADATA_WIDGET,
NEMO_PREFERENCES_IGNORE_VIEW_METADATA);
diff --git a/src/nemo-main-application.c b/src/nemo-main-application.c
index b0f42581a..4efe081bd 100644
--- a/src/nemo-main-application.c
+++ b/src/nemo-main-application.c
@@ -474,8 +474,34 @@ open_windows (NemoMainApplication *application,
gint i;
if (files == NULL || files[0] == NULL) {
- /* Open a window pointing at the default location. */
- open_window (application, NULL, screen, geometry);
+ /* No explicit locations requested: try restoring the last session. */
+ NemoWindow *window;
+ gboolean have_geometry;
+ gboolean do_restore;
+
+ window = nemo_main_application_create_window (NEMO_APPLICATION (application), screen);
+
+ have_geometry = geometry != NULL && strcmp (geometry, "") != 0;
+ if (have_geometry && !gtk_widget_get_visible (GTK_WIDGET (window))) {
+ /* never maximize windows opened from shell if a
+ * custom geometry has been requested.
+ */
+ gtk_window_unmaximize (GTK_WINDOW (window));
+ eel_gtk_window_set_initial_geometry_from_string (GTK_WINDOW (window),
+ geometry,
+ APPLICATION_WINDOW_MIN_WIDTH,
+ APPLICATION_WINDOW_MIN_HEIGHT,
+ FALSE);
+ }
+
+ do_restore = g_settings_get_boolean (nemo_preferences, NEMO_PREFERENCES_RESTORE_TABS_ON_STARTUP);
+
+ if (!do_restore || !nemo_window_restore_saved_tabs (window)) {
+ /* Fall back to a safe default location */
+ GFile *home = g_file_new_for_path (g_get_home_dir ());
+ nemo_window_go_to (window, home);
+ g_object_unref (home);
+ }
} else {
if (open_in_existing_window) {
/* Open one tab at each requested location in an existing window */
@@ -533,6 +559,7 @@ nemo_main_application_open (GApplication *app,
gboolean open_in_tabs = FALSE;
gchar *geometry = NULL;
gboolean open_in_existing_window = strcmp (options, "EXISTING_WINDOW") == 0;
+ gboolean default_no_args = FALSE;
const char splitter = '=';
g_debug ("Open called on the GApplication instance; %d files", n_files);
@@ -541,7 +568,12 @@ nemo_main_application_open (GApplication *app,
/* Check if local command line passed --geometry or --tabs */
if (strlen (options) > 0) {
gchar** split_options = g_strsplit (options, &splitter, 2);
- if (strcmp (split_options[0], "NULL") != 0) {
+ if (g_str_has_prefix (split_options[0], "DEFAULT")) {
+ default_no_args = TRUE;
+ if (g_str_has_prefix (split_options[0], "DEFAULT+")) {
+ geometry = g_strdup (split_options[0] + strlen ("DEFAULT+"));
+ }
+ } else if (strcmp (split_options[0], "NULL") != 0) {
geometry = g_strdup (split_options[0]);
}
sscanf (split_options[1], "%d", &open_in_tabs);
@@ -556,7 +588,13 @@ nemo_main_application_open (GApplication *app,
geometry ? geometry : "none",
open_in_existing_window ? "yes" : "no");
- open_windows (self, files, n_files, gdk_screen_get_default (), geometry, open_in_tabs, open_in_existing_window);
+ if (default_no_args) {
+ /* Treat this as a no-arg launch; open_windows() will attempt session restore
+ * and fall back to Home if restore isn't possible. */
+ open_windows (self, NULL, 0, gdk_screen_get_default (), geometry, open_in_tabs, open_in_existing_window);
+ } else {
+ open_windows (self, files, n_files, gdk_screen_get_default (), geometry, open_in_tabs, open_in_existing_window);
+ }
g_clear_pointer (&geometry, g_free);
}
@@ -798,9 +836,11 @@ nemo_main_application_local_command_line (GApplication *application,
GFile **files;
gint idx, len;
+ gboolean used_default_location;
len = 0;
files = NULL;
+ used_default_location = FALSE;
/* Convert args to GFiles */
if (remaining != NULL) {
@@ -822,32 +862,50 @@ nemo_main_application_local_command_line (GApplication *application,
}
if (files == NULL && !no_default_window) {
+ /* Original behavior: default to Home when no URIs are provided. */
files = g_malloc0 (2 * sizeof (GFile *));
len = 1;
files[0] = g_file_new_for_path (g_get_home_dir ());
files[1] = NULL;
+
+ /* Mark that this was a no-arg launch, not an explicit URI. */
+ used_default_location = TRUE;
}
- /* Invoke "Open" to open in existing window or create new windows */
+
+ /* Invoke "Open" to open in existing window or create new windows.
+ */
if (len > 0) {
gchar* concatOptions = g_malloc0(64);
if (open_in_existing_window) {
g_stpcpy (concatOptions, "EXISTING_WINDOW");
} else {
if (self->priv->geometry == NULL) {
- g_snprintf (concatOptions, 64, "NULL=%d", open_in_tabs);
+ /* If Home was synthesized because no URIs were passed, signal that
+ * to the primary instance so it can attempt session restore. */
+ if (used_default_location) {
+ g_snprintf (concatOptions, 64, "DEFAULT=%d", open_in_tabs);
+ } else {
+ g_snprintf (concatOptions, 64, "NULL=%d", open_in_tabs);
+ }
} else {
- g_snprintf (concatOptions, 64, "%s=%d", self->priv->geometry, open_in_tabs);
+ if (used_default_location) {
+ g_snprintf (concatOptions, 64, "DEFAULT+%s=%d", self->priv->geometry, open_in_tabs);
+ } else {
+ g_snprintf (concatOptions, 64, "%s=%d", self->priv->geometry, open_in_tabs);
+ }
}
}
g_application_open (application, files, len, concatOptions);
g_free (concatOptions);
}
- for (idx = 0; idx < len; idx++) {
- g_object_unref (files[idx]);
+ if (files != NULL) {
+ for (idx = 0; idx < len; idx++) {
+ g_object_unref (files[idx]);
+ }
+ g_free (files);
}
- g_free (files);
out:
g_option_context_free (context);
diff --git a/src/nemo-window-private.h b/src/nemo-window-private.h
index b8f8e0444..1f43e5f40 100644
--- a/src/nemo-window-private.h
+++ b/src/nemo-window-private.h
@@ -154,6 +154,9 @@ void nemo_window_set_active_pane (NemoWindow
NemoWindowPane *new_pane);
NemoWindowPane * nemo_window_get_active_pane (NemoWindow *window);
+gboolean nemo_window_restore_saved_tabs (NemoWindow *window);
+void nemo_window_save_session_state (NemoWindow *window);
+
/* sync window GUI with current slot. Used when changing slots,
* and when updating the slot state.
diff --git a/src/nemo-window.c b/src/nemo-window.c
index a9e502d72..c7956eb10 100644
--- a/src/nemo-window.c
+++ b/src/nemo-window.c
@@ -2025,11 +2025,309 @@ real_get_icon (NemoWindow *window,
NEMO_FILE_ICON_FLAGS_USE_MOUNT_ICON);
}
+static gboolean
+uri_is_native_session_uri (const char *uri)
+{
+ GFile *file;
+ gboolean is_native;
+
+ if (uri == NULL || uri[0] == '\0') {
+ return FALSE;
+ }
+
+ file = g_file_new_for_uri (uri);
+
+ /* skip searches and non-native locations for this simple session restore */
+ if (g_file_has_uri_scheme (file, "x-nemo-search")) {
+ g_object_unref (file);
+ return FALSE;
+ }
+
+ is_native = g_file_is_native (file);
+ g_object_unref (file);
+
+ return is_native;
+}
+
+static char **
+collect_pane_saved_tab_uris (NemoWindowPane *pane, gint *active_index_out)
+{
+ GtkNotebook *notebook;
+ int n_pages, i;
+ int current_page;
+ int saved_index = 0;
+ int saved_active_index = 0;
+ GPtrArray *arr;
+
+ if (active_index_out != NULL) {
+ *active_index_out = 0;
+ }
+
+ if (pane == NULL || pane->notebook == NULL) {
+ return g_new0 (char *, 1);
+ }
+
+ notebook = GTK_NOTEBOOK (pane->notebook);
+ n_pages = gtk_notebook_get_n_pages (notebook);
+ current_page = gtk_notebook_get_current_page (notebook);
+
+ arr = g_ptr_array_new_with_free_func (g_free);
+
+ for (i = 0; i < n_pages; i++) {
+ GtkWidget *page;
+ NemoWindowSlot *slot;
+ char *uri;
+
+ page = gtk_notebook_get_nth_page (notebook, i);
+ if (page == NULL) {
+ continue;
+ }
+
+ slot = NEMO_WINDOW_SLOT (page);
+ uri = nemo_window_slot_get_location_uri (slot);
+
+ if (uri_is_native_session_uri (uri)) {
+ if (i == current_page) {
+ saved_active_index = saved_index;
+ }
+ g_ptr_array_add (arr, uri);
+ saved_index++;
+ } else {
+ g_free (uri);
+ }
+ }
+
+ g_ptr_array_add (arr, NULL);
+
+ if (active_index_out != NULL) {
+ *active_index_out = saved_active_index;
+ }
+
+ return (char **) g_ptr_array_free (arr, FALSE);
+}
+
+void
+nemo_window_save_session_state (NemoWindow *window)
+{
+ NemoWindowPane *left_pane;
+ NemoWindowPane *right_pane;
+ char **left_uris;
+ char **right_uris;
+ gint left_active = 0;
+ gint right_active = 0;
+ gboolean split_view;
+ GtkPaned *paned;
+ GtkWidget *child1;
+ GtkWidget *child2;
+
+ g_return_if_fail (NEMO_IS_WINDOW (window));
+
+ /* Do not store session state for the desktop window */
+ if (nemo_window_is_desktop (window)) {
+ return;
+ }
+
+ paned = GTK_PANED (window->details->split_view_hpane);
+ child1 = gtk_paned_get_child1 (paned);
+ child2 = gtk_paned_get_child2 (paned);
+
+ left_pane = child1 != NULL ? NEMO_WINDOW_PANE (child1) : NULL;
+ right_pane = child2 != NULL ? NEMO_WINDOW_PANE (child2) : NULL;
+
+ left_uris = collect_pane_saved_tab_uris (left_pane, &left_active);
+ right_uris = collect_pane_saved_tab_uris (right_pane, &right_active);
+ split_view = (right_pane != NULL);
+
+ g_settings_set_boolean (nemo_window_state, NEMO_WINDOW_STATE_SAVED_SPLIT_VIEW, split_view);
+ g_settings_set_strv (nemo_window_state, NEMO_WINDOW_STATE_SAVED_TABS_LEFT, (const gchar * const *) left_uris);
+ g_settings_set_strv (nemo_window_state, NEMO_WINDOW_STATE_SAVED_TABS_RIGHT, (const gchar * const *) right_uris);
+ g_settings_set_int (nemo_window_state, NEMO_WINDOW_STATE_SAVED_ACTIVE_TAB_LEFT, left_active);
+ g_settings_set_int (nemo_window_state, NEMO_WINDOW_STATE_SAVED_ACTIVE_TAB_RIGHT, right_active);
+
+ g_strfreev (left_uris);
+ g_strfreev (right_uris);
+}
+
+static void
+clear_pane_to_single_slot (NemoWindowPane *pane)
+{
+ GtkNotebook *notebook;
+ int n_pages;
+
+ if (pane == NULL || pane->notebook == NULL) {
+ return;
+ }
+
+ notebook = GTK_NOTEBOOK (pane->notebook);
+ n_pages = gtk_notebook_get_n_pages (notebook);
+
+ /* Ensure there is a predictable active tab */
+ if (n_pages > 0) {
+ gtk_notebook_set_current_page (notebook, 0);
+ }
+
+ /* Close all tabs except the first one */
+ while (gtk_notebook_get_n_pages (notebook) > 1) {
+ GtkWidget *page;
+ NemoWindowSlot *slot;
+ int last = gtk_notebook_get_n_pages (notebook) - 1;
+
+ page = gtk_notebook_get_nth_page (notebook, last);
+ if (page == NULL) {
+ break;
+ }
+
+ slot = NEMO_WINDOW_SLOT (page);
+ nemo_window_pane_close_slot (pane, slot);
+ }
+}
+
+static void
+open_uri_list_in_pane (NemoWindowPane *pane, char **uris)
+{
+ int i;
+
+ if (pane == NULL) {
+ return;
+ }
+
+ /* If no URIs were saved for this pane, leave its first tab alone */
+ if (uris == NULL || uris[0] == NULL) {
+ return;
+ }
+
+ for (i = 0; uris[i] != NULL; i++) {
+ NemoWindowSlot *slot;
+ GFile *location;
+
+ if (!uri_is_native_session_uri (uris[i])) {
+ continue;
+ }
+
+ if (i == 0) {
+ /* Reuse the existing first tab */
+ slot = pane->active_slot;
+ if (slot == NULL && pane->notebook != NULL) {
+ GtkWidget *page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (pane->notebook), 0);
+ if (page != NULL) {
+ slot = NEMO_WINDOW_SLOT (page);
+ }
+ }
+ } else {
+ slot = nemo_window_pane_open_slot (pane, NEMO_WINDOW_OPEN_SLOT_APPEND);
+ }
+
+ if (slot == NULL) {
+ continue;
+ }
+
+ location = g_file_new_for_uri (uris[i]);
+ nemo_window_slot_open_location (slot, location, 0);
+ g_object_unref (location);
+ }
+}
+
+gboolean
+nemo_window_restore_saved_tabs (NemoWindow *window)
+{
+ NemoWindowPane *left_pane;
+ NemoWindowPane *right_pane;
+ char **left_uris;
+ char **right_uris;
+ gint left_active;
+ gint right_active;
+ gboolean want_split;
+ gboolean saved_split;
+
+ g_return_val_if_fail (NEMO_IS_WINDOW (window), FALSE);
+
+ /* Never restore tabs for the desktop window */
+ if (nemo_window_is_desktop (window)) {
+ return FALSE;
+ }
+
+ left_uris = g_settings_get_strv (nemo_window_state, NEMO_WINDOW_STATE_SAVED_TABS_LEFT);
+ right_uris = g_settings_get_strv (nemo_window_state, NEMO_WINDOW_STATE_SAVED_TABS_RIGHT);
+ left_active = g_settings_get_int (nemo_window_state, NEMO_WINDOW_STATE_SAVED_ACTIVE_TAB_LEFT);
+ right_active = g_settings_get_int (nemo_window_state, NEMO_WINDOW_STATE_SAVED_ACTIVE_TAB_RIGHT);
+ saved_split = g_settings_get_boolean (nemo_window_state, NEMO_WINDOW_STATE_SAVED_SPLIT_VIEW);
+
+ if ((left_uris == NULL || left_uris[0] == NULL) &&
+ (right_uris == NULL || right_uris[0] == NULL)) {
+ g_strfreev (left_uris);
+ g_strfreev (right_uris);
+ return FALSE;
+ }
+
+ /* Only create the extra pane if we actually have tabs to restore there */
+ want_split = saved_split && (right_uris != NULL && right_uris[0] != NULL);
+
+ if (want_split && !nemo_window_split_view_showing (window)) {
+ nemo_window_split_view_on (window);
+ } else if (!want_split && nemo_window_split_view_showing (window)) {
+ nemo_window_split_view_off (window);
+ }
+
+ {
+ GtkPaned *paned = GTK_PANED (window->details->split_view_hpane);
+ GtkWidget *child1 = gtk_paned_get_child1 (paned);
+ GtkWidget *child2 = gtk_paned_get_child2 (paned);
+
+ left_pane = child1 != NULL ? NEMO_WINDOW_PANE (child1) : NULL;
+ right_pane = (want_split && child2 != NULL) ? NEMO_WINDOW_PANE (child2) : NULL;
+ }
+
+ /* Reset panes to one tab each, then rebuild tabs in saved order */
+ clear_pane_to_single_slot (left_pane);
+ clear_pane_to_single_slot (right_pane);
+
+ /* If nothing saved for the left pane, open Home as a minimal fallback */
+ if (left_uris == NULL || left_uris[0] == NULL) {
+ GFile *home = g_file_new_for_path (g_get_home_dir ());
+ if (left_pane != NULL && left_pane->active_slot != NULL) {
+ nemo_window_slot_open_location (left_pane->active_slot, home, 0);
+ }
+ g_object_unref (home);
+ } else {
+ open_uri_list_in_pane (left_pane, left_uris);
+ }
+
+ open_uri_list_in_pane (right_pane, right_uris);
+
+ /* Restore active tabs (clamp indices) */
+ if (left_pane != NULL && left_pane->notebook != NULL) {
+ GtkNotebook *nb = GTK_NOTEBOOK (left_pane->notebook);
+ int n = gtk_notebook_get_n_pages (nb);
+ if (n > 0) {
+ gtk_notebook_set_current_page (nb, CLAMP (left_active, 0, n - 1));
+ }
+ }
+
+ if (right_pane != NULL && right_pane->notebook != NULL) {
+ GtkNotebook *nb = GTK_NOTEBOOK (right_pane->notebook);
+ int n = gtk_notebook_get_n_pages (nb);
+ if (n > 0) {
+ gtk_notebook_set_current_page (nb, CLAMP (right_active, 0, n - 1));
+ }
+ }
+
+ /* Make the left pane active for a predictable starting point */
+ if (left_pane != NULL) {
+ nemo_window_set_active_pane (window, left_pane);
+ }
+
+ g_strfreev (left_uris);
+ g_strfreev (right_uris);
+
+ return TRUE;
+}
+
static void
real_window_close (NemoWindow *window)
{
g_return_if_fail (NEMO_IS_WINDOW (window));
+ nemo_window_save_session_state (window);
nemo_window_save_geometry (window);
gtk_widget_destroy (GTK_WIDGET (window));