[Xfce4-commits] r26427 - in terminal/trunk: . terminal

Benedikt Meurer benny at xfce.org
Sun Dec 2 15:21:23 CET 2007


Author: benny
Date: 2007-12-02 14:21:23 +0000 (Sun, 02 Dec 2007)
New Revision: 26427

Modified:
   terminal/trunk/ChangeLog
   terminal/trunk/NEWS
   terminal/trunk/configure.in.in
   terminal/trunk/terminal/terminal-app.c
   terminal/trunk/terminal/terminal-marshal.list
   terminal/trunk/terminal/terminal-screen.c
   terminal/trunk/terminal/terminal-tab-header.c
   terminal/trunk/terminal/terminal-tab-header.h
   terminal/trunk/terminal/terminal-widget.c
   terminal/trunk/terminal/terminal-window.c
   terminal/trunk/terminal/terminal-window.h
Log:
2007-12-02	Benedikt Meurer <benny at xfce.org>

	* configure.in.in: Post-release version bump.
	* terminal/: Re-apply patch from Nick Schermer <nick at xfce.org> to
	  enable Drag and Drop for tabs between Terminal windows.
	  Bug #2684.
	* configure.in.in: Bump GTK+ requirement to 2.10 to avoid
	  the lot of potentially buggy #ifdef's.
	* NEWS: Update NEWS.




Modified: terminal/trunk/ChangeLog
===================================================================
--- terminal/trunk/ChangeLog	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/ChangeLog	2007-12-02 14:21:23 UTC (rev 26427)
@@ -1,5 +1,15 @@
 2007-12-02	Benedikt Meurer <benny at xfce.org>
 
+	* configure.in.in: Post-release version bump.
+	* terminal/: Re-apply patch from Nick Schermer <nick at xfce.org> to
+	  enable Drag and Drop for tabs between Terminal windows.
+	  Bug #2684.
+	* configure.in.in: Bump GTK+ requirement to 2.10 to avoid
+	  the lot of potentially buggy #ifdef's.
+	* NEWS: Update NEWS.
+
+2007-12-02	Benedikt Meurer <benny at xfce.org>
+
 	* === Released 0.2.8 ===
 	* NEWS, configure.in.in: Bump version.
 	* configure.in.in: Depend on libexo 0.3.4.

Modified: terminal/trunk/NEWS
===================================================================
--- terminal/trunk/NEWS	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/NEWS	2007-12-02 14:21:23 UTC (rev 26427)
@@ -1,3 +1,10 @@
+0.2.9svn
+========
+- Support for Drag and Drop of tabs between Terminal windows was added
+  (Bug #2684).
+- The required version of GTK+ is now 2.10.
+
+
 0.2.8
 =====
 - Close tabs with middle mouse click (Bug #3380).

Modified: terminal/trunk/configure.in.in
===================================================================
--- terminal/trunk/configure.in.in	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/configure.in.in	2007-12-02 14:21:23 UTC (rev 26427)
@@ -11,10 +11,10 @@
 dnl ***************************
 m4_define([terminal_version_major], [0])
 m4_define([terminal_version_minor], [2])
-m4_define([terminal_version_micro], [8])
+m4_define([terminal_version_micro], [9])
 m4_define([terminal_version_nano], [])
 m4_define([terminal_version_build], [@REVISION@])
-m4_define([terminal_version_tag], [])
+m4_define([terminal_version_tag], [svn])
 m4_define([terminal_version_dbus], [3])
 m4_define([terminal_version], [terminal_version_major().terminal_version_minor().terminal_version_micro()ifelse(terminal_version_nano(), [], [], [.terminal_version_nano()])ifelse(terminal_version_tag(), [svn], [terminal_version_tag()-terminal_version_build()], [terminal_version_tag()])])
 
@@ -82,7 +82,7 @@
 dnl *** Check for required packages ***
 dnl ***********************************
 XDT_CHECK_PACKAGE([EXO], [exo-0.3], [0.3.4])
-XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.6.0])
+XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.10.0])
 XDT_CHECK_PACKAGE([VTE], [vte], [0.11.11])
 
 dnl *************************************************

Modified: terminal/trunk/terminal/terminal-app.c
===================================================================
--- terminal/trunk/terminal/terminal-app.c	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-app.c	2007-12-02 14:21:23 UTC (rev 26427)
@@ -60,6 +60,8 @@
                                                                  TerminalApp        *app);
 static void               terminal_app_new_window_with_terminal (TerminalWindow     *window,
                                                                  TerminalScreen     *terminal,
+                                                                 gint                x,
+                                                                 gint                y,
                                                                  TerminalApp        *app);
 static void               terminal_app_window_destroyed         (GtkWidget          *window,
                                                                  TerminalApp        *app);
