From 43c4cafd2b703f618b31417dfcc5c1fbb6be7f30 Mon Sep 17 00:00:00 2001 From: ebbes Date: Thu, 27 Sep 2012 14:28:30 +0200 Subject: [PATCH 1/3] Make tabs detachable and interchangable between windows --- src/nemo-notebook.c | 1 + src/nemo-window-pane.c | 104 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) diff --git a/src/nemo-notebook.c b/src/nemo-notebook.c index cb6ca3545..d6efe5e4c 100644 --- a/src/nemo-notebook.c +++ b/src/nemo-notebook.c @@ -405,6 +405,7 @@ nemo_notebook_insert_page (GtkNotebook *gnotebook, gtk_notebook_set_show_tabs (gnotebook, gtk_notebook_get_n_pages (gnotebook) > 1); gtk_notebook_set_tab_reorderable (gnotebook, tab_widget, TRUE); + gtk_notebook_set_tab_detachable (gnotebook, tab_widget, TRUE); return position; } diff --git a/src/nemo-window-pane.c b/src/nemo-window-pane.c index 873b3b6e4..62168f985 100644 --- a/src/nemo-window-pane.c +++ b/src/nemo-window-pane.c @@ -29,6 +29,7 @@ #include "nemo-window-pane.h" #include "nemo-actions.h" +#include "nemo-application.h" #include "nemo-location-bar.h" #include "nemo-notebook.h" #include "nemo-pathbar.h" @@ -612,6 +613,99 @@ notebook_switch_page_cb (GtkNotebook *notebook, return FALSE; } +static void +notebook_page_removed_cb (GtkNotebook *notebook, + GtkWidget *page, + guint page_num, + gpointer user_data) +{ + NemoWindowPane *pane = user_data; + NemoWindowSlot *slot = NEMO_WINDOW_SLOT (page), *next_slot; + gboolean dnd_slot; + + dnd_slot = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (slot), "dnd-window-slot")); + if (!dnd_slot) { + return; + } + + if (pane->active_slot == slot) { + next_slot = get_first_inactive_slot (pane); + nemo_window_set_active_slot (pane->window, next_slot); + } +} + +static void +notebook_page_added_cb (GtkNotebook *notebook, + GtkWidget *page, + guint page_num, + gpointer user_data) +{ + NemoWindowPane *pane; + NemoWindowSlot *slot; + NemoWindowSlot *dummy_slot; + gboolean dnd_slot; + + pane = NEMO_WINDOW_PANE (user_data); + slot = NEMO_WINDOW_SLOT (page); + + //Slot has been dropped onto another pane (window or tab bar of other window) + //So reassociate the pane if needed. + if (slot->pane != pane) { + slot->pane->slots = g_list_remove (slot->pane->slots, slot); + slot->pane = pane; + pane->slots = g_list_append (pane->slots, slot); + nemo_window_set_active_slot (pane->window, slot); + } + + dnd_slot = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (slot), "dnd-window-slot")); + + //Slot does not come from dnd window creation. + if (!dnd_slot) { + return; + } + + g_object_set_data (G_OBJECT (page), "dnd-window-slot", + GINT_TO_POINTER (FALSE)); + + dummy_slot = g_list_nth_data (pane->slots, 0); + if (dummy_slot != NULL) { + nemo_window_pane_close_slot (dummy_slot->pane, dummy_slot); + } + + gtk_widget_show (GTK_WIDGET (pane)); + gtk_widget_show (GTK_WIDGET (pane->window)); +} + +static GtkNotebook * +notebook_create_window_cb (GtkNotebook *notebook, + GtkWidget *page, + gint x, + gint y, + gpointer user_data) +{ + NemoApplication *app; + NemoWindow *new_window; + NemoWindowPane *new_pane; + NemoWindowSlot *slot; + + if (!NEMO_IS_WINDOW_SLOT (page)) { + return NULL; + } + + app = NEMO_APPLICATION (g_application_get_default ()); + new_window = nemo_application_create_window + (app, gtk_widget_get_screen (GTK_WIDGET (notebook))); + + slot = NEMO_WINDOW_SLOT (page); + g_object_set_data (G_OBJECT (slot), "dnd-window-slot", + GINT_TO_POINTER (TRUE)); + + gtk_window_set_position (GTK_WINDOW (new_window), GTK_WIN_POS_MOUSE); + + new_pane = nemo_window_get_active_pane (new_window); + return GTK_NOTEBOOK (new_pane->notebook); +} + static void action_show_hide_search_callback (GtkAction *action, gpointer user_data) @@ -820,9 +914,19 @@ nemo_window_pane_constructed (GObject *obj) "switch-page", G_CALLBACK (notebook_switch_page_cb), pane); + g_signal_connect (pane->notebook, "create-window", + G_CALLBACK (notebook_create_window_cb), + pane); + g_signal_connect (pane->notebook, "page-added", + G_CALLBACK (notebook_page_added_cb), + pane); + g_signal_connect (pane->notebook, "page-removed", + G_CALLBACK (notebook_page_removed_cb), + pane); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (pane->notebook), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (pane->notebook), FALSE); + gtk_notebook_set_group_name (GTK_NOTEBOOK (pane->notebook), "nemo-slots"); gtk_widget_show (pane->notebook); gtk_container_set_border_width (GTK_CONTAINER (pane->notebook), 0); From 38f08aecf1a67ec1efeeed961e052fc19096715c Mon Sep 17 00:00:00 2001 From: ebbes Date: Thu, 27 Sep 2012 18:08:58 +0200 Subject: [PATCH 2/3] Fixed fatal crash when navigating in detached views --- src/nemo-view.c | 19 +++++++++++++++++++ src/nemo-window-pane.c | 9 +++++---- src/nemo-window-slot.c | 10 ++++++++++ src/nemo-window-slot.h | 5 +++-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/nemo-view.c b/src/nemo-view.c index 64b1b8de4..d9acbb434 100644 --- a/src/nemo-view.c +++ b/src/nemo-view.c @@ -2343,6 +2343,22 @@ slot_inactive (NemoWindowSlot *slot, remove_update_menus_timeout_callback (view); } +static void slot_changed_pane (NemoWindowSlot *slot, + NemoView *view) +{ + g_signal_handlers_disconnect_matched (view->details->window, + G_SIGNAL_MATCH_DATA, 0, 0, + NULL, NULL, view); + + view->details->window = nemo_window_slot_get_window (slot); + schedule_update_menus (view); + + g_signal_connect_object (view->details->window, + "hidden-files-mode-changed", G_CALLBACK (hidden_files_mode_changed), + view, 0); + hidden_files_mode_changed (view->details->window, view); +} + void nemo_view_grab_focus (NemoView *view) { @@ -9539,6 +9555,9 @@ nemo_view_set_property (GObject *object, g_signal_connect_object (directory_view->details->slot, "inactive", G_CALLBACK (slot_inactive), directory_view, 0); + g_signal_connect_object (directory_view->details->slot, + "changed-pane", G_CALLBACK (slot_changed_pane), + directory_view, 0); g_signal_connect_object (directory_view->details->window, "hidden-files-mode-changed", G_CALLBACK (hidden_files_mode_changed), diff --git a/src/nemo-window-pane.c b/src/nemo-window-pane.c index 62168f985..2ab9bfc15 100644 --- a/src/nemo-window-pane.c +++ b/src/nemo-window-pane.c @@ -648,19 +648,20 @@ notebook_page_added_cb (GtkNotebook *notebook, pane = NEMO_WINDOW_PANE (user_data); slot = NEMO_WINDOW_SLOT (page); - //Slot has been dropped onto another pane (window or tab bar of other window) + //Slot has been dropped onto another pane (new window or tab bar of other window) //So reassociate the pane if needed. if (slot->pane != pane) { slot->pane->slots = g_list_remove (slot->pane->slots, slot); slot->pane = pane; pane->slots = g_list_append (pane->slots, slot); - nemo_window_set_active_slot (pane->window, slot); + g_signal_emit_by_name (slot, "changed-pane"); + nemo_window_set_active_slot (nemo_window_slot_get_window (slot), slot); } dnd_slot = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (slot), "dnd-window-slot")); - - //Slot does not come from dnd window creation. + if (!dnd_slot) { + //Slot does not come from dnd window creation. return; } diff --git a/src/nemo-window-slot.c b/src/nemo-window-slot.c index 7820b3f35..24c358d19 100644 --- a/src/nemo-window-slot.c +++ b/src/nemo-window-slot.c @@ -41,6 +41,7 @@ G_DEFINE_TYPE (NemoWindowSlot, nemo_window_slot, GTK_TYPE_BOX); enum { ACTIVE, INACTIVE, + CHANGED_PANE, LAST_SIGNAL }; @@ -296,6 +297,15 @@ nemo_window_slot_class_init (NemoWindowSlotClass *klass) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + signals[CHANGED_PANE] = + g_signal_new ("changed-pane", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (NemoWindowSlotClass, changed_pane), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } GFile * diff --git a/src/nemo-window-slot.h b/src/nemo-window-slot.h index 6126ecb15..8fc4aabdc 100644 --- a/src/nemo-window-slot.h +++ b/src/nemo-window-slot.h @@ -47,8 +47,9 @@ struct NemoWindowSlotClass { GtkBoxClass parent_class; /* wrapped NemoWindowInfo signals, for overloading */ - void (* active) (NemoWindowSlot *slot); - void (* inactive) (NemoWindowSlot *slot); + void (* active) (NemoWindowSlot *slot); + void (* inactive) (NemoWindowSlot *slot); + void (* changed_pane) (NemoWindowSlot *slot); }; /* Each NemoWindowSlot corresponds to From 04fc27aa4047478326b553468e613a3cb5b92b11 Mon Sep 17 00:00:00 2001 From: ebbes Date: Thu, 27 Sep 2012 21:34:12 +0200 Subject: [PATCH 3/3] Add slot close to page_removed_cb --- src/nemo-window-pane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/nemo-window-pane.c b/src/nemo-window-pane.c index 2ab9bfc15..758b2eaed 100644 --- a/src/nemo-window-pane.c +++ b/src/nemo-window-pane.c @@ -632,6 +632,9 @@ notebook_page_removed_cb (GtkNotebook *notebook, next_slot = get_first_inactive_slot (pane); nemo_window_set_active_slot (pane->window, next_slot); } + + nemo_window_manage_views_close_slot (slot); + pane->slots = g_list_remove (pane->slots, slot); } static void