summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Mikhaylenko <alexm@gnome.org>2020-09-09 02:46:32 +0500
committerAntónio Fernandes <antoniof@gnome.org>2022-07-30 20:23:15 +0000
commitc279180a9268e3b6d3749affb27917778b3a7b47 (patch)
treeb65bc77b670368c0b255b1aa0ebd34db698b5073
parenta931fdd53a16a013f9f6c4a33c6087e13ddb3c75 (diff)
downloadnautilus-c279180a9268e3b6d3749affb27917778b3a7b47.tar.gz
window: Port to AdwTabView and AdwTabBar
They are better fit than GtkNotebook for our use cases and provide more features and better visuals. Also, they include DND support for switching tabs on hover. There is a small regression: files can no longer be dropped in the tab itself; this is because on one hand the AdwTabBar extra drop API is too limiting for our needs (it lacks a means to check the value before drop to pick a preferred action), and on the other hand our new DND code is too new and our needs might change, so we shouldn't be asking for more API yet. With this we also reenable detachable tabs. Closes https://gitlab.gnome.org/GNOME/nautilus/-/issues/615 (Rebased and amended by António Fernandes and Christopher Davis)
-rw-r--r--src/meson.build2
-rw-r--r--src/nautilus-notebook.c439
-rw-r--r--src/nautilus-notebook.h59
-rw-r--r--src/nautilus-window-slot-dnd.c38
-rw-r--r--src/nautilus-window-slot.c11
-rw-r--r--src/nautilus-window.c350
-rw-r--r--src/nautilus-window.h2
-rw-r--r--src/resources/ui/nautilus-window.ui18
8 files changed, 183 insertions, 736 deletions
diff --git a/src/meson.build b/src/meson.build
index 2772ab6be..a0c92c92b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -101,8 +101,6 @@ libnautilus_sources = [
'nautilus-mime-actions.h',
'nautilus-name-cell.c',
'nautilus-name-cell.h',
- 'nautilus-notebook.c',
- 'nautilus-notebook.h',
'nautilus-pathbar.c',
'nautilus-pathbar.h',
'nautilus-places-view.c',
diff --git a/src/nautilus-notebook.c b/src/nautilus-notebook.c
deleted file mode 100644
index 9713b545b..000000000
--- a/src/nautilus-notebook.c
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Copyright © 2002 Christophe Fergeau
- * Copyright © 2003, 2004 Marco Pesenti Gritti
- * Copyright © 2003, 2004, 2005 Christian Persch
- * (ephy-notebook.c)
- *
- * Copyright © 2008 Free Software Foundation, Inc.
- * (nautilus-notebook.c)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "config.h"
-
-#include "nautilus-notebook.h"
-
-#include "nautilus-window.h"
-#include "nautilus-window-slot.h"
-#include "nautilus-window-slot-dnd.h"
-
-#include <eel/eel-vfs-extensions.h>
-#include <glib/gi18n.h>
-#include <gio/gio.h>
-#include <gtk/gtk.h>
-
-#define AFTER_ALL_TABS -1
-
-static GtkWidget *
-find_tab_at_pos (GtkNotebook *notebook,
- gdouble abs_x,
- gdouble abs_y,
- gint *tab_num)
-{
- int page_num = 0;
- GtkWidget *page;
- GtkAllocation allocation;
-
- *tab_num = AFTER_ALL_TABS;
-
- while ((page = gtk_notebook_get_nth_page (notebook, page_num)))
- {
- GtkWidget *tab;
- gdouble tab_x, tab_y;
-
- tab = gtk_notebook_get_tab_label (notebook, page);
- g_return_val_if_fail (tab != NULL, NULL);
-
- if (!gtk_widget_get_mapped (GTK_WIDGET (tab)))
- {
- page_num++;
- continue;
- }
-
- gtk_widget_get_allocation (tab, &allocation);
- gtk_widget_translate_coordinates (GTK_WIDGET (notebook), tab,
- abs_x, abs_y, &tab_x, &tab_y);
-
- if (tab_x >= allocation.x && tab_x <= allocation.x + allocation.width &&
- tab_y >= allocation.y && tab_y <= allocation.y + allocation.height)
- {
- *tab_num = page_num;
- return tab;
- }
-
- page_num++;
- }
- return NULL;
-}
-
-static void
-on_page_removed (GtkNotebook *notebook,
- GtkWidget *child,
- guint page_num,
- gpointer user_data)
-{
- gtk_notebook_set_show_tabs (notebook,
- gtk_notebook_get_n_pages (notebook) > 1);
-}
-
-static void
-on_page_added (GtkNotebook *notebook,
- GtkWidget *child,
- guint page_num,
- gpointer user_data)
-{
- gtk_notebook_set_show_tabs (notebook,
- gtk_notebook_get_n_pages (notebook) > 1);
- gtk_notebook_set_tab_reorderable (notebook, child, TRUE);
- gtk_notebook_set_tab_detachable (notebook, child, TRUE);
-}
-
-void
-nautilus_notebook_setup (GtkNotebook *notebook)
-{
- gtk_notebook_set_scrollable (notebook, TRUE);
- gtk_notebook_set_show_border (notebook, FALSE);
- gtk_notebook_set_show_tabs (notebook, FALSE);
-
- g_signal_connect (notebook, "page-removed", G_CALLBACK (on_page_removed), NULL);
- g_signal_connect (notebook, "page-added", G_CALLBACK (on_page_added), NULL);
-}
-
-gboolean
-nautilus_notebook_contains_slot (GtkNotebook *notebook,
- NautilusWindowSlot *slot)
-{
- GtkWidget *child;
- gint n_pages;
- gboolean found = FALSE;
-
- g_return_val_if_fail (slot != NULL, FALSE);
-
- n_pages = gtk_notebook_get_n_pages (notebook);
- for (gint i = 0; i < n_pages; i++)
- {
- child = gtk_notebook_get_nth_page (notebook, i);
- if ((gpointer) child == (gpointer) slot)
- {
- found = TRUE;
- break;
- }
- }
-
- return found;
-}
-
-GtkWidget *
-nautilus_notebook_get_tab_clicked (GtkNotebook *notebook,
- gdouble x,
- gdouble y,
- gint *position)
-{
- GtkWidget *tab;
- gint tab_num;
-
- tab = find_tab_at_pos (notebook, x, y, &tab_num);
-
- if (position != NULL)
- {
- *position = tab_num;
- }
- return tab;
-}
-
-void
-nautilus_notebook_sync_loading (GtkNotebook *notebook,
- NautilusWindowSlot *slot)
-{
- GtkWidget *tab_label, *spinner, *icon;
- gboolean active, allow_stop;
-
- g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
- g_return_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot));
-
- tab_label = gtk_notebook_get_tab_label (notebook,
- GTK_WIDGET (slot));
- g_return_if_fail (GTK_IS_WIDGET (tab_label));
-
- spinner = GTK_WIDGET (g_object_get_data (G_OBJECT (tab_label), "spinner"));
- icon = GTK_WIDGET (g_object_get_data (G_OBJECT (tab_label), "icon"));
- g_return_if_fail (spinner != NULL && icon != NULL);
-
- active = FALSE;
- g_object_get (spinner, "spinning", &active, NULL);
- allow_stop = nautilus_window_slot_get_allow_stop (slot);
-
- if (active == allow_stop)
- {
- return;
- }
-
- if (allow_stop)
- {
- gtk_widget_hide (icon);
- gtk_widget_show (spinner);
- gtk_spinner_start (GTK_SPINNER (spinner));
- }
- else
- {
- gtk_spinner_stop (GTK_SPINNER (spinner));
- gtk_widget_hide (spinner);
- gtk_widget_show (icon);
- }
-}
-
-void
-nautilus_notebook_sync_tab_label (GtkNotebook *notebook,
- NautilusWindowSlot *slot)
-{
- GtkWidget *cbox, *label;
- char *location_name;
- GFile *location;
- const gchar *title_name;
-
- g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
- g_return_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot));
-
- cbox = gtk_notebook_get_tab_label (notebook, GTK_WIDGET (slot));
- g_return_if_fail (GTK_IS_WIDGET (cbox));
-
- label = GTK_WIDGET (g_object_get_data (G_OBJECT (cbox), "label"));
- g_return_if_fail (GTK_IS_WIDGET (label));
-
- gtk_label_set_text (GTK_LABEL (label), nautilus_window_slot_get_title (slot));
- location = nautilus_window_slot_get_location (slot);
-
- if (location != NULL)
- {
- /* Set the tooltip on the label's parent (the tab label cbox),
- * so it covers all of the tab label.
- */
- location_name = g_file_get_parse_name (location);
- title_name = nautilus_window_slot_get_title (slot);
- if (eel_uri_is_search (location_name))
- {
- gtk_widget_set_tooltip_text (gtk_widget_get_parent (label), title_name);
- }
- else
- {
- gtk_widget_set_tooltip_text (gtk_widget_get_parent (label), location_name);
- }
- g_free (location_name);
- }
- else
- {
- gtk_widget_set_tooltip_text (gtk_widget_get_parent (label), NULL);
- }
-}
-
-static GtkWidget *
-build_tab_label (GtkNotebook *notebook,
- NautilusWindowSlot *slot)
-{
- GtkWidget *tab_label;
- GtkWidget *start_box;
- GtkWidget *label;
- GtkWidget *close_button;
- GtkWidget *spinner;
- GtkWidget *icon;
-
- tab_label = gtk_center_box_new ();
- gtk_widget_show (tab_label);
-
- start_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
- gtk_center_box_set_start_widget (GTK_CENTER_BOX (tab_label), start_box);
-
- /* Spinner to be shown as load feedback */
- spinner = gtk_spinner_new ();
- gtk_box_append (GTK_BOX (start_box), spinner);
-
- /* Dummy icon to allocate space for spinner */
- icon = gtk_image_new ();
- gtk_box_append (GTK_BOX (start_box), icon);
- /* don't show the icon */
-
- /* Tab title */
- label = gtk_label_new (NULL);
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
- gtk_label_set_single_line_mode (GTK_LABEL (label), TRUE);
- gtk_label_set_width_chars (GTK_LABEL (label), 6);
- gtk_center_box_set_center_widget (GTK_CENTER_BOX (tab_label), label);
- gtk_widget_show (label);
-
- /* Tab close button */
- close_button = gtk_button_new_from_icon_name ("window-close-symbolic");
- gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (close_button)),
- "flat");
- /* don't allow focus on the close button */
- gtk_widget_set_focus_on_click (close_button, FALSE);
-
- gtk_widget_set_name (close_button, "nautilus-tab-close-button");
-
- gtk_widget_set_tooltip_text (close_button, _("Close tab"));
- gtk_actionable_set_action_name (GTK_ACTIONABLE (close_button), "win.close-current-view");
-
- gtk_center_box_set_end_widget (GTK_CENTER_BOX (tab_label), close_button);
- gtk_widget_show (close_button);
-
- g_object_set_data (G_OBJECT (tab_label), "nautilus-notebook-tab", GINT_TO_POINTER (1));
- nautilus_drag_slot_proxy_init (tab_label, NULL, slot);
-
- g_object_set_data (G_OBJECT (tab_label), "label", label);
- g_object_set_data (G_OBJECT (tab_label), "spinner", spinner);
- g_object_set_data (G_OBJECT (tab_label), "icon", icon);
- g_object_set_data (G_OBJECT (tab_label), "close-button", close_button);
-
- return tab_label;
-}
-
-int
-nautilus_notebook_add_tab (GtkNotebook *notebook,
- NautilusWindowSlot *slot,
- int position,
- gboolean jump_to)
-{
- GtkWidget *tab_label;
-
- g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), -1);
- g_return_val_if_fail (NAUTILUS_IS_WINDOW_SLOT (slot), -1);
-
- tab_label = build_tab_label (notebook, slot);
-
- position = gtk_notebook_insert_page (notebook,
- GTK_WIDGET (slot),
- tab_label,
- position);
-
- g_object_set (gtk_notebook_get_page (GTK_NOTEBOOK (notebook),
- GTK_WIDGET (slot)),
- "tab-expand", TRUE,
- "detachable", FALSE,
- NULL);
-
- nautilus_notebook_sync_tab_label (notebook, slot);
- nautilus_notebook_sync_loading (notebook, slot);
-
- if (jump_to)
- {
- gtk_notebook_set_current_page (notebook, position);
- }
-
- return position;
-}
-
-void
-nautilus_notebook_reorder_current_child_relative (GtkNotebook *notebook,
- int offset)
-{
- GtkWidget *child;
- int page;
-
- g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-
- if (!nautilus_notebook_can_reorder_current_child_relative (notebook, offset))
- {
- return;
- }
-
- page = gtk_notebook_get_current_page (notebook);
- child = gtk_notebook_get_nth_page (notebook, page);
- gtk_notebook_reorder_child (notebook, child, page + offset);
-}
-
-static gboolean
-nautilus_notebook_is_valid_relative_position (GtkNotebook *notebook,
- int offset)
-{
- int page;
- int n_pages;
-
- page = gtk_notebook_get_current_page (notebook);
- n_pages = gtk_notebook_get_n_pages (notebook) - 1;
- if (page < 0 ||
- (offset < 0 && page < -offset) ||
- (offset > 0 && page > n_pages - offset))
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-gboolean
-nautilus_notebook_can_reorder_current_child_relative (GtkNotebook *notebook,
- int offset)
-{
- g_return_val_if_fail (GTK_IS_NOTEBOOK (notebook), FALSE);
-
- return nautilus_notebook_is_valid_relative_position (notebook, offset);
-}
-
-void
-nautilus_notebook_next_page (GtkNotebook *notebook)
-{
- gint current_page, n_pages;
-
- g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-
- current_page = gtk_notebook_get_current_page (notebook);
- n_pages = gtk_notebook_get_n_pages (notebook);
-
- if (current_page < n_pages - 1)
- {
- gtk_notebook_next_page (notebook);
- }
- else
- {
- gboolean wrap_around;
-
- g_object_get (gtk_widget_get_settings (GTK_WIDGET (notebook)),
- "gtk-keynav-wrap-around", &wrap_around,
- NULL);
-
- if (wrap_around)
- {
- gtk_notebook_set_current_page (notebook, 0);
- }
- }
-}
-
-void
-nautilus_notebook_prev_page (GtkNotebook *notebook)
-{
- gint current_page;
-
- g_return_if_fail (GTK_IS_NOTEBOOK (notebook));
-
- current_page = gtk_notebook_get_current_page (notebook);
-
- if (current_page > 0)
- {
- gtk_notebook_prev_page (notebook);
- }
- else
- {
- gboolean wrap_around;
-
- g_object_get (gtk_widget_get_settings (GTK_WIDGET (notebook)),
- "gtk-keynav-wrap-around", &wrap_around,
- NULL);
-
- if (wrap_around)
- {
- gtk_notebook_set_current_page (notebook, -1);
- }
- }
-}
diff --git a/src/nautilus-notebook.h b/src/nautilus-notebook.h
deleted file mode 100644
index 7851ee7ae..000000000
--- a/src/nautilus-notebook.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright © 2002 Christophe Fergeau
- * Copyright © 2003 Marco Pesenti Gritti
- * Copyright © 2003, 2004 Christian Persch
- * (ephy-notebook.c)
- *
- * Copyright © 2008 Free Software Foundation, Inc.
- * (nautilus-notebook.c)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#pragma once
-
-#include <glib.h>
-#include <gtk/gtk.h>
-
-#include "nautilus-window-slot.h"
-
-G_BEGIN_DECLS
-
-int nautilus_notebook_add_tab (GtkNotebook *nb,
- NautilusWindowSlot *slot,
- int position,
- gboolean jump_to);
-
-void nautilus_notebook_sync_tab_label (GtkNotebook *nb,
- NautilusWindowSlot *slot);
-void nautilus_notebook_sync_loading (GtkNotebook *nb,
- NautilusWindowSlot *slot);
-
-void nautilus_notebook_reorder_current_child_relative (GtkNotebook *notebook,
- int offset);
-gboolean nautilus_notebook_can_reorder_current_child_relative (GtkNotebook *notebook,
- int offset);
-void nautilus_notebook_prev_page (GtkNotebook *notebook);
-void nautilus_notebook_next_page (GtkNotebook *notebook);
-
-gboolean nautilus_notebook_contains_slot (GtkNotebook *notebook,
- NautilusWindowSlot *slot);
-
-GtkWidget * nautilus_notebook_get_tab_clicked (GtkNotebook *notebook,
- gdouble x,
- gdouble y,
- gint *position);
-void nautilus_notebook_setup (GtkNotebook *notebook);
-G_END_DECLS
diff --git a/src/nautilus-window-slot-dnd.c b/src/nautilus-window-slot-dnd.c
index 71aa458c9..1c1839737 100644
--- a/src/nautilus-window-slot-dnd.c
+++ b/src/nautilus-window-slot-dnd.c
@@ -25,7 +25,6 @@
#include <config.h>
-#include "nautilus-notebook.h"
#include "nautilus-application.h"
#include "nautilus-files-view-dnd.h"
#include "nautilus-window-slot-dnd.h"
@@ -36,36 +35,10 @@ typedef struct
NautilusWindowSlot *target_slot;
GtkWidget *widget;
- gboolean is_notebook;
guint switch_location_timer;
} NautilusDragSlotProxyInfo;
static void
-switch_tab (NautilusDragSlotProxyInfo *drag_info)
-{
- GtkWidget *notebook, *slot;
- gint idx, n_pages;
-
- if (drag_info->target_slot == NULL)
- {
- return;
- }
-
- notebook = gtk_widget_get_ancestor (GTK_WIDGET (drag_info->target_slot), GTK_TYPE_NOTEBOOK);
- n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook));
-
- for (idx = 0; idx < n_pages; idx++)
- {
- slot = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), idx);
- if (NAUTILUS_WINDOW_SLOT (slot) == drag_info->target_slot)
- {
- gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), idx);
- break;
- }
- }
-}
-
-static void
switch_location (NautilusDragSlotProxyInfo *drag_info)
{
GFile *location;
@@ -93,14 +66,7 @@ slot_proxy_switch_location_timer (gpointer user_data)
drag_info->switch_location_timer = 0;
- if (drag_info->is_notebook)
- {
- switch_tab (drag_info);
- }
- else
- {
- switch_location (drag_info);
- }
+ switch_location (drag_info);
return FALSE;
}
@@ -327,8 +293,6 @@ nautilus_drag_slot_proxy_init (GtkWidget *widget,
g_object_set_data_full (G_OBJECT (widget), "drag-slot-proxy-data", drag_info,
drag_info_free);
- drag_info->is_notebook = (g_object_get_data (G_OBJECT (widget), "nautilus-notebook-tab") != NULL);
-
if (target_file != NULL)
{
drag_info->target_file = nautilus_file_ref (target_file);
diff --git a/src/nautilus-window-slot.c b/src/nautilus-window-slot.c
index a0bb238a7..40fd5260f 100644
--- a/src/nautilus-window-slot.c
+++ b/src/nautilus-window-slot.c
@@ -3392,14 +3392,15 @@ nautilus_window_slot_set_active (NautilusWindowSlot *self,
if (active)
{
- int page_num;
+ AdwTabView *tab_view;
+ AdwTabPage *page;
window = self->window;
- page_num = gtk_notebook_page_num (GTK_NOTEBOOK (nautilus_window_get_notebook (window)),
- GTK_WIDGET (self));
- g_assert (page_num >= 0);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (nautilus_window_get_notebook (window)), page_num);
+ tab_view = nautilus_window_get_tab_view (window);
+ page = adw_tab_view_get_page (tab_view, GTK_WIDGET (self));
+
+ adw_tab_view_set_selected_page (tab_view, page);
/* sync window to new slot */
nautilus_window_sync_allow_stop (window, self);
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index ee81470fb..0acd81a56 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -61,7 +61,6 @@
#include "nautilus-metadata.h"
#include "nautilus-mime-actions.h"
#include "nautilus-module.h"
-#include "nautilus-notebook.h"
#include "nautilus-pathbar.h"
#include "nautilus-profile.h"
#include "nautilus-signaller.h"
@@ -97,7 +96,8 @@ struct _NautilusWindow
{
AdwApplicationWindow parent_instance;
- GtkWidget *notebook;
+ AdwTabView *tab_view;
+ AdwTabPage *menu_page;
GList *slots;
NautilusWindowSlot *active_slot; /* weak reference */
@@ -125,8 +125,6 @@ struct _NautilusWindow
guint sidebar_width_handler_id;
gulong bookmarks_id;
- GtkWidget *tab_menu;
-
GQueue *tab_data_queue;
};
@@ -156,13 +154,15 @@ action_close_current_view (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
- NautilusWindow *window;
- NautilusWindowSlot *slot;
+ NautilusWindow *window = user_data;
+ AdwTabPage *page = window->menu_page;
- window = NAUTILUS_WINDOW (user_data);
- slot = nautilus_window_get_active_slot (window);
+ if (page == NULL)
+ {
+ page = adw_tab_view_get_selected_page (window->tab_view);
+ }
- nautilus_window_slot_close (window, slot);
+ adw_tab_view_close_page (window->tab_view, page);
}
static void
@@ -315,33 +315,19 @@ action_enter_location (GSimpleAction *action,
}
static void
-action_tab_previous (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusWindow *window = user_data;
-
- nautilus_notebook_prev_page (GTK_NOTEBOOK (window->notebook));
-}
-
-static void
-action_tab_next (GSimpleAction *action,
- GVariant *state,
- gpointer user_data)
-{
- NautilusWindow *window = user_data;
-
- nautilus_notebook_next_page (GTK_NOTEBOOK (window->notebook));
-}
-
-static void
action_tab_move_left (GSimpleAction *action,
GVariant *state,
gpointer user_data)
{
NautilusWindow *window = user_data;
+ AdwTabPage *page = window->menu_page;
+
+ if (page == NULL)
+ {
+ page = adw_tab_view_get_selected_page (window->tab_view);
+ }
- nautilus_notebook_reorder_current_child_relative (GTK_NOTEBOOK (window->notebook), -1);
+ adw_tab_view_reorder_backward (window->tab_view, page);
}
static void
@@ -350,8 +336,14 @@ action_tab_move_right (GSimpleAction *action,
gpointer user_data)
{
NautilusWindow *window = user_data;
+ AdwTabPage *page = window->menu_page;
- nautilus_notebook_reorder_current_child_relative (GTK_NOTEBOOK (window->notebook), 1);
+ if (page == NULL)
+ {
+ page = adw_tab_view_get_selected_page (window->tab_view);
+ }
+
+ adw_tab_view_reorder_forward (window->tab_view, page);
}
static void
@@ -360,15 +352,14 @@ action_go_to_tab (GSimpleAction *action,
gpointer user_data)
{
NautilusWindow *window = NAUTILUS_WINDOW (user_data);
- GtkNotebook *notebook;
gint16 num;
- notebook = GTK_NOTEBOOK (window->notebook);
-
num = g_variant_get_int32 (value);
- if (num < gtk_notebook_get_n_pages (notebook))
+ if (num < adw_tab_view_get_n_pages (window->tab_view))
{
- gtk_notebook_set_current_page (notebook, num);
+ AdwTabPage *page = adw_tab_view_get_nth_page (window->tab_view, num);
+
+ adw_tab_view_set_selected_page (window->tab_view, page);
}
}
@@ -479,15 +470,45 @@ on_slot_location_changed (NautilusWindowSlot *slot,
}
static void
-notebook_switch_page_cb (GtkNotebook *notebook,
- GtkWidget *page,
- unsigned int page_num,
- NautilusWindow *window)
+tab_view_setup_menu_cb (AdwTabView *tab_view,
+ AdwTabPage *page,
+ NautilusWindow *window)
{
+ GAction *move_tab_left_action;
+ GAction *move_tab_right_action;
+ int position, n_pages;
+
+ if (page != NULL)
+ {
+ position = adw_tab_view_get_page_position (tab_view, page);
+ n_pages = adw_tab_view_get_n_pages (tab_view);
+ }
+
+ move_tab_left_action = g_action_map_lookup_action (G_ACTION_MAP (window),
+ "tab-move-left");
+ move_tab_right_action = g_action_map_lookup_action (G_ACTION_MAP (window),
+ "tab-move-right");
+
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (move_tab_left_action),
+ page == NULL || position > 0);
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (move_tab_right_action),
+ page == NULL || position < n_pages - 1);
+
+ window->menu_page = page;
+}
+
+static void
+tab_view_notify_selected_page_cb (AdwTabView *tab_view,
+ GParamSpec *pspec,
+ NautilusWindow *window)
+{
+ AdwTabPage *page;
NautilusWindowSlot *slot;
GtkWidget *widget;
- widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), page_num);
+ page = adw_tab_view_get_selected_page (tab_view);
+ widget = adw_tab_page_get_child (page);
+
g_assert (widget != NULL);
/* find slot corresponding to the target page */
@@ -525,26 +546,63 @@ nautilus_window_create_and_init_slot (NautilusWindow *window,
return slot;
}
+static gboolean
+location_to_tooltip (GBinding *binding,
+ const GValue *input,
+ GValue *output,
+ NautilusWindowSlot *slot)
+{
+ GFile *location = g_value_get_object (input);
+ g_autofree gchar *location_name = NULL;
+
+ if (location == NULL)
+ {
+ return TRUE;
+ }
+
+ /* Set the tooltip on the label's parent (the tab label hbox),
+ * so it covers all of the tab label.
+ */
+ location_name = g_file_get_parse_name (location);
+
+ if (eel_uri_is_search (location_name))
+ {
+ g_value_set_string (output, nautilus_window_slot_get_title (slot));
+ }
+ else
+ {
+ g_value_set_string (output, location_name);
+ }
+
+ return TRUE;
+}
+
void
nautilus_window_initialize_slot (NautilusWindow *window,
NautilusWindowSlot *slot,
NautilusOpenFlags flags)
{
+ AdwTabPage *page, *current;
+
g_assert (NAUTILUS_IS_WINDOW (window));
g_assert (NAUTILUS_IS_WINDOW_SLOT (slot));
connect_slot (window, slot);
- g_signal_handlers_block_by_func (window->notebook,
- G_CALLBACK (notebook_switch_page_cb),
- window);
- nautilus_notebook_add_tab (GTK_NOTEBOOK (window->notebook),
- slot,
- -1,
- FALSE);
- g_signal_handlers_unblock_by_func (window->notebook,
- G_CALLBACK (notebook_switch_page_cb),
- window);
+ current = adw_tab_view_get_selected_page (window->tab_view);
+ page = adw_tab_view_add_page (window->tab_view, GTK_WIDGET (slot), current);
+
+ g_object_bind_property (slot, "allow-stop",
+ page, "loading",
+ G_BINDING_SYNC_CREATE);
+ g_object_bind_property (slot, "title",
+ page, "title",
+ G_BINDING_SYNC_CREATE);
+ g_object_bind_property_full (slot, "location",
+ page, "tooltip",
+ G_BINDING_SYNC_CREATE,
+ (GBindingTransformFunc) location_to_tooltip,
+ NULL, slot, NULL);
}
void
@@ -751,22 +809,15 @@ nautilus_window_sync_allow_stop (NautilusWindow *window,
{
update_cursor (window);
}
-
- /* Avoid updating the notebook if we are calling on dispose or
- * on removal of a notebook tab */
- if (nautilus_notebook_contains_slot (GTK_NOTEBOOK (window->notebook), slot))
- {
- nautilus_notebook_sync_loading (GTK_NOTEBOOK (window->notebook), slot);
- }
}
}
-GtkWidget *
-nautilus_window_get_notebook (NautilusWindow *window)
+AdwTabView *
+nautilus_window_get_tab_view (NautilusWindow *window)
{
g_return_val_if_fail (NAUTILUS_IS_WINDOW (window), NULL);
- return window->notebook;
+ return window->tab_view;
}
/* Callback used when the places sidebar changes location; we need to change the displayed folder */
@@ -989,8 +1040,7 @@ nautilus_window_slot_close (NautilusWindow *window,
NautilusWindowSlot *slot)
{
NautilusNavigationState *data;
- GtkNotebook *notebook = GTK_NOTEBOOK (window->notebook);
- int page_num;
+ AdwTabPage *page;
DEBUG ("Requesting to remove slot %p from window %p", slot, window);
if (window == NULL || slot == NULL)
@@ -1006,10 +1056,9 @@ nautilus_window_slot_close (NautilusWindow *window,
remove_slot_from_window (slot, window);
- page_num = gtk_notebook_page_num (notebook, GTK_WIDGET (slot));
- g_assert (page_num >= 0);
+ page = adw_tab_view_get_page (window->tab_view, GTK_WIDGET (slot));
/* this will destroy the slot */
- gtk_notebook_remove_page (notebook, page_num);
+ adw_tab_view_close_page (window->tab_view, page);
/* If that was the last slot in the window, close the window. */
if (window->slots == NULL)
@@ -1272,70 +1321,6 @@ on_path_bar_open_location (NautilusWindow *window,
}
}
-static void
-notebook_popup_menu_show (NautilusWindow *window,
- GtkWidget *tab)
-{
- GtkPopover *popover = GTK_POPOVER (window->tab_menu);
- GtkAllocation allocation;
- gdouble x, y;
-
- gtk_widget_get_allocation (tab, &allocation);
- gtk_widget_translate_coordinates (tab, GTK_WIDGET (window),
- allocation.x, allocation.y, &x, &y);
- allocation.x = x;
- allocation.y = y;
- gtk_popover_set_pointing_to (popover, (GdkRectangle *) &allocation);
- gtk_popover_popup (popover);
-}
-
-static void
-notebook_button_press_cb (GtkGestureClick *gesture,
- gint n_press,
- gdouble x,
- gdouble y,
- gpointer user_data)
-{
- NautilusWindow *window;
- GtkNotebook *notebook;
- gint tab_clicked;
- GtkWidget *tab_widget;
- guint button;
- GdkModifierType state;
-
- if (n_press != 1)
- {
- return;
- }
-
- window = NAUTILUS_WINDOW (user_data);
- notebook = GTK_NOTEBOOK (window->notebook);
-
- tab_widget = nautilus_notebook_get_tab_clicked (notebook, x, y, &tab_clicked);
- if (tab_widget == NULL)
- {
- return;
- }
-
- button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
- state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (gesture));
-
- if (button == GDK_BUTTON_SECONDARY &&
- (state & gtk_accelerator_get_default_mod_mask ()) == 0)
- {
- /* switch to the page before opening the menu */
- gtk_notebook_set_current_page (notebook, tab_clicked);
- notebook_popup_menu_show (window, tab_widget);
- }
- else if (button == GDK_BUTTON_MIDDLE)
- {
- GtkWidget *slot;
-
- slot = gtk_notebook_get_nth_page (notebook, tab_clicked);
- nautilus_window_slot_close (window, NAUTILUS_WINDOW_SLOT (slot));
- }
-}
-
GtkWidget *
nautilus_window_get_toolbar (NautilusWindow *window)
{
@@ -1368,14 +1353,27 @@ setup_toolbar (NautilusWindow *window)
G_CALLBACK (location_entry_cancel_callback), window, 0);
}
+static gboolean
+tab_view_close_page_cb (AdwTabView *view,
+ AdwTabPage *page,
+ NautilusWindow *window)
+{
+ NautilusWindowSlot *slot;
+
+ slot = NAUTILUS_WINDOW_SLOT (adw_tab_page_get_child (page));
+
+ nautilus_window_slot_close (window, slot);
+
+ return GDK_EVENT_PROPAGATE;
+}
+
static void
-notebook_page_removed_cb (GtkNotebook *notebook,
- GtkWidget *page,
- guint page_num,
- gpointer user_data)
+tab_view_page_detached_cb (AdwTabView *tab_view,
+ AdwTabPage *page,
+ gint position,
+ NautilusWindow *window)
{
- NautilusWindow *window = user_data;
- NautilusWindowSlot *slot = NAUTILUS_WINDOW_SLOT (page);
+ NautilusWindowSlot *slot = NAUTILUS_WINDOW_SLOT (adw_tab_page_get_child (page));
/* If the tab has been moved to another window, we need to remove the slot
* from the current window here. Otherwise, if the tab has been closed, then
@@ -1387,66 +1385,56 @@ notebook_page_removed_cb (GtkNotebook *notebook,
}
static void
-notebook_page_added_cb (GtkNotebook *notebook,
- GtkWidget *page,
- guint page_num,
- gpointer user_data)
+tab_view_page_attached_cb (AdwTabView *tab_view,
+ AdwTabPage *page,
+ gint position,
+ NautilusWindow *window)
{
- NautilusWindow *window = user_data;
- NautilusWindowSlot *slot = NAUTILUS_WINDOW_SLOT (page);
+ NautilusWindowSlot *slot = NAUTILUS_WINDOW_SLOT (adw_tab_page_get_child (page));
nautilus_window_slot_set_window (slot, window);
window->slots = g_list_append (window->slots, slot);
g_signal_emit (window, signals[SLOT_ADDED], 0, slot);
}
-static GtkNotebook *
-notebook_create_window_cb (GtkNotebook *notebook,
- GtkWidget *page,
- gint x,
- gint y,
- gpointer user_data)
+static AdwTabView *
+tab_view_create_window_cb (AdwTabView *tab_view,
+ NautilusWindow *window)
{
NautilusApplication *app;
NautilusWindow *new_window;
- if (!NAUTILUS_IS_WINDOW_SLOT (page))
- {
- return NULL;
- }
-
app = NAUTILUS_APPLICATION (g_application_get_default ());
new_window = nautilus_application_create_window (app);
gtk_window_set_display (GTK_WINDOW (new_window),
- gtk_widget_get_display (GTK_WIDGET (notebook)));
+ gtk_widget_get_display (GTK_WIDGET (tab_view)));
- return GTK_NOTEBOOK (new_window->notebook);
+ gtk_window_present (GTK_WINDOW (new_window));
+
+ return new_window->tab_view;
}
static void
-setup_notebook (NautilusWindow *window)
+setup_tab_view (NautilusWindow *window)
{
- GtkEventController *controller;
-
- g_signal_connect (window->notebook, "switch-page",
- G_CALLBACK (notebook_switch_page_cb),
+ g_signal_connect (window->tab_view, "close-page",
+ G_CALLBACK (tab_view_close_page_cb),
window);
- g_signal_connect (window->notebook, "create-window",
- G_CALLBACK (notebook_create_window_cb),
+ g_signal_connect (window->tab_view, "setup-menu",
+ G_CALLBACK (tab_view_setup_menu_cb),
window);
- g_signal_connect (window->notebook, "page-added",
- G_CALLBACK (notebook_page_added_cb),
+ g_signal_connect (window->tab_view, "notify::selected-page",
+ G_CALLBACK (tab_view_notify_selected_page_cb),
window);
- g_signal_connect (window->notebook, "page-removed",
- G_CALLBACK (notebook_page_removed_cb),
+ g_signal_connect (window->tab_view, "create-window",
+ G_CALLBACK (tab_view_create_window_cb),
+ window);
+ g_signal_connect (window->tab_view, "page-attached",
+ G_CALLBACK (tab_view_page_attached_cb),
+ window);
+ g_signal_connect (window->tab_view, "page-detached",
+ G_CALLBACK (tab_view_page_detached_cb),
window);
-
- controller = GTK_EVENT_CONTROLLER (gtk_gesture_click_new ());
- gtk_widget_add_controller (GTK_WIDGET (window->notebook), controller);
- gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
- gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (controller), 0);
- g_signal_connect (controller, "pressed",
- G_CALLBACK (notebook_button_press_cb), window);
}
const GActionEntry win_entries[] =
@@ -1470,8 +1458,6 @@ const GActionEntry win_entries[] =
{ "close-current-view", action_close_current_view },
{ "go-home", action_go_home },
{ "go-starred", action_go_starred },
- { "tab-previous", action_tab_previous },
- { "tab-next", action_tab_next },
{ "tab-move-left", action_tab_move_left },
{ "tab-move-right", action_tab_move_right },
{ "prompt-root-location", action_prompt_for_location_root },
@@ -1514,8 +1500,6 @@ nautilus_window_initialize_actions (NautilusWindow *window)
nautilus_application_set_accelerator (app, "win.up", "<alt>Up");
nautilus_application_set_accelerators (app, "win.go-home", ACCELS ("<alt>Home", "HomePage", "Start"));
nautilus_application_set_accelerator (app, "win.go-starred", "Favorites");
- nautilus_application_set_accelerator (app, "win.tab-previous", "<control>Page_Up");
- nautilus_application_set_accelerator (app, "win.tab-next", "<control>Page_Down");
nautilus_application_set_accelerator (app, "win.tab-move-left", "<shift><control>Page_Up");
nautilus_application_set_accelerator (app, "win.tab-move-right", "<shift><control>Page_Down");
nautilus_application_set_accelerators (app, "win.prompt-root-location", ACCELS ("slash", "KP_Divide"));
@@ -1562,7 +1546,7 @@ nautilus_window_constructed (GObject *self)
NAUTILUS_WINDOW_DEFAULT_WIDTH,
NAUTILUS_WINDOW_DEFAULT_HEIGHT);
- setup_notebook (window);
+ setup_tab_view (window);
nautilus_window_set_up_sidebar (window);
@@ -1595,8 +1579,6 @@ nautilus_window_dispose (GObject *object)
DEBUG ("Destroying window");
- g_clear_pointer (&window->tab_menu, gtk_widget_unparent);
-
/* close all slots safely */
slots_copy = g_list_copy (window->slots);
g_list_foreach (slots_copy, (GFunc) remove_slot_from_window, window);
@@ -1781,8 +1763,6 @@ nautilus_window_sync_title (NautilusWindow *window,
{
gtk_window_set_title (GTK_WINDOW (window), nautilus_window_slot_get_title (slot));
}
-
- nautilus_notebook_sync_tab_label (GTK_NOTEBOOK (window->notebook), slot);
}
#ifdef GDK_WINDOWING_WAYLAND
@@ -2065,7 +2045,6 @@ nautilus_window_init (NautilusWindow *window)
g_type_ensure (NAUTILUS_TYPE_TOOLBAR);
g_type_ensure (NAUTILUS_TYPE_GTK_PLACES_SIDEBAR);
gtk_widget_init_template (GTK_WIDGET (window));
- nautilus_notebook_setup (GTK_NOTEBOOK (window->notebook));
g_signal_connect_object (window->places_sidebar,
"show-other-locations-with-flags",
@@ -2078,8 +2057,6 @@ nautilus_window_init (NautilusWindow *window)
window,
G_CONNECT_SWAPPED);
- gtk_widget_set_parent (window->tab_menu, GTK_WIDGET (window));
-
g_signal_connect (window, "notify::is-maximized",
G_CALLBACK (on_is_maximized_changed), NULL);
@@ -2143,9 +2120,8 @@ nautilus_window_class_init (NautilusWindowClass *class)
gtk_widget_class_bind_template_child (wclass, NautilusWindow, toolbar);
gtk_widget_class_bind_template_child (wclass, NautilusWindow, content_flap);
gtk_widget_class_bind_template_child (wclass, NautilusWindow, places_sidebar);
- gtk_widget_class_bind_template_child (wclass, NautilusWindow, notebook);
- gtk_widget_class_bind_template_child (wclass, NautilusWindow, tab_menu);
gtk_widget_class_bind_template_child (wclass, NautilusWindow, toast_overlay);
+ gtk_widget_class_bind_template_child (wclass, NautilusWindow, tab_view);
signals[SLOT_ADDED] =
g_signal_new ("slot-added",
diff --git a/src/nautilus-window.h b/src/nautilus-window.h
index 71bf490e3..2f7add9b0 100644
--- a/src/nautilus-window.h
+++ b/src/nautilus-window.h
@@ -85,7 +85,7 @@ void nautilus_window_sync_location_widgets (NautilusWindow *wind
void nautilus_window_reset_menus (NautilusWindow *window);
-GtkWidget * nautilus_window_get_notebook (NautilusWindow *window);
+AdwTabView * nautilus_window_get_tab_view (NautilusWindow *window);
void nautilus_window_show_about_dialog (NautilusWindow *window);
diff --git a/src/resources/ui/nautilus-window.ui b/src/resources/ui/nautilus-window.ui
index dd9048f81..7d5d21b3f 100644
--- a/src/resources/ui/nautilus-window.ui
+++ b/src/resources/ui/nautilus-window.ui
@@ -25,9 +25,6 @@
</item>
</section>
</menu>
- <object class="GtkPopoverMenu" id="tab_menu">
- <property name="menu-model">tab_menu_model</property>
- </object>
<template class="NautilusWindow" parent="AdwApplicationWindow">
<property name="show-menubar">False</property>
<property name="title" translatable="yes">_Files</property>
@@ -59,10 +56,19 @@
<object class="GtkSeparator"/>
</child>
<child>
- <object class="GtkNotebook" id="notebook">
- <property name="show-tabs">False</property>
- <property name="show-border">False</property>
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
<property name="width-request">360</property>
+ <child>
+ <object class="AdwTabBar">
+ <property name="view">tab_view</property>
+ </object>
+ </child>
+ <child>
+ <object class="AdwTabView" id="tab_view">
+ <property name="menu-model">tab_menu_model</property>
+ </object>
+ </child>
</object>
</child>
</object>