@@ -253,16 +255,26 @@
 static void
 terminal_app_new_window_with_terminal (TerminalWindow *existing,
                                        TerminalScreen *terminal,
+                                       gint            x,
+                                       gint            y,
                                        TerminalApp    *app)
 {
   GtkWidget *window;
   GdkScreen *screen;
+  
+  _terminal_return_if_fail (TERMINAL_IS_WINDOW (existing));
+  _terminal_return_if_fail (TERMINAL_IS_SCREEN (terminal));
+  _terminal_return_if_fail (TERMINAL_IS_APP (app));
 
   window = terminal_app_create_window (app, FALSE,
                                        TERMINAL_VISIBILITY_DEFAULT,
                                        TERMINAL_VISIBILITY_DEFAULT,
                                        TERMINAL_VISIBILITY_DEFAULT);
 
+  /* set new window position */
+  if (x > -1 && y > -1)
+    gtk_window_move (GTK_WINDOW (window), x, y);
+
   /* place the new window on the same screen as
    * the existing window.
    */
@@ -347,9 +359,7 @@
 terminal_app_find_screen (const gchar *display_name)
 {
   const gchar *other_name;
-#if GTK_CHECK_VERSION(2,10,0)
   GdkColormap *colormap;
-#endif
   GdkDisplay  *display = NULL;
   GdkScreen   *screen = NULL;
   GSList      *displays;
@@ -410,7 +420,6 @@
       g_object_ref (G_OBJECT (screen));
     }
 
-#if GTK_CHECK_VERSION(2,10,0)
   /* check if we already checked this screen */
   if (g_object_get_data (G_OBJECT (screen), "terminal-checked-screen") == NULL)
     {
@@ -427,7 +436,6 @@
       /* mark this screen as handled */
       g_object_set_data (G_OBJECT (screen), I_("terminal-checked-screen"), GINT_TO_POINTER (1));
     }
-#endif
 
   return screen;
 }

Modified: terminal/trunk/terminal/terminal-marshal.list
===================================================================
--- terminal/trunk/terminal/terminal-marshal.list	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-marshal.list	2007-12-02 14:21:23 UTC (rev 26427)
@@ -1,2 +1,3 @@
 OBJECT:VOID
 VOID:STRING,ENUM
+VOID:OBJECT,INT,INT

Modified: terminal/trunk/terminal/terminal-screen.c
===================================================================
--- terminal/trunk/terminal/terminal-screen.c	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-screen.c	2007-12-02 14:21:23 UTC (rev 26427)
@@ -373,7 +373,7 @@
 static void
 terminal_screen_realize (GtkWidget *widget)
 {
-#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY)
+#ifdef HAVE_VTE_TERMINAL_SET_OPACITY
   GdkScreen *screen;
 #endif
 
@@ -383,7 +383,7 @@
   if (!GTK_WIDGET_REALIZED (TERMINAL_SCREEN (widget)->terminal))
     gtk_widget_realize (TERMINAL_SCREEN (widget)->terminal);
 
-#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY)
+#ifdef HAVE_VTE_TERMINAL_SET_OPACITY
   /* connect to the "composited-changed" signal */
   screen = gtk_widget_get_screen (widget);
   g_signal_connect_swapped (G_OBJECT (screen), "composited-changed", G_CALLBACK (terminal_screen_update_background), widget);
@@ -395,7 +395,7 @@
 static void
 terminal_screen_unrealize (GtkWidget *widget)
 {
-#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY)
+#ifdef HAVE_VTE_TERMINAL_SET_OPACITY
   GdkScreen *screen;
 
   /* disconnect the "composited-changed" handler */
@@ -854,6 +854,11 @@
   GdkPixbuf           *image;
   gdouble              background_darkness;
 
+  _terminal_return_val_if_fail (TERMINAL_IS_SCREEN (screen), FALSE);
+  _terminal_return_val_if_fail (VTE_IS_TERMINAL (screen->terminal), FALSE);
+
+  GDK_THREADS_ENTER ();
+
   g_object_get (G_OBJECT (screen->preferences), "background-mode", &background_mode, NULL);
 
   if (background_mode == TERMINAL_BACKGROUND_SOLID)
@@ -861,7 +866,7 @@
       vte_terminal_set_background_image (VTE_TERMINAL (screen->terminal), NULL);
       vte_terminal_set_background_saturation (VTE_TERMINAL (screen->terminal), 1.0);
       vte_terminal_set_background_transparent (VTE_TERMINAL (screen->terminal), FALSE);
-#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY)
+#ifdef HAVE_VTE_TERMINAL_SET_OPACITY
       vte_terminal_set_opacity (VTE_TERMINAL (screen->terminal), 0xFFFF);
 #endif
     }
@@ -875,7 +880,7 @@
                                           screen->terminal->allocation.width,
                                           screen->terminal->allocation.height);
       vte_terminal_set_background_image (VTE_TERMINAL (screen->terminal), image);
-#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY)
+#ifdef HAVE_VTE_TERMINAL_SET_OPACITY
       vte_terminal_set_opacity (VTE_TERMINAL (screen->terminal), 0xFFFF);
 #endif
       if (image != NULL)
@@ -887,7 +892,7 @@
       g_object_get (G_OBJECT (screen->preferences), "background-darkness", &background_darkness, NULL);
       vte_terminal_set_background_image (VTE_TERMINAL (screen->terminal), NULL);
 
-#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY)
+#ifdef HAVE_VTE_TERMINAL_SET_OPACITY
       /* check if the X screen is composited */
       if (gdk_screen_is_composited (gtk_widget_get_screen (user_data)))
         {
@@ -900,12 +905,14 @@
 #endif
           vte_terminal_set_background_saturation (VTE_TERMINAL (screen->terminal), 1.0 - background_darkness);
           vte_terminal_set_background_transparent (VTE_TERMINAL (screen->terminal), TRUE);
-#if GTK_CHECK_VERSION(2,10,0) && defined(HAVE_VTE_TERMINAL_SET_OPACITY)
+#ifdef HAVE_VTE_TERMINAL_SET_OPACITY
           vte_terminal_set_opacity (VTE_TERMINAL (screen->terminal), 0xFFFF);
         }
 #endif
     }
 
+  GDK_THREADS_LEAVE ();
+
   return FALSE;
 }
 
@@ -1071,12 +1078,11 @@
   gint           xpad;
   gint           ypad;
 
-  gtk_widget_set_size_request (screen->terminal, 2000, 2000);
   gtk_widget_size_request (GTK_WIDGET (window), &window_requisition);
   gtk_widget_size_request (screen->terminal, &terminal_requisition);
 
-  width = window_requisition.width - terminal_requisition.width;
-  height = window_requisition.height - terminal_requisition.height;
+  width = MAX (window_requisition.width - terminal_requisition.width, 0);
+  height = MAX (window_requisition.height - terminal_requisition.height, 0);
 
   if (force_columns < 0)
     columns = VTE_TERMINAL (screen->terminal)->column_count;

Modified: terminal/trunk/terminal/terminal-tab-header.c
===================================================================
--- terminal/trunk/terminal/terminal-tab-header.c	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-tab-header.c	2007-12-02 14:21:23 UTC (rev 26427)
@@ -78,21 +78,8 @@
   void (*set_title)   (TerminalTabHeader *header);
 };
 
-struct _TerminalTabHeader
-{
-  GtkHBox              __parent__;
 
-  TerminalPreferences *preferences;
 
-  GtkWidget           *ebox;
-  GtkWidget           *label;
-
-  /* the popup menu */
-  GtkWidget           *menu;
-};
-
-
-
 static guint header_signals[LAST_SIGNAL];
 
 
@@ -185,6 +172,8 @@
 
   header->preferences = terminal_preferences_get ();
 
+  header->tab_pos_binding = NULL;
+
   gtk_widget_push_composite_child ();
 
   header->ebox = g_object_new (GTK_TYPE_EVENT_BOX, "border-width", 2, NULL);

Modified: terminal/trunk/terminal/terminal-tab-header.h
===================================================================
--- terminal/trunk/terminal/terminal-tab-header.h	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-tab-header.h	2007-12-02 14:21:23 UTC (rev 26427)
@@ -36,6 +36,21 @@
 typedef struct _TerminalTabHeaderClass TerminalTabHeaderClass;
 typedef struct _TerminalTabHeader      TerminalTabHeader;
 
+struct _TerminalTabHeader
+{
+  GtkHBox              __parent__;
+
+  TerminalPreferences *preferences;
+
+  GtkWidget           *ebox;
+  GtkWidget           *label;
+
+  /* the popup menu */
+  GtkWidget           *menu;
+
+  ExoBinding          *tab_pos_binding;
+};
+
 GType      terminal_tab_header_get_type (void) G_GNUC_CONST;
 
 GtkWidget *terminal_tab_header_new      (void);

Modified: terminal/trunk/terminal/terminal-widget.c
===================================================================
--- terminal/trunk/terminal/terminal-widget.c	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-widget.c	2007-12-02 14:21:23 UTC (rev 26427)
@@ -72,6 +72,7 @@
   TARGET_TEXT_PLAIN,
   TARGET_MOZ_URL,
   TARGET_APPLICATION_X_COLOR,
+  TARGET_GTK_NOTEBOOK_TAB,
 };
 
 
@@ -132,6 +133,7 @@
   { "STRING", 0, TARGET_STRING },
   { "text/plain", 0, TARGET_TEXT_PLAIN },
   { "application/x-color", 0, TARGET_APPLICATION_X_COLOR },
+  { "GTK_NOTEBOOK_TAB", GTK_TARGET_SAME_APP, TARGET_GTK_NOTEBOOK_TAB },
 };
 
 
@@ -185,7 +187,7 @@
                      GTK_DEST_DEFAULT_HIGHLIGHT |
                      GTK_DEST_DEFAULT_DROP,
                      targets, G_N_ELEMENTS (targets),
-                     GDK_ACTION_COPY | GDK_ACTION_LINK);
+                     GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE);
 
   /* monitor the misc-highlight-urls setting */
   g_signal_connect_swapped (G_OBJECT (widget->preferences), "notify::misc-highlight-urls",
@@ -437,6 +439,7 @@
   gchar         *text;
   gint           argc;
   gint           n;
+  GtkWidget     *screen;
 
   switch (info)
     {
@@ -564,7 +567,24 @@
           g_value_unset (&value);
         }
       break;
+
+    case TARGET_GTK_NOTEBOOK_TAB:
+      /* 'send' the drag to the parent widget (TerminalScreen) */
+      screen = gtk_widget_get_parent (widget);
+      if (G_LIKELY (screen))
+        {
+          g_signal_emit_by_name (G_OBJECT (screen), "drag-data-received", context,
+                                 x, y, selection_data, info, time);
+        }
+      break;
+
+    default:
+      /* never finish the drag */
+      return;
     }
+
+  if (info != TARGET_GTK_NOTEBOOK_TAB)
+    gtk_drag_finish (context, TRUE, FALSE, time);
 }
 
 

Modified: terminal/trunk/terminal/terminal-window.c
===================================================================
--- terminal/trunk/terminal/terminal-window.c	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-window.c	2007-12-02 14:21:23 UTC (rev 26427)
@@ -54,6 +54,7 @@
 #include <terminal/terminal-preferences-dialog.h>
 #include <terminal/terminal-private.h>
 #include <terminal/terminal-stock.h>
+#include <terminal/terminal-marshal.h>
 #include <terminal/terminal-tab-header.h>
 #include <terminal/terminal-toolbars-view.h>
 #include <terminal/terminal-window.h>
@@ -100,16 +101,32 @@
 static void            terminal_window_page_notified            (GtkNotebook            *notebook,
                                                                  GParamSpec             *pspec,
                                                                  TerminalWindow         *window);
-static void            terminal_window_page_switched            (GtkNotebook            *notebook,
+static void            terminal_window_notebook_visibility      (TerminalWindow         *window);
+static void            terminal_window_page_reordered           (GtkNotebook            *notebook,
                                                                  GtkNotebookPage        *page,
                                                                  guint                   page_num,
                                                                  TerminalWindow         *window);
-#if GTK_CHECK_VERSION (2,10,0)
-static void            terminal_window_page_reordered           (GtkNotebook            *notebook,
-                                                                 GtkNotebookPage        *page,
+static void            terminal_window_page_added               (GtkNotebook            *notebook,
+                                                                 GtkWidget              *child,
                                                                  guint                   page_num,
                                                                  TerminalWindow         *window);
-#endif
+static void            terminal_window_page_removed             (GtkNotebook            *notebook,
+                                                                 GtkWidget              *child,
+                                                                 guint                   page_num,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_page_drag_data_received  (GtkWidget              *widget,
+                                                                 GdkDragContext         *context,
+                                                                 gint                    x,
+                                                                 gint                    y,
+                                                                 GtkSelectionData       *selection_data,
+                                                                 guint                   info,
+                                                                 guint                   time,
+                                                                 TerminalWindow         *window);
+static GtkNotebook    *terminal_window_page_detach              (GtkNotebook            *notebook,
+                                                                 GtkWidget              *child,
+                                                                 gint                    x,
+                                                                 gint                    y,
+                                                                 TerminalWindow         *window);
 static GtkWidget      *terminal_window_get_context_menu         (TerminalScreen         *screen,
                                                                  TerminalWindow         *window);
 static void            terminal_window_detach_screen            (TerminalWindow         *window,
@@ -117,9 +134,6 @@
 static void            terminal_window_notify_title             (TerminalScreen         *screen,
                                                                  GParamSpec             *pspec,
                                                                  TerminalWindow         *window);
-static void            terminal_window_screen_removed           (GtkNotebook            *notebook,
-                                                                 TerminalScreen         *screen,
-                                                                 TerminalWindow         *window);
 static void            terminal_window_action_new_tab           (GtkAction              *action,
                                                                  TerminalWindow         *window);
 static void            terminal_window_action_new_window        (GtkAction              *action,
@@ -144,26 +158,26 @@
                                                                  TerminalWindow         *window);
 static void            terminal_window_action_show_toolbars     (GtkToggleAction        *action,
                                                                  TerminalWindow         *window);
-static void            terminal_window_action_show_borders      (GtkToggleAction *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_fullscreen        (GtkToggleAction *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_prev_tab          (GtkAction       *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_next_tab          (GtkAction       *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_set_title         (GtkAction       *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_reset             (GtkAction       *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_reset_and_clear   (GtkAction       *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_contents          (GtkAction       *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_report_bug        (GtkAction       *action,
-                                                                 TerminalWindow  *window);
-static void            terminal_window_action_about             (GtkAction       *action,
-                                                                 TerminalWindow  *window);
+static void            terminal_window_action_show_borders      (GtkToggleAction        *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_fullscreen        (GtkToggleAction        *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_prev_tab          (GtkAction              *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_next_tab          (GtkAction              *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_set_title         (GtkAction              *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_reset             (GtkAction              *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_reset_and_clear   (GtkAction              *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_contents          (GtkAction              *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_report_bug        (GtkAction              *action,
+                                                                 TerminalWindow         *window);
+static void            terminal_window_action_about             (GtkAction              *action,
+                                                                 TerminalWindow         *window);
 
 
 
@@ -191,6 +205,9 @@
 
 
 static guint window_signals[LAST_SIGNAL];
+#if GTK_CHECK_VERSION (2,12,0)
+static gpointer window_notebook_group = "Terminal";
+#endif
 
 
 
@@ -242,7 +259,7 @@
 {
   GtkWidgetClass *gtkwidget_class;
   GObjectClass   *gobject_class;
-  
+
   gobject_class = G_OBJECT_CLASS (klass);
   gobject_class->dispose = terminal_window_dispose;
   gobject_class->finalize = terminal_window_finalize;
@@ -269,12 +286,13 @@
   window_signals[NEW_WINDOW_WITH_SCREEN] =
     g_signal_new (I_("new-window-with-screen"),
                   G_TYPE_FROM_CLASS (gobject_class),
-                  G_SIGNAL_RUN_LAST,
+                  G_SIGNAL_RUN_FIRST,
                   G_STRUCT_OFFSET (TerminalWindowClass, new_window_with_screen),
                   NULL, NULL,
-                  g_cclosure_marshal_VOID__OBJECT,
-                  G_TYPE_NONE, 1,
-                  G_TYPE_OBJECT);
+                  _terminal_marshal_VOID__OBJECT_INT_INT,
+                  G_TYPE_NONE, 3,
+                  G_TYPE_OBJECT,
+                  G_TYPE_INT, G_TYPE_INT);
 }
 
 
@@ -317,6 +335,7 @@
   gtk_ui_manager_insert_action_group (window->ui_manager, window->action_group, 0);
   gtk_ui_manager_add_ui_from_string (window->ui_manager, terminal_window_ui, terminal_window_ui_length, NULL);
   
+
   accel_group = gtk_ui_manager_get_accel_group (window->ui_manager);
   gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
 
@@ -348,6 +367,7 @@
         }
     }
 
+
   /* setup mnemonics */
   g_object_get (G_OBJECT (window->preferences), "shortcuts-no-mnemonics", &bval, NULL);
   if (G_UNLIKELY (bval))
@@ -375,16 +395,26 @@
                                    "tab-vborder", 0,
                                    NULL);
   exo_binding_new (G_OBJECT (window->preferences), "misc-tab-position", G_OBJECT (window->notebook), "tab-pos");
-  g_signal_connect_after (G_OBJECT (window->notebook), "switch-page",
-                          G_CALLBACK (terminal_window_page_switched), window);
+
+  /* set the notebook group id */
+#if GTK_CHECK_VERSION (2,12,0)
+  gtk_notebook_set_group (GTK_NOTEBOOK (window->notebook), window_notebook_group);
+#else
+  gtk_notebook_set_group_id (GTK_NOTEBOOK (window->notebook), 1);
+#endif
+
+  /* signals */
   g_signal_connect (G_OBJECT (window->notebook), "notify::page",
                     G_CALLBACK (terminal_window_page_notified), window);
-  g_signal_connect (G_OBJECT (window->notebook), "remove",
-                    G_CALLBACK (terminal_window_screen_removed), window);
-
-#if GTK_CHECK_VERSION (2,10,0)
   g_signal_connect (G_OBJECT (window->notebook), "page-reordered",
                     G_CALLBACK (terminal_window_page_reordered), window);
+  g_signal_connect (G_OBJECT (window->notebook), "page-removed",
+                    G_CALLBACK (terminal_window_page_removed), window);
+  g_signal_connect (G_OBJECT (window->notebook), "page-added",
+                    G_CALLBACK (terminal_window_page_added), window);
+#if GTK_CHECK_VERSION (2,12,0)
+  g_signal_connect (G_OBJECT (window->notebook), "create-window",
+                    G_CALLBACK (terminal_window_page_detach), window);
 #endif
 
   gtk_box_pack_start (GTK_BOX (vbox), window->notebook, TRUE, TRUE, 0);
@@ -591,7 +621,9 @@
   TerminalScreen *active;
   gint            grid_width;
   gint            grid_height;
-  
+
+  GDK_THREADS_ENTER ();
+
   /* The trick is rather simple here. This is called before any Gtk+ resizing operation takes
    * place, so the columns/rows on the active terminal screen are still set to their old values.
    * We simply query these values and force them to be set with the new style.
@@ -603,6 +635,8 @@
       terminal_window_set_size_force_grid (window, active, grid_width, grid_height);
     }
 
+  GDK_THREADS_LEAVE ();
+
   return FALSE;
 }
 
@@ -826,7 +860,17 @@
 static gboolean
 terminal_window_delete_event (TerminalWindow *window)
 {
-  return !terminal_window_confirm_close (window);
+  gboolean result;
+
+  /* get close confirmation from the user */
+  result = terminal_window_confirm_close (window);
+
+  /* disconnect remove signal if we're closing the window */
+  if (result)
+    g_signal_handlers_disconnect_by_func (G_OBJECT (window->notebook),
+                                          G_CALLBACK (terminal_window_page_removed), window);
+
+  return !result;
 }
 
 
@@ -853,55 +897,268 @@
 
 
 static void
-terminal_window_page_switched (GtkNotebook     *notebook,
-                               GtkNotebookPage *page,
-                               guint            page_num,
-                               TerminalWindow  *window)
+terminal_window_notebook_visibility (TerminalWindow *window)
 {
-  TerminalScreen *terminal;
-  gint            grid_width;
-  gint            grid_height;
+  TerminalScreen *active;
+  gboolean        always_show_tabs, tabs_shown;
+  gint            npages;
+  gint            grid_width, grid_height;
 
-  terminal = terminal_window_get_active (window);
-  if (G_LIKELY (terminal != NULL))
+  /* check if we should always display tabs */
+  g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL);
+
+  /* current notebook status */
+  tabs_shown = gtk_notebook_get_show_tabs (GTK_NOTEBOOK (window->notebook));
+  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+
+  /* change the visibility if the new status differs */
+  if (((npages > 1) != tabs_shown) || (always_show_tabs && !tabs_shown))
     {
-      /* FIXME: This isn't really needed anymore, instead we
-       * could grab the grid size of the previously selected
-       * page and apply that to the newly selected page.
-       */
+      /* get active screen */
+      active = terminal_window_get_active (window);
 
-      /* This is a bit tricky, but seems to be necessary to get the
-       * sizing correct: First we query the current terminal size
-       * (rows x columns), then we force a size update on the terminal
-       * window (which may reset the terminal size). Afterwards we
-       * reset the terminal screen size to the original values and
-       * resize the terminal window accordingly.
-       */
-      terminal_screen_get_size (terminal, &grid_width, &grid_height);
-      terminal_screen_set_size (terminal, grid_width, grid_height);
-      terminal_window_set_size_force_grid (window, terminal, grid_width, grid_height);
+      /* get screen grid size */
+      terminal_screen_get_size (active, &grid_width, &grid_height);
+
+      /* show or hide the tabs */
+      gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), !tabs_shown);
+
+      /* don't focus the notebook */
+      GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS);
+
+      /* resize the window */
+      terminal_screen_force_resize_window (active, GTK_WINDOW (window), grid_width, grid_height);
     }
 }
 
 
 
-#if GTK_CHECK_VERSION (2,10,0)
 static void
 terminal_window_page_reordered (GtkNotebook     *notebook,
                                 GtkNotebookPage *page,
                                 guint            page_num,
                                 TerminalWindow  *window)
 {
-  
-  /* Regenerate the "Go" menu.
-   * This also updates the accelerators.
-   */
+
+  /* Regenerate the "Go" menu */
   terminal_window_rebuild_gomenu (window);
 }
-#endif
 
 
 
+static void
+terminal_window_page_added (GtkNotebook    *notebook,
+                            GtkWidget      *child,
+                            guint           page_num,
+                            TerminalWindow *window)
+{
+  gint               grid_width, grid_height;
+  GtkAction         *action;
+  TerminalTabHeader *header;
+  TerminalScreen    *active;
+
+  _terminal_return_if_fail (TERMINAL_IS_SCREEN (child));
+  _terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
+
+  /* get tab header */
+  header = g_object_get_data (G_OBJECT (child), I_("terminal-tab-header"));
+
+  _terminal_return_if_fail (TERMINAL_IS_TAB_HEADER (header));
+
+  /* tab position binding */
+  header->tab_pos_binding = exo_binding_new (G_OBJECT (window->notebook), "tab-pos", G_OBJECT (header), "tab-pos");
+
+  /* connect screen signals */
+  g_signal_connect (G_OBJECT (child), "get-context-menu", G_CALLBACK (terminal_window_get_context_menu), window);
+  g_signal_connect (G_OBJECT (child), "notify::title", G_CALLBACK (terminal_window_notify_title), window);
+  g_signal_connect_swapped (G_OBJECT (child), "selection-changed", G_CALLBACK (terminal_window_update_actions), window);
+  g_signal_connect (G_OBJECT (child), "drag-data-received", G_CALLBACK (terminal_window_page_drag_data_received), window);
+
+  /* get action from window action group */
+  action = gtk_action_group_get_action (window->action_group, "set-title");
+
+  /* connect tab label signals */
+  g_signal_connect_swapped (G_OBJECT (header), "detach-tab", G_CALLBACK (terminal_window_detach_screen), window);
+  g_signal_connect_swapped (G_OBJECT (header), "set-title", G_CALLBACK (gtk_action_activate), action);
+
+  /* set visibility of the notebook */
+  terminal_window_notebook_visibility (window);
+
+  /* get the active tab */
+  active = terminal_window_get_active (window);
+  if (G_LIKELY (active != NULL))
+    {
+      /* set new screen grid size based on the old one */
+      terminal_screen_get_size (active, &grid_width, &grid_height);
+      terminal_screen_set_size (TERMINAL_SCREEN (child), grid_width, grid_height);
+    }
+  else
+    {
+      /* set the window size (needed for resizing) */
+      terminal_screen_get_size (TERMINAL_SCREEN (child), &grid_width, &grid_height);
+      terminal_window_set_size_force_grid (window, TERMINAL_SCREEN (child), grid_width, grid_height);
+    }
+
+  /* regenerate the "Go" menu */
+  terminal_window_rebuild_gomenu (window);
+
+  /* update all screen sensitive actions (Copy, Prev Tab, ...) */
+  terminal_window_update_actions (window);
+}
+
+
+
+static void
+terminal_window_page_removed (GtkNotebook    *notebook,
+                              GtkWidget      *child,
+                              guint           page_num,
+                              TerminalWindow *window)
+{
+  TerminalTabHeader *header = g_object_get_data (G_OBJECT (child), I_("terminal-tab-header"));
+  GtkAction         *action;
+  gint               npages;
+
+  _terminal_return_if_fail (TERMINAL_IS_SCREEN (child));
+  _terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
+  _terminal_return_if_fail (TERMINAL_IS_TAB_HEADER (header));
+  _terminal_return_if_fail (header->tab_pos_binding != NULL);
+
+  /* get old window action */
+  action = gtk_action_group_get_action (window->action_group, "set-title");
+
+  /* disconnect signals */
+  g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_get_context_menu, window);
+  g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_notify_title, window);
+  g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_update_actions, window);
+  g_signal_handlers_disconnect_by_func (G_OBJECT (child), terminal_window_page_drag_data_received, window);
+  g_signal_handlers_disconnect_by_func (G_OBJECT (header), terminal_window_detach_screen, window);
+  g_signal_handlers_disconnect_by_func (G_OBJECT (header), gtk_action_activate, action);
+
+  /* remove exo binding */
+  exo_binding_unbind (header->tab_pos_binding);
+
+  /* set tab visibility */
+  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+  if (G_UNLIKELY (npages == 0))
+    {
+      /* no tabs, destroy the window */
+      gtk_widget_destroy (GTK_WIDGET (window));
+    }
+  else
+    {
+      /* set visibility of the notebook */
+      terminal_window_notebook_visibility (window);
+
+      /* regenerate the "Go" menu */
+      terminal_window_rebuild_gomenu (window);
+
+      /* update all screen sensitive actions (Copy, Prev Tab, ...) */
+      terminal_window_update_actions (window);
+    }
+}
+
+
+
+static void
+terminal_window_page_drag_data_received (GtkWidget        *widget,
+                                         GdkDragContext   *context,
+                                         gint              x,
+                                         gint              y,
+                                         GtkSelectionData *selection_data,
+                                         guint             info,
+                                         guint             time,
+                                         TerminalWindow *window)
+{
+  GtkWidget  *source_widget;
+  GtkWidget **screen;
+  GtkWidget  *child, *label;
+  gint        i, n_pages;
+
+  _terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
+
+  /* get the source notebook (other window) */
+  source_widget = gtk_drag_get_source_widget (context);
+
+  /* get the dragged screen */
+  screen = (GtkWidget **) selection_data->data;
+
+  /* check */
+  if (source_widget && TERMINAL_IS_SCREEN (*screen))
+    {
+      /* take a reference */
+      g_object_ref (G_OBJECT (*screen));
+
+      /* remove the document from the source notebook */
+      gtk_container_remove (GTK_CONTAINER (source_widget), *screen);
+
+      /* get the number of pages in the new window */
+      n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+
+      /* figure out where to insert the tab in the notebook */
+      for (i = 0; i < n_pages; i++)
+        {
+          /* get the child label */
+          child = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), i);
+          label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (window->notebook), child);
+
+          /* break if we have a matching drop position */
+          if (x < (label->allocation.x + label->allocation.width / 2))
+            break;
+        }
+
+      /* add the screen to the new window */
+      terminal_window_add (window, TERMINAL_SCREEN (*screen));
+
+      /* move the child to the correct position */
+      gtk_notebook_reorder_child (GTK_NOTEBOOK (window->notebook), *screen, i);
+
+      /* release reference */
+      g_object_unref (G_OBJECT (*screen));
+
+      /* finish the drag */
+      gtk_drag_finish (context, TRUE, TRUE, time);
+    }
+}
+
+
+
+static GtkNotebook *
+terminal_window_page_detach (GtkNotebook    *notebook,
+                             GtkWidget      *child,
+                             gint            x,
+                             gint            y,
+                             TerminalWindow *window)
+{
+  TerminalScreen *screen;
+
+  _terminal_return_val_if_fail (TERMINAL_IS_WINDOW (window), NULL);
+  _terminal_return_val_if_fail (TERMINAL_IS_SCREEN (child), NULL);
+  _terminal_return_val_if_fail (notebook == GTK_NOTEBOOK (window->notebook), NULL);
+
+  /* only create new window when there are more then 2 tabs (bug #2686) */
+  if (gtk_notebook_get_n_pages (notebook) >= 2)
+    {
+      /* get the screen */
+      screen = TERMINAL_SCREEN (child);
+
+      /* take a reference */
+      g_object_ref (G_OBJECT (screen));
+
+      /* remove screen from active window */
+      gtk_container_remove (GTK_CONTAINER (window->notebook), child);
+
+      /* create new window with the screen */
+      g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW_WITH_SCREEN], 0, screen, x, y);
+
+      /* release our reference */
+      g_object_unref (G_OBJECT (screen));
+    }
+    
+  return NULL;
+}
+
+
+
 static GtkWidget*
 terminal_window_get_context_menu (TerminalScreen  *screen,
                                   TerminalWindow  *window)
@@ -942,20 +1199,10 @@
 {
   GtkWidget *screen;
 
-  /* verify that we have atleast two tabs, otherwise we'll crash,
-   * see http://bugzilla.xfce.org/show_bug.cgi?id=2686.
-   */
-  if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) >= 2)
-    {
-      screen = g_object_get_data (G_OBJECT (header), "terminal-window-screen");
-      if (G_LIKELY (screen != NULL))
-        {
-          g_object_ref (G_OBJECT (screen));
-          gtk_container_remove (GTK_CONTAINER (window->notebook), screen);
-          g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW_WITH_SCREEN], 0, screen);
-          g_object_unref (G_OBJECT (screen));
-        }
-    }
+  /* get the screen */
+  screen = g_object_get_data (G_OBJECT (header), I_("terminal-window-screen"));
+  if (G_LIKELY (screen != NULL))
+    terminal_window_page_detach (GTK_NOTEBOOK (window->notebook), screen, -1, -1, window);
 }
 
 
@@ -981,50 +1228,6 @@
 
 
 static void
-terminal_window_screen_removed (GtkNotebook     *notebook,
-                                TerminalScreen  *screen,
-                                TerminalWindow  *window)
-{
-  TerminalScreen *active;
-  gboolean        always_show_tabs;
-  gint            npages;
-  gint            grid_width;
-  gint            grid_height;
-
-  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
-  if (G_UNLIKELY (npages == 0))
-    {
-      gtk_widget_destroy (GTK_WIDGET (window));
-    }
-  else
-    {
-      /* check tabs should always be visible */
-      g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL);
-
-      /* change the visibility of the tabs accordingly */
-      gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), always_show_tabs || (npages > 1));
-
-      /* meh, Gtk+, who wants focus on the notebook? */
-      GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS);
-
-      active = terminal_window_get_active (window);
-      if (G_LIKELY (active != NULL))
-        {
-          terminal_screen_get_size (screen, &grid_width, &grid_height);
-          terminal_window_set_size_force_grid (window, active, grid_width, grid_height);
-        }
-
-      /* regenerate the "Go" menu */
-      terminal_window_rebuild_gomenu (window);
-
-      /* update all screen sensitive actions (Copy, Prev Tab, ...) */
-      terminal_window_update_actions (window);
-    }
-}
-
-
-
-static void
 terminal_window_action_new_tab (GtkAction       *action,
                                 TerminalWindow  *window)
 {
@@ -1071,14 +1274,11 @@
 {
   TerminalScreen *terminal;
 
+  /* get active terminal window */
   terminal = terminal_window_get_active (window);
+
   if (G_LIKELY (terminal != NULL))
-    {
-      g_object_ref (G_OBJECT (terminal));
-      gtk_container_remove (GTK_CONTAINER (window->notebook), GTK_WIDGET (terminal));
-      g_signal_emit (G_OBJECT (window), window_signals[NEW_WINDOW_WITH_SCREEN], 0, terminal);
-      g_object_unref (G_OBJECT (terminal));
-    }
+    terminal_window_page_detach (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (terminal), -1, -1, window);
 }
 
 
@@ -1489,77 +1689,29 @@
 terminal_window_add (TerminalWindow *window,
                      TerminalScreen *screen)
 {
-  TerminalScreen *active;
   GtkWidget      *header;
-  GtkAction      *action;
-  gboolean        always_show_tabs;
-  gint            npages;
   gint            page;
-  gint            grid_width;
-  gint            grid_height;
 
   _terminal_return_if_fail (TERMINAL_IS_WINDOW (window));
   _terminal_return_if_fail (TERMINAL_IS_SCREEN (screen));
 
-  active = terminal_window_get_active (window);
-  if (G_LIKELY (active != NULL))
-    {
-      terminal_screen_get_size (active, &grid_width, &grid_height);
-      terminal_screen_set_size (screen, grid_width, grid_height);
-    }
-
-  action = gtk_action_group_get_action (window->action_group, "set-title");
-
   header = terminal_tab_header_new ();
   exo_binding_new (G_OBJECT (screen), "title", G_OBJECT (header), "title");
-  exo_binding_new (G_OBJECT (window->notebook), "tab-pos", G_OBJECT (header), "tab-pos");
   g_signal_connect_swapped (G_OBJECT (header), "close-tab", G_CALLBACK (gtk_widget_destroy), screen);
-  g_signal_connect_swapped (G_OBJECT (header), "detach-tab", G_CALLBACK (terminal_window_detach_screen), window);
-  g_signal_connect_swapped (G_OBJECT (header), "set-title", G_CALLBACK (gtk_action_activate), action);
   g_object_set_data_full (G_OBJECT (header), I_("terminal-window-screen"), g_object_ref (G_OBJECT (screen)), (GDestroyNotify) g_object_unref);
+  g_object_set_data_full (G_OBJECT (screen), I_("terminal-tab-header"), g_object_ref (G_OBJECT (header)), (GDestroyNotify) g_object_unref);
   gtk_widget_show (header);
 
-  page = gtk_notebook_append_page (GTK_NOTEBOOK (window->notebook),
-                                   GTK_WIDGET (screen), header);
-  gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (window->notebook),
-                                      GTK_WIDGET (screen),
-                                      TRUE, TRUE, GTK_PACK_START);
+  page = gtk_notebook_append_page (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), header);
+  gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), TRUE, TRUE, GTK_PACK_START);
 
-#if GTK_CHECK_VERSION(2,10,0)
-  gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook),
-                                    GTK_WIDGET (screen),
-                                    TRUE);
-#endif
+  /* allow tab sorting and dnd */
+  gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), TRUE);
+  gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (window->notebook), GTK_WIDGET (screen), TRUE);
 
-  /* check if we should always display tabs */
-  g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL);
-
-  /* change the visibility of the tabs accordingly */
-  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
-  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), always_show_tabs || (npages > 1));
-
-  /* yep, still no focus on the notebook! */
-  GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS);
-
-  g_signal_connect (G_OBJECT (screen), "get-context-menu",
-                    G_CALLBACK (terminal_window_get_context_menu), window);
-  g_signal_connect (G_OBJECT (screen), "notify::title",
-                    G_CALLBACK (terminal_window_notify_title), window);
-  g_signal_connect_swapped (G_OBJECT (screen), "selection-changed",
-                            G_CALLBACK (terminal_window_update_actions), window);
-
-  terminal_window_rebuild_gomenu (window);
-
-  /* need to save the grid size here for detached screens */
-  terminal_screen_get_size (screen, &grid_width, &grid_height);
-
   /* need to show this first, else we cannot switch to it */
   gtk_widget_show (GTK_WIDGET (screen));
   gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), page);
-
-  terminal_window_set_size_force_grid (window, screen, grid_width, grid_height);
-
-  gtk_widget_queue_draw (GTK_WIDGET (screen));
 }
 
 

Modified: terminal/trunk/terminal/terminal-window.h
===================================================================
--- terminal/trunk/terminal/terminal-window.h	2007-12-02 14:16:02 UTC (rev 26426)
+++ terminal/trunk/terminal/terminal-window.h	2007-12-02 14:21:23 UTC (rev 26427)
@@ -44,7 +44,9 @@
   void  (*new_window)             (TerminalWindow *window,
                                    const gchar    *working_directory);
   void  (*new_window_with_screen) (TerminalWindow *window,
-                                   TerminalScreen *screen);
+                                   TerminalScreen *screen,
+                                   gint            x,
+                                   gint            y);
 };
 
 GType           terminal_window_get_type             (void) G_GNUC_CONST;



More information about the Xfce4-commits mailing list