* looking for tsui.tony@gmail.com--projects/gnome-terminal--vendor--2.12.0--version-0 to compare with
* comparing to tsui.tony@gmail.com--projects/gnome-terminal--vendor--2.12.0--version-0: ......................................... done.

* modified files

--- orig/ChangeLog
+++ mod/ChangeLog
@@ -1,3 +1,32 @@
+2005-11-09  Tony Tsui  <tsui.tony@gmail.com>
+
+	* gnome-terminal.schemas.in
+	* src/terminal-accels.c:
+	* src/terminal-accels.c:
+	* src/terminal-window.c:
+	Support for detaching tabs via Tabs menu and via keybindings.
+
+2005-11-08  Mario Manno  <mm-bugs@manno.name>
+
+	* gnome-terminal.schemas.in
+	* src/terminal-accels.c:
+	* src/terminal-accels.c:
+	* src/terminal-window.c:
+	Support for moving tabs via Tabs menu and via keybindings.
+
+2005-11-01  Tony Tsui  <tsui.tony@gmail.com>
+
+	* src/Makefile.am:
+	* src/terminal-notebook.h:
+	* src/terminal-notebook.h:
+	* src/terminal-screen.c:
+	* src/terminal-screen.h:
+	* src/terminal-window.c:
+	* src/terminal-window.h:
+	* src/terminal.c:
+	* src/terminal.h:
+	Add support for making tabs movable and detachable.
+
 ========================== 2.12.0 =======================
 
 2005-09-06  Kjartan Maraas  <kmaraas@gnome.org>
--- orig/src/Makefile.am
+++ mod/src/Makefile.am
@@ -46,6 +46,8 @@ gnome_terminal_SOURCES=				\
 	terminal-widget-vte.c			\
 	terminal-window.c			\
 	terminal-window.h			\
+	terminal-notebook.c			\
+	terminal-notebook.h			\
 	simple-x-font-selector.c		\
 	simple-x-font-selector.h		\
 	$(EGGFILES)
--- orig/src/Makefile.in
+++ mod/src/Makefile.in
@@ -58,7 +58,7 @@ am_gnome_terminal_OBJECTS = encoding.$(O
 	profile-editor.$(OBJEXT) skey-popup.$(OBJEXT) \
 	terminal.$(OBJEXT) terminal-accels.$(OBJEXT) \
 	terminal-profile.$(OBJEXT) terminal-screen.$(OBJEXT) \
-	terminal-widget-vte.$(OBJEXT) terminal-window.$(OBJEXT) \
+	terminal-widget-vte.$(OBJEXT) terminal-window.$(OBJEXT) terminal-notebook.$(OBJEXT) \
 	simple-x-font-selector.$(OBJEXT) $(am__objects_1)
 gnome_terminal_OBJECTS = $(am_gnome_terminal_OBJECTS)
 am__DEPENDENCIES_1 =
@@ -290,6 +290,8 @@ gnome_terminal_SOURCES = \
 	terminal-widget-vte.c			\
 	terminal-window.c			\
 	terminal-window.h			\
+	terminal-notebook.c			\
+	terminal-notebook.h			\
 	simple-x-font-selector.c		\
 	simple-x-font-selector.h		\
 	$(EGGFILES)
--- orig/src/gnome-terminal.schemas
+++ mod/src/gnome-terminal.schemas
@@ -15981,6 +15981,56 @@ 正常來說，Delete 鍵應該使用“
     </schema>
 
     <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/move_tab_left</key>
+      <applyto>/apps/gnome-terminal/keybindings/move_tab_left</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <default>&lt;Ctrl&gt;&lt;Shift&gt;Page_Up</default>
+      <locale name="C">
+         <short>Accelerator to move current tab left.</short>
+         <long>
+          Accelerator key to move current tab left. Expressed as a string
+          in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keybinding for this action.
+         </long>
+      </locale>
+    </schema>
+    
+    <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/move_tab_right</key>
+      <applyto>/apps/gnome-terminal/keybindings/move_tab_right</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <default>&lt;Ctrl&gt;&lt;Shift&gt;Page_Down</default>
+      <locale name="C">
+         <short>Accelerator to move current tab right.</short>
+         <long>
+          Accelerator key to move current tab right. Expressed as a string
+          in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keybinding for this action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/detach_tab</key>
+      <applyto>/apps/gnome-terminal/keybindings/detach_tab</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <locale name="C">
+         <short>Accelerator to detach current tab.</short>
+         <long>
+          Accelerator key to detach current tab. Expressed as a string
+          in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keybinding for this action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/gnome-terminal/keybindings/switch_to_tab_1</key>
       <applyto>/apps/gnome-terminal/keybindings/switch_to_tab_1</applyto>
       <owner>gnome-terminal</owner>
--- orig/src/gnome-terminal.schemas.in
+++ mod/src/gnome-terminal.schemas.in
@@ -867,6 +867,56 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/move_tab_left</key>
+      <applyto>/apps/gnome-terminal/keybindings/move_tab_left</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <default>&lt;Ctrl&gt;&lt;Shift&gt;Page_Up</default>
+      <locale name="C">
+         <short>Accelerator to move current tab left.</short>
+         <long>
+          Accelerator key to move current tab left. Expressed as a string
+          in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keybinding for this action.
+         </long>
+      </locale>
+    </schema>
+    
+    <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/move_tab_right</key>
+      <applyto>/apps/gnome-terminal/keybindings/move_tab_right</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <default>&lt;Ctrl&gt;&lt;Shift&gt;Page_Down</default>
+      <locale name="C">
+         <short>Accelerator to move current tab right.</short>
+         <long>
+          Accelerator key to move current tab right. Expressed as a string
+          in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keybinding for this action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/gnome-terminal/keybindings/detach_tab</key>
+      <applyto>/apps/gnome-terminal/keybindings/detach_tab</applyto>
+      <owner>gnome-terminal</owner>
+      <type>string</type>
+      <locale name="C">
+         <short>Accelerator to detach current tab.</short>
+         <long>
+          Accelerator key to detach current tab. Expressed as a string
+          in the same format used for GTK+ resource files.
+          If you set the option to the special string "disabled", then there 
+          will be no keybinding for this action.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/gnome-terminal/keybindings/switch_to_tab_1</key>
       <applyto>/apps/gnome-terminal/keybindings/switch_to_tab_1</applyto>
       <owner>gnome-terminal</owner>
--- orig/src/terminal-accels.c
+++ mod/src/terminal-accels.c
@@ -43,6 +43,9 @@
 #define KEY_RESET_AND_CLEAR CONF_KEYS_PREFIX"/reset_and_clear"
 #define KEY_PREV_TAB CONF_KEYS_PREFIX"/prev_tab"
 #define KEY_NEXT_TAB CONF_KEYS_PREFIX"/next_tab"
+#define KEY_MOVE_TAB_LEFT CONF_KEYS_PREFIX"/move_tab_left"
+#define KEY_MOVE_TAB_RIGHT CONF_KEYS_PREFIX"/move_tab_right"
+#define KEY_DETACH_TAB CONF_KEYS_PREFIX"/detach_tab"
 #define KEY_SET_TERMINAL_TITLE CONF_KEYS_PREFIX"/set_window_title"
 #define PREFIX_KEY_SWITCH_TO_TAB CONF_KEYS_PREFIX"/switch_to_tab_"
 #define KEY_HELP CONF_KEYS_PREFIX"/help"
@@ -122,6 +125,12 @@ static KeyEntry go_entries[] =
     KEY_PREV_TAB, ACCEL_PATH_PREV_TAB, 0, 0, NULL, FALSE },
   { N_("Switch to Next Tab"),
     KEY_NEXT_TAB, ACCEL_PATH_NEXT_TAB, 0, 0, NULL, FALSE },
+  { N_("Move Tab Left"),
+    KEY_MOVE_TAB_LEFT, ACCEL_PATH_MOVE_TAB_LEFT, 0, 0, NULL, FALSE },
+  { N_("Move Tab Right"),
+    KEY_MOVE_TAB_RIGHT, ACCEL_PATH_MOVE_TAB_RIGHT, 0, 0, NULL, FALSE },
+  { N_("Detach Tab"),
+    KEY_DETACH_TAB, ACCEL_PATH_DETACH_TAB, 0, 0, NULL, FALSE },
   { N_("Switch to Tab 1"),
     PREFIX_KEY_SWITCH_TO_TAB"1",
     PREFIX_ACCEL_PATH_SWITCH_TO_TAB"1", 0, 0, NULL, FALSE },
--- orig/src/terminal-accels.h
+++ mod/src/terminal-accels.h
@@ -47,6 +47,9 @@ GtkAccelGroup* terminal_accels_get_group
 #define ACCEL_PATH_ZOOM_IN ACCEL_PATH_ROOT"/zoom_in"
 #define ACCEL_PATH_ZOOM_OUT ACCEL_PATH_ROOT"/zoom_out"
 #define ACCEL_PATH_ZOOM_NORMAL ACCEL_PATH_ROOT"/zoom_normal"
+#define ACCEL_PATH_MOVE_TAB_LEFT ACCEL_PATH_ROOT"/move_tab_left"
+#define ACCEL_PATH_MOVE_TAB_RIGHT ACCEL_PATH_ROOT"/move_tab_right"
+#define ACCEL_PATH_DETACH_TAB ACCEL_PATH_ROOT"/detach_tab"
 
 #define FORMAT_ACCEL_PATH_SWITCH_TO_TAB ACCEL_PATH_ROOT"/switch_to_tab_%d"
 #define PREFIX_ACCEL_PATH_SWITCH_TO_TAB ACCEL_PATH_ROOT"/switch_to_tab_"
--- orig/src/terminal-screen.c
+++ mod/src/terminal-screen.c
@@ -67,6 +67,8 @@ struct _TerminalScreenPrivate
   double font_scale;
   guint recheck_working_dir_idle;
   guint gconf_connection_id;
+  GtkWidget *hbox;
+  GtkWidget *scrollbar;
 };
 
 static GList* used_ids = NULL;
@@ -91,6 +93,11 @@ enum
 static void terminal_screen_init        (TerminalScreen      *screen);
 static void terminal_screen_class_init  (TerminalScreenClass *klass);
 static void terminal_screen_finalize    (GObject             *object);
+static void terminal_screen_size_allocate (GtkWidget *widget,
+                                           GtkAllocation *allocation);
+static void terminal_screen_size_request (GtkWidget *widget,
+                                           GtkRequisition *requisition);
+static void terminal_screen_map         (GtkWidget           *widget);
 static void terminal_screen_update_on_realize (GtkWidget      *widget,
                                                TerminalScreen *screen);
 static gboolean terminal_screen_popup_menu         (GtkWidget      *term,
@@ -137,7 +144,7 @@ static char*    make_xfont_have_size_fro
 
 static GdkFont* load_fonset_without_error (const gchar *fontset_name);
 
-static gpointer parent_class;
+static GObjectClass *parent_class = NULL;
 static guint signals[LAST_SIGNAL] = { 0 };
 
 GType
@@ -161,8 +168,8 @@ terminal_screen_get_type (void)
         0,              /* n_preallocs */
         (GInstanceInitFunc) terminal_screen_init,
       };
-      
-      object_type = g_type_register_static (G_TYPE_OBJECT,
+
+      object_type = g_type_register_static (GTK_TYPE_BIN,
                                             "TerminalScreen",
                                             &object_info, 0);
     }
@@ -221,6 +228,35 @@ connect_monospace_font_change (TerminalS
 }
 
 static void
+terminal_screen_size_request (GtkWidget *widget,
+                              GtkRequisition *requisition)
+{
+  TerminalScreen *screen;
+  GtkRequisition widget_request;
+
+  screen = TERMINAL_SCREEN (widget);
+ 
+  gtk_widget_size_request (screen->priv->hbox, &widget_request);
+
+  requisition->width = widget_request.width;
+  requisition->height = widget_request.height;
+}
+
+static void
+terminal_screen_size_allocate (GtkWidget *widget,
+      GtkAllocation *allocation)
+{
+  GtkWidget *child;
+
+  widget->allocation = *allocation;
+
+  child = GTK_BIN (widget)->child;
+  g_assert (child != NULL);
+
+  gtk_widget_size_allocate (child, allocation);
+}
+
+static void
 terminal_screen_init (TerminalScreen *screen)
 {
   screen->priv = g_new0 (TerminalScreenPrivate, 1);
@@ -235,9 +271,6 @@ terminal_screen_init (TerminalScreen *sc
   screen->priv->term = terminal_widget_new ();
 
   screen->priv->font_scale = PANGO_SCALE_MEDIUM;
-  
-  g_object_ref (G_OBJECT (screen->priv->term));
-  gtk_object_sink (GTK_OBJECT (screen->priv->term));
 
 #define USERCHARS "-A-Za-z0-9"
 #define PASSCHARS "-A-Za-z0-9,?;.:/!%$^*&~\"#'"
@@ -308,17 +341,33 @@ terminal_screen_init (TerminalScreen *sc
 
   connect_monospace_font_change (screen);
 
-  gtk_widget_show (screen->priv->term);
+  screen->priv->scrollbar = gtk_vscrollbar_new (NULL);
+
+  screen->priv->hbox = gtk_hbox_new (FALSE, 0);
+
+  gtk_box_pack_start (GTK_BOX (screen->priv->hbox), GTK_WIDGET (screen->priv->term), TRUE, TRUE, 0);
+                      
+  gtk_range_set_adjustment (GTK_RANGE (screen->priv->scrollbar),
+                            terminal_widget_get_scroll_adjustment (screen->priv->term));
+  
+  gtk_container_add (GTK_CONTAINER (screen), GTK_WIDGET (screen->priv->hbox));
+
+  gtk_widget_show_all (screen->priv->hbox);
 }
 
 static void
 terminal_screen_class_init (TerminalScreenClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+
   parent_class = g_type_class_peek_parent (klass);
   
   object_class->finalize = terminal_screen_finalize;
+
+  widget_class->size_allocate = terminal_screen_size_allocate;
+  widget_class->size_request = terminal_screen_size_request;
+  widget_class->map = terminal_screen_map;
   
   signals[PROFILE_SET] =
     g_signal_new ("profile_set",
@@ -390,8 +439,6 @@ terminal_screen_finalize (GObject *objec
     gtk_widget_destroy (screen->priv->title_editor);
   
   terminal_screen_set_profile (screen, NULL);
-  
-  g_object_unref (G_OBJECT (screen->priv->term));
 
   if (screen->priv->recheck_working_dir_idle)
     g_source_remove (screen->priv->recheck_working_dir_idle);
@@ -435,6 +482,19 @@ terminal_screen_new (void)
   return screen;
 }
 
+static void
+terminal_screen_map (GtkWidget *widget)
+{
+  GtkWidget *child;
+
+  g_assert (GTK_WIDGET_REALIZED (widget));
+
+  child = GTK_BIN (widget)->child;
+  g_assert (child != NULL);
+
+  GTK_WIDGET_CLASS (parent_class)->map (widget);
+}
+
 int
 terminal_screen_get_id (TerminalScreen *screen)
 {
@@ -508,7 +568,7 @@ reread_profile (TerminalScreen *screen)
       /* We need these in line for the set_size in
        * update_on_realize
        */
-      terminal_window_update_scrollbar (screen->priv->window, screen);
+      terminal_screen_update_scrollbar (screen);
       terminal_window_update_icon (screen->priv->window);
       terminal_window_update_geometry (screen->priv->window);
     }
@@ -910,6 +970,7 @@ terminal_screen_set_profile (TerminalScr
 
   if (screen->priv->profile)
     g_signal_emit (G_OBJECT (screen), signals[PROFILE_SET], 0);
+
 }
 
 TerminalProfile*
@@ -947,7 +1008,7 @@ static void
 show_command_error_dialog (TerminalScreen *screen,
                            GError         *error)
 {
-  g_return_if_fail (error != NULL);
+  g_assert (error != NULL);
   
   terminal_util_show_error_dialog ((GtkWindow*) gtk_widget_get_ancestor (screen->priv->term, GTK_TYPE_WINDOW), NULL,
                                    _("There was a problem with the command for this terminal: %s"), error->message);
@@ -1160,6 +1221,7 @@ new_window_callback (GtkWidget      *men
   terminal_app_new_terminal (terminal_app_get (),
                              terminal_profile_get_for_new_term (screen->priv->profile),
                              NULL,
+                             NULL,
                              FALSE, FALSE, FALSE,
                              NULL, NULL, NULL, dir, NULL, 1.0,
                              NULL, name, -1);
@@ -1178,6 +1240,7 @@ new_tab_callback (GtkWidget      *menu_i
   terminal_app_new_terminal (terminal_app_get (),
                              terminal_profile_get_for_new_term (screen->priv->profile),
                              screen->priv->window,
+                             NULL,
                              FALSE, FALSE, FALSE,
                              NULL, NULL, NULL, dir, NULL, 1.0,
                              NULL, NULL, -1);
@@ -2379,6 +2442,49 @@ terminal_screen_setup_dnd (TerminalScree
                      GDK_ACTION_COPY | GDK_ACTION_MOVE);
 }
 
+void
+terminal_screen_update_scrollbar (TerminalScreen *screen)
+{
+  TerminalProfile *profile;
+
+  profile = terminal_screen_get_profile (screen);
+
+  if (profile == NULL)
+    return;
+  
+  g_object_ref (G_OBJECT (screen->priv->scrollbar));
+
+  if (screen->priv->scrollbar->parent)
+    gtk_container_remove (GTK_CONTAINER (screen->priv->hbox), screen->priv->scrollbar);
+  
+  switch (terminal_profile_get_scrollbar_position (profile))
+    {
+    case TERMINAL_SCROLLBAR_HIDDEN:
+      gtk_widget_hide (screen->priv->scrollbar);
+      /* pack just to hold refcount */
+      gtk_box_pack_end (GTK_BOX (screen->priv->hbox),
+                        screen->priv->scrollbar, FALSE, FALSE, 0);
+      break;
+    case TERMINAL_SCROLLBAR_RIGHT:
+      gtk_box_pack_end (GTK_BOX (screen->priv->hbox),
+                        screen->priv->scrollbar, FALSE, FALSE, 0);
+      gtk_box_reorder_child (GTK_BOX (screen->priv->hbox), screen->priv->scrollbar, -1);
+      gtk_widget_show (screen->priv->scrollbar);
+      break;
+    case TERMINAL_SCROLLBAR_LEFT:
+      gtk_box_pack_start (GTK_BOX (screen->priv->hbox),
+                          screen->priv->scrollbar, FALSE, FALSE, 0);
+      gtk_box_reorder_child (GTK_BOX (screen->priv->hbox), screen->priv->scrollbar, 0);
+      gtk_widget_show (screen->priv->scrollbar);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  g_object_unref (G_OBJECT (screen->priv->scrollbar));
+}
+
 /* Indices of some xlfd string entries.  The first entry is 1 */
 #define XLFD_WEIGHT_INDEX			3
 #define XLFD_SLANT_INDEX			4	
--- orig/src/terminal-screen.h
+++ mod/src/terminal-screen.h
@@ -22,6 +22,8 @@
 #ifndef TERMINAL_SCREEN_H
 #define TERMINAL_SCREEN_H
 
+#include <gtk/gtkbin.h>
+
 #include "terminal-profile.h"
 
 G_BEGIN_DECLS
@@ -42,14 +44,14 @@ typedef struct _TerminalScreenPrivate Te
 
 struct _TerminalScreen
 {
-  GObject parent_instance;
+  GtkBin parent_instance;
 
   TerminalScreenPrivate *priv;
 };
 
 struct _TerminalScreenClass
 {
-  GObjectClass parent_class;
+  GtkBinClass parent_class;
 
   void (* profile_set)        (TerminalScreen *screen);
   void (* title_changed)      (TerminalScreen *screen);
@@ -110,6 +112,8 @@ void        terminal_screen_set_font_sca
                                                double          factor);
 double      terminal_screen_get_font_scale    (TerminalScreen *screen);
 
+void terminal_screen_update_scrollbar (TerminalScreen *screen);
+
 /* Allow scales a bit smaller and a bit larger than the usual pango ranges */
 #define TERMINAL_SCALE_XXX_SMALL   (PANGO_SCALE_XX_SMALL/1.2)
 #define TERMINAL_SCALE_XXXX_SMALL  (TERMINAL_SCALE_XXX_SMALL/1.2)
--- orig/src/terminal-window.c
+++ mod/src/terminal-window.c
@@ -24,6 +24,7 @@
 #include "terminal-accels.h"
 #include "terminal-widget.h"
 #include "terminal-window.h"
+#include "terminal-notebook.h"
 #include "terminal.h"
 #include "encoding.h"
 #include <string.h>
@@ -59,6 +60,9 @@ struct _TerminalWindowPrivate
   GtkWidget *choose_config_menuitem;
   GtkWidget *next_tab_menuitem;
   GtkWidget *previous_tab_menuitem;
+  GtkWidget *move_left_tab_menuitem;
+  GtkWidget *move_right_tab_menuitem;
+  GtkWidget *detach_tab_menuitem;
   GtkWidget *go_menu;
   GtkWidget *encoding_menuitem;
   GList *tab_menuitems;
@@ -101,27 +105,33 @@ static gboolean terminal_window_delete_e
                                               GdkEvent *event,
                                               gpointer data);
 
-static void       screen_set_scrollbar (TerminalScreen *screen,
-                                        GtkWidget      *scrollbar);
-static void       screen_set_hbox      (TerminalScreen *screen,
-                                        GtkWidget      *hbox);
-static void       screen_set_label     (TerminalScreen *screen,
-                                        GtkWidget      *label);
 static void       screen_set_menuitem  (TerminalScreen *screen,
                                         GtkWidget      *menuitem);
-static GtkWidget* screen_get_scrollbar (TerminalScreen *screen);
-static GtkWidget* screen_get_hbox      (TerminalScreen *screen);
-static GtkWidget* screen_get_label     (TerminalScreen *screen);
 static GtkWidget* screen_get_menuitem  (TerminalScreen *screen);
 
-static TerminalScreen* find_screen_by_hbox (TerminalWindow *window,
-                                            GtkWidget      *hbox);
+static TerminalScreen* find_screen (TerminalWindow *window,
+                                    TerminalScreen *screen);
 
 static void notebook_page_selected_callback (GtkWidget *notebook,
                                              GtkNotebookPage *useless_crap,
                                              int              page_num,
                                              TerminalWindow  *window);
 
+static void notebook_tab_added_callback     (GtkWidget       *notebook,
+                                             TerminalScreen  *screen,
+                                             TerminalWindow  *window);
+
+static void notebook_tab_detached_callback  (GtkWidget       *notebook,
+                                             TerminalScreen  *screen,
+                                             TerminalWindow  *window);
+
+static void notebook_tab_removed_callback   (GtkWidget       *notebook,
+                                             TerminalScreen  *screen,
+                                             TerminalWindow  *window);
+
+static void notebook_tabs_reordered_callback (GtkWidget      *notebook,
+                                              TerminalWindow *window);
+
 static void config_change_notify            (GConfClient *client,
                                              guint        cnxn_id,
                                              GConfEntry  *entry,
@@ -138,6 +148,11 @@ static void menuitem_icon_visibility    
 static void reset_menubar_labels          (TerminalWindow *window);
 static void reset_tab_menuitems           (TerminalWindow *window);
 
+static void new_window                    (TerminalWindow  *window,
+                                           TerminalScreen  *screen,
+                                           TerminalProfile *profile,
+                                           char            *name,
+                                           const char      *dir);
 static void new_window_callback           (GtkWidget      *menuitem,
                                            TerminalWindow *window);
 static void new_tab_callback              (GtkWidget      *menuitem,
@@ -184,6 +199,14 @@ static void next_tab_callback           
                                            TerminalWindow *window);
 static void previous_tab_callback         (GtkWidget      *menuitem,
                                            TerminalWindow *window);
+static void move_left_tab_callback        (GtkWidget      *menuitem,
+                                           TerminalWindow *window);
+static void move_right_tab_callback       (GtkWidget      *menuitem,
+                                           TerminalWindow *window);
+static void detach_tab                    (TerminalScreen *screen,
+                                           TerminalWindow *window);
+static void detach_tab_callback           (GtkWidget      *menuitem,
+                                           TerminalWindow *window);
 static void change_tab_callback           (GtkWidget      *menuitem,
                                            TerminalWindow *window);
 static void help_callback                 (GtkWidget      *menuitem,
@@ -790,7 +813,7 @@ terminal_window_init (TerminalWindow *wi
   window->priv->menubar_visible = FALSE;
   
   window->priv->main_vbox = gtk_vbox_new (FALSE, 0);
-  window->priv->notebook = gtk_notebook_new ();
+  window->priv->notebook = terminal_notebook_new ();
   
   window->priv->old_char_width = -1;
   window->priv->old_char_height = -1;
@@ -826,7 +849,27 @@ terminal_window_init (TerminalWindow *wi
                           "switch_page",
                           G_CALLBACK (notebook_page_selected_callback),
                           window);
+
+  g_signal_connect_after (G_OBJECT (window->priv->notebook),
+                          "tab_added",
+                          G_CALLBACK (notebook_tab_added_callback),
+                          window);
+
+  g_signal_connect_after (G_OBJECT (window->priv->notebook),
+                          "tab_detached",
+                          G_CALLBACK (notebook_tab_detached_callback),
+                          window);
+
+  g_signal_connect_after (G_OBJECT (window->priv->notebook),
+                          "tab_removed",
+                          G_CALLBACK (notebook_tab_removed_callback),
+                          window);
   
+  g_signal_connect_after (G_OBJECT (window->priv->notebook),
+                          "tabs_reordered",
+                          G_CALLBACK (notebook_tabs_reordered_callback),
+                          window);
+
   gtk_container_add (GTK_CONTAINER (window),
                      window->priv->main_vbox);
 
@@ -1020,6 +1063,24 @@ terminal_window_init (TerminalWindow *wi
 
   mi = gtk_separator_menu_item_new ();
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+  mi = append_menuitem (menu, _("Move Tab _Left"), ACCEL_PATH_MOVE_TAB_LEFT,
+                        G_CALLBACK (move_left_tab_callback), window);
+  window->priv->move_left_tab_menuitem = mi;
+  
+  mi = append_menuitem (menu, _("Move Tab _Right"), ACCEL_PATH_MOVE_TAB_RIGHT,
+                        G_CALLBACK (move_right_tab_callback), window);
+  window->priv->move_right_tab_menuitem = mi;
+
+  mi = gtk_separator_menu_item_new ();
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+  mi = append_menuitem (menu, _("Detach Tab"), ACCEL_PATH_DETACH_TAB,
+                        G_CALLBACK (detach_tab_callback), window);
+  window->priv->detach_tab_menuitem = mi;
+
+  mi = gtk_separator_menu_item_new ();
+  gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
   
   mi = append_menuitem (window->priv->menubar,
                         "", NULL,
@@ -1270,7 +1331,6 @@ update_notebook (TerminalWindow *window)
   single = g_list_length (window->priv->terms) == 1;
     
   gtk_notebook_set_show_border (GTK_NOTEBOOK (window->priv->notebook), !single);
-  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->priv->notebook), !single);
 }
 
 static void
@@ -1287,7 +1347,6 @@ static void
 title_changed_callback (TerminalScreen *screen,
                         TerminalWindow *window)
 {
-  GtkWidget *label;
   GtkWidget *mi;
   
   if (screen == window->priv->active_term) 
@@ -1300,9 +1359,6 @@ title_changed_callback (TerminalScreen *
       gdk_window_set_icon_name (GTK_WIDGET (window)->window, terminal_screen_get_title (screen));
     }
 
-  label = screen_get_label (screen);
-  gtk_label_set_text (GTK_LABEL (label), terminal_screen_get_title (screen));
-
   mi = screen_get_menuitem (screen);
   if (mi)
     gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (mi))),
@@ -1353,9 +1409,21 @@ update_tab_sensitivity (TerminalWindow *
 
   /* If there's only one tab, Close Tab is insensitive */
   if (page_num == 0 && on_last_page)
-    gtk_widget_set_sensitive (window->priv->close_tab_menuitem, FALSE);
+    {
+      gtk_widget_set_sensitive (window->priv->close_tab_menuitem, FALSE);
+      gtk_widget_set_sensitive (window->priv->detach_tab_menuitem, FALSE);
+      
+      gtk_widget_set_sensitive (window->priv->move_left_tab_menuitem, FALSE);
+      gtk_widget_set_sensitive (window->priv->move_right_tab_menuitem, FALSE);
+    }
   else
-    gtk_widget_set_sensitive (window->priv->close_tab_menuitem, TRUE);
+    {
+      gtk_widget_set_sensitive (window->priv->close_tab_menuitem, TRUE);
+      gtk_widget_set_sensitive (window->priv->detach_tab_menuitem, TRUE);
+      
+      gtk_widget_set_sensitive (window->priv->move_left_tab_menuitem, TRUE);
+      gtk_widget_set_sensitive (window->priv->move_right_tab_menuitem, TRUE);
+    }
   
   gtk_widget_set_sensitive (window->priv->next_tab_menuitem,
                             !on_last_page);
@@ -1373,11 +1441,7 @@ terminal_window_add_screen (TerminalWind
                             TerminalScreen *screen)
 {
   TerminalWindow *old;
-  GtkWidget *term;
-  GtkWidget *hbox;
-  GtkWidget *scrollbar;
-  GtkWidget *label;  
-  
+ 
   old = terminal_screen_get_window (screen);
 
   if (old == window)
@@ -1396,166 +1460,26 @@ terminal_window_add_screen (TerminalWind
 
   terminal_screen_set_window (screen, window);
 
-  hbox = gtk_hbox_new (FALSE, 0);
-  scrollbar = gtk_vscrollbar_new (NULL);
-  label = gtk_label_new (terminal_screen_get_title (screen));
-  gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
-  gtk_widget_show (label);
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  
-  screen_set_hbox (screen, hbox);
-  screen_set_scrollbar (screen, scrollbar);
-  screen_set_label (screen, label);
-
-  g_signal_connect (G_OBJECT (screen),
-                    "profile_set",
-                    G_CALLBACK (profile_set_callback),
-                    window);
-
-  g_signal_connect (G_OBJECT (screen),
-                    "title-changed",
-                    G_CALLBACK (title_changed_callback),
-                    window);
-
-  g_signal_connect (G_OBJECT (screen),
-                    "icon-title-changed",
-                    G_CALLBACK (icon_title_changed_callback),
-                    window);
-
-  g_signal_connect (G_OBJECT (screen),
-                    "selection-changed",
-                    G_CALLBACK (selection_changed_callback),
-                    window);
-  
-  term = terminal_screen_get_widget (screen);
-
-  gtk_box_pack_start (GTK_BOX (hbox),
-                      GTK_WIDGET (term), TRUE, TRUE, 0);
-  
-  gtk_range_set_adjustment (GTK_RANGE (scrollbar),
-                            terminal_widget_get_scroll_adjustment (term));
-
-  gtk_widget_show_all (hbox);
-  terminal_window_update_scrollbar (window, screen);
-  
-  update_notebook (window);
-  
-  gtk_notebook_append_page (GTK_NOTEBOOK (window->priv->notebook),
-                            hbox,
-                            label);
-
-  reset_tab_menuitems (window);
-  update_tab_sensitivity (window);
-  
-  /* Busting out the GtkNotebook crackrock features */
-  gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (window->priv->notebook),
-                                      hbox,
-                                      TRUE, TRUE, GTK_PACK_START);
-  
-  /* ZvtTerm is a broken POS and requires this realize to get
-   * the size request right.
-   */
-  gtk_widget_realize (GTK_WIDGET (term));
-
-  {
-    /* Match size to current active screen */
-    int current_width, current_height;
-    if (window->priv->active_term)
-      terminal_widget_get_size (terminal_screen_get_widget(window->priv->active_term), 
-                                &current_width, &current_height);
-    else
-      {
-        current_width = 80;
-        current_height = 24;
-      }
+  gtk_widget_show_all (GTK_WIDGET (screen));
 
-    terminal_widget_set_size (term, current_width, current_height);
-  }
-  
-  /* Make the first-added screen the active one */
-  if (window->priv->terms == NULL)
-    terminal_window_set_active (window, screen);
+  terminal_notebook_add_tab (TERMINAL_NOTEBOOK (window->priv->notebook),
+                             screen,
+                             -1,
+                             FALSE);
 }
 
 void
 terminal_window_remove_screen (TerminalWindow *window,
                                TerminalScreen *screen)
 {
-  int old_grid_width;
-  int old_grid_height;
-  
   g_return_if_fail (terminal_screen_get_window (screen) == window);
 
-  old_grid_width = -1;
-  old_grid_height = -1;
-  
-  if (window->priv->active_term == screen)
-    {
-      GtkWidget *old_active_widget;
-      
-      window->priv->active_term = NULL;
-
-      old_active_widget = terminal_screen_get_widget (screen);
-      terminal_widget_get_size (old_active_widget, &old_grid_width, &old_grid_height);
-    }
-      
   window->priv->terms = g_list_remove (window->priv->terms, screen);
-
-  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
-                                        G_CALLBACK (profile_set_callback),
-                                        window);
-
-  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
-                                        G_CALLBACK (title_changed_callback),
-                                        window);
-
-  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
-                                        G_CALLBACK (icon_title_changed_callback),
-                                        window);
-
-  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
-                                        G_CALLBACK (selection_changed_callback),
-                                        window);
   
   terminal_screen_set_window (screen, NULL);
   
-  gtk_container_remove (GTK_CONTAINER (window->priv->notebook),
-                        screen_get_hbox (screen));
-
-  screen_set_hbox (screen, NULL);
-  screen_set_label (screen, NULL);
-  screen_set_scrollbar (screen, NULL);
-  screen_set_menuitem (screen, NULL);
-  
-  g_object_unref (G_OBJECT (screen));
-  
-  update_notebook (window);
-
-  /* Put ourselves back in a sane state */
-  /* FIXME this block never gets called because removing a notebook page
-   * already emitted switch_page and updated the active terminal.
-   */
-  if (window->priv->active_term == NULL &&
-      window->priv->terms)
-    {
-      terminal_window_set_active (window, window->priv->terms->data);
-    }
-
-  if (window->priv->active_term)
-    {
-#ifdef DEBUG_GEOMETRY
-      g_print ("setting size with forced grid after removing a terminal\n");
-#endif
-      terminal_window_set_size_force_grid (window, window->priv->active_term,
-                                           TRUE, old_grid_width, old_grid_height);
-    }
-
-  reset_tab_menuitems (window);
-  update_tab_sensitivity (window);
-  
-  /* Close window if no more terminals */
-  if (window->priv->terms == NULL)
-    gtk_widget_destroy (GTK_WIDGET (window));
+  terminal_notebook_remove_tab (TERMINAL_NOTEBOOK (window->priv->notebook),
+                                screen);
 }
 
 GList*
@@ -1597,7 +1521,7 @@ terminal_window_set_menubar_visible (Ter
   if (window->priv->active_term)
     {
 #ifdef DEBUG_GEOMETRY
-      g_print ("setting size after toggling menubar visibility\n");
+      g_fprintf (stderr,"setting size after toggling menubar visibility\n");
 #endif
       terminal_window_set_size (window, window->priv->active_term, TRUE);
     }
@@ -1609,6 +1533,14 @@ terminal_window_get_menubar_visible (Ter
   return window->priv->menubar_visible;
 }
 
+GtkWidget *
+terminal_window_get_notebook (TerminalWindow *window)
+{
+	g_return_val_if_fail (TERMINAL_IS_WINDOW (window), NULL);
+
+	return GTK_WIDGET (window->priv->notebook);
+}
+
 void
 terminal_window_set_size (TerminalWindow *window,
                           TerminalScreen *screen,
@@ -1639,12 +1571,11 @@ terminal_window_set_size_force_grid (Ter
 
   /* be sure our geometry is up-to-date */
   terminal_window_update_geometry (window);
-  
   widget = terminal_screen_get_widget (screen);
   
   app = gtk_widget_get_toplevel (widget);
   g_assert (app != NULL);
-  
+
   /* This set_size_request hack is because the extra size above base
    * size should only include the width of widgets that intersect the
    * term vertically and the height of widgets that intersect the term
@@ -1657,7 +1588,7 @@ terminal_window_set_size_force_grid (Ter
   gtk_widget_size_request (widget, &widget_request);
 
 #ifdef DEBUG_GEOMETRY
-  g_print ("set size: toplevel %dx%d widget %dx%d\n",
+  g_fprintf (stderr,"set size: toplevel %dx%d widget %dx%d\n",
            toplevel_request.width, toplevel_request.height,
            widget_request.width, widget_request.height);
 #endif
@@ -1679,14 +1610,16 @@ terminal_window_set_size_force_grid (Ter
   h += ypad + char_height * grid_height;
 
 #ifdef DEBUG_GEOMETRY
-  g_print ("set size: grid %dx%d force %dx%d setting %dx%d pixels\n",
+  g_fprintf (stderr,"set size: grid %dx%d force %dx%d setting %dx%d pixels\n",
            grid_width, grid_height, force_grid_width, force_grid_height, w, h);
 #endif
-  
-  if (even_if_mapped && GTK_WIDGET_MAPPED (app))
+
+  if (even_if_mapped && GTK_WIDGET_MAPPED (app)) {
     gtk_window_resize (GTK_WINDOW (app), w, h);
-  else
+  }
+  else {
     gtk_window_set_default_size (GTK_WINDOW (app), w, h);
+  }
 }
 
 void
@@ -1702,10 +1635,10 @@ terminal_window_set_active (TerminalWind
   widget = terminal_screen_get_widget (screen);
   
   profile = terminal_screen_get_profile (screen);
-  
+
   if (!GTK_WIDGET_REALIZED (widget))
     gtk_widget_realize (widget); /* we need this for the char width */
-  
+
   window->priv->active_term = screen;
 
   terminal_window_update_geometry (window);
@@ -1725,11 +1658,11 @@ terminal_window_set_active (TerminalWind
 
   gtk_notebook_set_current_page (GTK_NOTEBOOK (window->priv->notebook),
                                  gtk_notebook_page_num (GTK_NOTEBOOK (window->priv->notebook),
-                                                        screen_get_hbox (screen)));
+                                                        GTK_WIDGET (screen)));
 
   /* set size of window to current grid size */
 #ifdef DEBUG_GEOMETRY
-  g_print ("setting size after flipping notebook pages\n");
+  g_fprintf (stderr,"setting size after flipping notebook pages\n");
 #endif
   terminal_window_set_size (window, screen, TRUE);
   
@@ -1749,33 +1682,6 @@ terminal_window_get_active (TerminalWind
 }
 
 static void
-screen_set_scrollbar (TerminalScreen *screen,
-                      GtkWidget      *scrollbar)
-{
-  g_object_set_data (G_OBJECT (screen),
-                     "scrollbar",
-                     scrollbar);
-}
-
-static void
-screen_set_hbox (TerminalScreen *screen,
-                 GtkWidget      *hbox)
-{
-  g_object_set_data (G_OBJECT (screen),
-                     "hbox",
-                     hbox);
-}
-
-static void
-screen_set_label (TerminalScreen *screen,
-                  GtkWidget      *label)
-{
-  g_object_set_data (G_OBJECT (screen),
-                     "label",
-                     label);
-}
-
-static void
 screen_set_menuitem  (TerminalScreen *screen,
                       GtkWidget      *menuitem)
 {
@@ -1785,39 +1691,21 @@ screen_set_menuitem  (TerminalScreen *sc
 }
 
 static GtkWidget*
-screen_get_scrollbar (TerminalScreen *screen)
-{
-  return g_object_get_data (G_OBJECT (screen), "scrollbar");
-}
-
-static GtkWidget*
-screen_get_hbox (TerminalScreen *screen)
-{
-  return g_object_get_data (G_OBJECT (screen), "hbox");
-}
-
-static GtkWidget*
-screen_get_label (TerminalScreen *screen)
-{
-  return g_object_get_data (G_OBJECT (screen), "label");
-}
-
-static GtkWidget*
 screen_get_menuitem (TerminalScreen *screen)
 {
   return g_object_get_data (G_OBJECT (screen), "menuitem");
 }
 
 static TerminalScreen*
-find_screen_by_hbox (TerminalWindow *window,
-                     GtkWidget      *hbox)
+find_screen (TerminalWindow *window,
+             TerminalScreen *screen)
 {
   GList *tmp;
 
   tmp = window->priv->terms;
   while (tmp != NULL)
     {
-      if (screen_get_hbox (tmp->data) == hbox)
+      if (tmp->data == screen)
         return tmp->data;
 
       tmp = tmp->next;
@@ -1842,18 +1730,18 @@ notebook_page_selected_callback (GtkWidg
   old_grid_width = -1;
   old_grid_height = -1;
 
-  if (window->priv->active_term)
-    {
-      old_widget = terminal_screen_get_widget (window->priv->active_term);
-      terminal_widget_get_size (old_widget, &old_grid_width, &old_grid_height);
-    }
+  if (window->priv->active_term == NULL)
+    return;
+
+  old_widget = terminal_screen_get_widget (window->priv->active_term);
+  terminal_widget_get_size (old_widget, &old_grid_width, &old_grid_height);
   
   page_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook),
                                            page_num);
 
   g_assert (page_widget);
 
-  screen = find_screen_by_hbox (window, page_widget);
+  screen = TERMINAL_SCREEN (page_widget);
 
   g_assert (screen);
 
@@ -1863,7 +1751,7 @@ notebook_page_selected_callback (GtkWidg
    * different fonts.
    */
 #ifdef DEBUG_GEOMETRY
-  g_print ("setting size in switch_page handler\n");
+  g_fprintf (stderr,"setting size in switch_page handler\n");
 #endif
   terminal_window_set_size_force_grid (window, screen, TRUE, old_grid_width, old_grid_height);
   
@@ -1876,53 +1764,134 @@ notebook_page_selected_callback (GtkWidg
                                     TRUE);
 }
 
-void
-terminal_window_update_scrollbar (TerminalWindow *window,
-                                  TerminalScreen *screen)
+static void
+notebook_tab_added_callback (GtkWidget       *notebook,
+                               TerminalScreen  *screen,
+                               TerminalWindow  *window)
 {
-  GtkWidget *scrollbar;
-  GtkWidget *hbox;
-  TerminalProfile *profile;
+  GtkWidget *term;
 
-  profile = terminal_screen_get_profile (screen);
+  /* Moved from another window */
+  if (find_screen (window, screen) == NULL) {
+    g_object_ref (G_OBJECT (screen)); /* make our own new refcount */
+  
+    /* keep this list in same order as tabs in notebook,
+     * so that terminal_window_list_screens() returns screens
+     * in tab order
+     */
+    window->priv->terms = g_list_append (window->priv->terms, screen);
+  
+    terminal_screen_set_window (screen, window);
+  }
+  
+  g_signal_connect (G_OBJECT (screen),
+                    "profile_set",
+                    G_CALLBACK (profile_set_callback),
+                    window);
 
-  if (profile == NULL)
-    return;
+  g_signal_connect (G_OBJECT (screen),
+                    "title-changed",
+                    G_CALLBACK (title_changed_callback),
+                    window);
+
+  g_signal_connect (G_OBJECT (screen),
+                    "icon-title-changed",
+                    G_CALLBACK (icon_title_changed_callback),
+                    window);
+
+  g_signal_connect (G_OBJECT (screen),
+                    "selection-changed",
+                    G_CALLBACK (selection_changed_callback),
+                    window);
+
+  terminal_screen_update_scrollbar (screen);
+
+  update_notebook (window);
+
+  reset_tab_menuitems (window);
+  update_tab_sensitivity (window);
   
-  scrollbar = screen_get_scrollbar (screen);
-  hbox = screen_get_hbox (screen);
+  term = terminal_screen_get_widget (screen);
+
+  /* ZvtTerm is a broken POS and requires this realize to get
+   * the size request right.
+   */
+  gtk_widget_realize (GTK_WIDGET (term));
+
+  {
+    /* Match size to current active screen */
+    int current_width, current_height;
+    if (window->priv->active_term)
+      terminal_widget_get_size (terminal_screen_get_widget(window->priv->active_term), 
+                                &current_width, &current_height);
+    else
+      {
+        current_width = 80;
+        current_height = 24;
+      }
+
+    terminal_widget_set_size (term, current_width, current_height);
+  }
   
-  g_object_ref (G_OBJECT (scrollbar));
+  /* Make the first-added screen the active one */
+  if (window->priv->active_term == NULL)
+    terminal_window_set_active (window, screen);
+}
+
+static void
+notebook_tab_detached_callback (GtkWidget       *notebook,
+                                TerminalScreen  *screen,
+                                TerminalWindow  *window)
+{
+  detach_tab (screen, window);
+}
 
-  if (scrollbar->parent)
-    gtk_container_remove (GTK_CONTAINER (hbox), scrollbar);
+static void
+notebook_tab_removed_callback (GtkWidget       *notebook,
+                               TerminalScreen  *screen,
+                               TerminalWindow  *window)
+{  
+  /* Called from terminal_notebook_move_tab() */
+  if (find_screen (window, screen) != NULL) {
+    g_assert (terminal_screen_get_window (screen) == window);
   
-  switch (terminal_profile_get_scrollbar_position (profile))
-    {
-    case TERMINAL_SCROLLBAR_HIDDEN:
-      gtk_widget_hide (scrollbar);
-      /* pack just to hold refcount */
-      gtk_box_pack_end (GTK_BOX (hbox),
-                        scrollbar, FALSE, FALSE, 0);
-      break;
-    case TERMINAL_SCROLLBAR_RIGHT:
-      gtk_box_pack_end (GTK_BOX (hbox),
-                        scrollbar, FALSE, FALSE, 0);
-      gtk_box_reorder_child (GTK_BOX (hbox), scrollbar, -1);
-      gtk_widget_show (scrollbar);
-      break;
-    case TERMINAL_SCROLLBAR_LEFT:
-      gtk_box_pack_start (GTK_BOX (hbox),
-                          scrollbar, FALSE, FALSE, 0);
-      gtk_box_reorder_child (GTK_BOX (hbox), scrollbar, 0);
-      gtk_widget_show (scrollbar);
-      break;
-    default:
-      g_assert_not_reached ();
-      break;
-    }
+    window->priv->terms = g_list_remove (window->priv->terms, screen);
+    terminal_screen_set_window (screen, NULL);
+  }
+  
+  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
+                                        G_CALLBACK (profile_set_callback),
+                                        window);
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
+                                        G_CALLBACK (title_changed_callback),
+                                        window);
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
+                                        G_CALLBACK (icon_title_changed_callback),
+                                        window);
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (screen),
+                                        G_CALLBACK (selection_changed_callback),
+                                        window);
+
+  screen_set_menuitem (screen, NULL);
+  
+  update_notebook (window);
+
+  reset_tab_menuitems (window);
+  update_tab_sensitivity (window);
 
-  g_object_unref (G_OBJECT (scrollbar));
+  /* Close window if no more terminals */
+  if (window->priv->terms == NULL)
+    gtk_widget_destroy (GTK_WIDGET (window));
+}
+
+static void
+notebook_tabs_reordered_callback (GtkWidget       *notebook,
+                                 TerminalWindow  *window)
+{
+	reset_tab_menuitems(window);
 }
 
 void
@@ -2012,7 +1981,7 @@ terminal_window_update_geometry (Termina
                                      GDK_HINT_BASE_SIZE);
 
 #ifdef DEBUG_GEOMETRY
-      g_print ("hints: base %dx%d min %dx%d inc %d %d\n",
+      g_fprintf (stderr,"hints: base %dx%d min %dx%d inc %d %d\n",
                hints.base_width,
                hints.base_height,
                hints.min_width,
@@ -2028,7 +1997,7 @@ terminal_window_update_geometry (Termina
 #ifdef DEBUG_GEOMETRY
   else
     {
-      g_print ("hints: increment unchanged, not setting\n");
+      g_fprintf (stderr,"hints: increment unchanged, not setting\n");
     }
 #endif
 }
@@ -2174,7 +2143,7 @@ reset_tab_menuitems (TerminalWindow *win
       if (page == NULL)
         break;
       
-      screen = find_screen_by_hbox (window, page);
+      screen = TERMINAL_SCREEN (page);
 
       menu_item = gtk_radio_menu_item_new_with_label (group,
                                                       terminal_screen_get_title (screen));
@@ -2265,18 +2234,29 @@ new_window_callback (GtkWidget      *men
       name = gdk_screen_make_display_name (gtk_widget_get_screen (menuitem));
       dir = terminal_screen_get_working_dir (window->priv->active_term);
 
-      terminal_app_new_terminal (terminal_app_get (),
-                                 profile,
-                                 NULL,
-                                 FALSE, FALSE, FALSE,
-                                 NULL, NULL, NULL, dir, NULL, 1.0,
-                                 NULL, name, -1);
+      new_window (window, NULL, profile, name, dir);
 
       g_free (name);
     }
 }
 
 static void
+new_window (TerminalWindow *window,
+            TerminalScreen *screen,
+            TerminalProfile *profile,
+            char *name,
+            const char *dir)
+{
+  terminal_app_new_terminal (terminal_app_get (),
+                             profile,
+                             NULL,
+                             screen,
+                             FALSE, FALSE, FALSE,
+                             NULL, NULL, NULL, dir, NULL, 1.0,
+                             NULL, name, -1);
+}
+
+static void
 new_tab_callback (GtkWidget      *menuitem,
                   TerminalWindow *window)
 {
@@ -2296,6 +2276,7 @@ new_tab_callback (GtkWidget      *menuit
       terminal_app_new_terminal (terminal_app_get (),
                                  profile,
                                  window,
+                                 NULL,
                                  FALSE, FALSE, FALSE,
                                  NULL, NULL, NULL, dir, NULL, 1.0,
                                  NULL, NULL, -1);
@@ -2690,6 +2671,96 @@ previous_tab_callback (GtkWidget      *m
 }
 
 static void
+move_left_tab_callback(GtkWidget      *menuitem,
+                       TerminalWindow *window)
+{
+  GtkNotebook *notebook;
+  gint page_num,last_page;
+  GtkWidget *page; 
+
+  notebook = GTK_NOTEBOOK (window->priv->notebook);
+  page_num = gtk_notebook_get_current_page (notebook);
+  last_page = gtk_notebook_get_n_pages (notebook) - 1;
+  page = gtk_notebook_get_nth_page (notebook, page_num);
+  
+  if (page_num == 0)
+    terminal_notebook_move_tab (TERMINAL_NOTEBOOK (notebook), NULL,
+                                TERMINAL_SCREEN (page), last_page);
+  else
+    terminal_notebook_move_tab (TERMINAL_NOTEBOOK (notebook), NULL,
+                                TERMINAL_SCREEN (page), page_num-1);
+
+  update_tab_sensitivity (window);
+  reset_tab_menuitems (window);
+}
+
+static void
+move_right_tab_callback(GtkWidget      *menuitem,
+                        TerminalWindow *window)
+{
+  GtkNotebook *notebook;
+  gint page_num,last_page;
+  GtkWidget *page; 
+
+  notebook = GTK_NOTEBOOK (window->priv->notebook);
+  page_num = gtk_notebook_get_current_page (notebook);
+  last_page = gtk_notebook_get_n_pages (notebook) - 1;
+  page = gtk_notebook_get_nth_page (notebook, page_num);
+  
+  if (page_num == last_page)
+    terminal_notebook_move_tab (TERMINAL_NOTEBOOK (notebook), NULL,
+                                TERMINAL_SCREEN (page), 0);
+  else
+    terminal_notebook_move_tab (TERMINAL_NOTEBOOK (notebook), NULL,
+                                TERMINAL_SCREEN (page), page_num+1);
+
+  update_tab_sensitivity (window);
+  reset_tab_menuitems (window);
+}
+
+static void
+detach_tab (TerminalScreen  *screen,
+            TerminalWindow  *window)
+{
+  TerminalProfile *profile;
+
+  profile = terminal_screen_get_profile (screen);
+
+  g_assert (profile);
+
+  if (!terminal_profile_get_forgotten (profile))
+    {
+      char *name;
+      const char *dir;
+
+      name = gdk_screen_make_display_name (gtk_widget_get_screen (GTK_WIDGET (window)));
+      dir = terminal_screen_get_working_dir (window->priv->active_term);
+
+      new_window (window, screen, profile, name, dir);
+
+      g_free (name);
+    }
+}
+
+static void
+detach_tab_callback(GtkWidget      *menuitem,
+                    TerminalWindow *window)
+{
+  GtkNotebook *notebook;
+  gint page_num,last_page;
+  GtkWidget *page; 
+
+  notebook = GTK_NOTEBOOK (window->priv->notebook);
+  page_num = gtk_notebook_get_current_page (notebook);
+  page = gtk_notebook_get_nth_page (notebook, page_num);
+  
+  detach_tab (TERMINAL_SCREEN (page), window);
+  
+  update_tab_sensitivity (window);
+  reset_tab_menuitems (window);
+}
+
+static void
 change_tab_callback (GtkWidget      *menuitem,
                      TerminalWindow *window)
 {
--- orig/src/terminal-window.h
+++ mod/src/terminal-window.h
@@ -76,8 +76,6 @@ TerminalScreen* terminal_window_get_acti
 GList* terminal_window_list_screens (TerminalWindow *window);
 int    terminal_window_get_screen_count (TerminalWindow *window);
 
-void terminal_window_update_scrollbar (TerminalWindow *window,
-                                       TerminalScreen *screen);
 void terminal_window_update_icon      (TerminalWindow *window);
 void terminal_window_update_geometry  (TerminalWindow *window);
 void terminal_window_set_size         (TerminalWindow *window,
@@ -93,6 +91,8 @@ void     terminal_window_set_fullscreen 
                                          gboolean        setting);
 gboolean terminal_window_get_fullscreen (TerminalWindow *window);
 
+GtkWidget* terminal_window_get_notebook (TerminalWindow *window);
+
 void terminal_window_reread_profile_list (TerminalWindow *window);
 
 void terminal_window_set_startup_id (TerminalWindow *window,
--- orig/src/terminal.c
+++ mod/src/terminal.c
@@ -25,6 +25,7 @@
 #include "terminal.h"
 #include "terminal-accels.h"
 #include "terminal-window.h"
+#include "terminal-notebook.h"
 #include "terminal-widget.h"
 #include "profile-editor.h"
 #include "encoding.h"
@@ -1432,6 +1433,7 @@ new_terminal_with_options (OptionParsing
               terminal_app_new_terminal (app,
                                          profile,
                                          NULL,
+                                         NULL,
                                          iw->force_menubar_state,
                                          iw->menubar_state,
                                          iw->start_fullscreen,
@@ -1453,6 +1455,7 @@ new_terminal_with_options (OptionParsing
               terminal_app_new_terminal (app,
                                          profile,
                                          current_window,
+                                         NULL,
                                          FALSE, FALSE,
                                          FALSE/*not fullscreen*/,
                                          it->exec_argv,
@@ -1884,6 +1887,7 @@ void
 terminal_app_new_terminal (TerminalApp     *app,
                            TerminalProfile *profile,
                            TerminalWindow  *window,
+                           TerminalScreen  *screen,
                            gboolean         force_menubar_state,
                            gboolean         forced_menubar_state,
                            gboolean         start_fullscreen,
@@ -1897,15 +1901,15 @@ terminal_app_new_terminal (TerminalApp  
                            const char      *display_name,
                            int              screen_number)
 {
-  TerminalScreen *screen;
   gboolean window_created;
+  gboolean screen_created;
   
   g_return_if_fail (profile);
 
   window_created = FALSE;
   if (window == NULL)
     {
-      GdkScreen *screen;
+      GdkScreen *gdk_screen;
       
       window_created = TRUE;
       window = terminal_window_new (conf);
@@ -1917,11 +1921,11 @@ terminal_app_new_terminal (TerminalApp  
       
       app->windows = g_list_append (app->windows, window);
 
-      screen = find_screen_by_display_name (display_name, screen_number);
-      if (screen != NULL)
+      gdk_screen = find_screen_by_display_name (display_name, screen_number);
+      if (gdk_screen != NULL)
         {
-          gtk_window_set_screen (GTK_WINDOW (window), screen);
-          g_object_unref (G_OBJECT (screen));
+          gtk_window_set_screen (GTK_WINDOW (window), gdk_screen);
+          g_object_unref (G_OBJECT (gdk_screen));
         }
 
       if (startup_id != NULL)
@@ -1937,27 +1941,40 @@ terminal_app_new_terminal (TerminalApp  
     {
       terminal_window_set_menubar_visible (window, forced_menubar_state);
     }
-  
-  screen = terminal_screen_new ();
-  
-  terminal_screen_set_profile (screen, profile);
-
-  if (title)
-    terminal_screen_set_dynamic_title (screen, title);
 
-  if (working_dir)
-    terminal_screen_set_working_dir (screen, working_dir);
-  
-  if (override_command)    
-    terminal_screen_set_override_command (screen, override_command);
-
-  terminal_screen_set_font_scale (screen, zoom);
-  
-  terminal_window_add_screen (window, screen);
-
-  g_object_unref (G_OBJECT (screen));
+  screen_created = FALSE;
+  if (screen == NULL)
+    {  
+      screen_created = TRUE;
+      screen = terminal_screen_new ();
+      
+      terminal_screen_set_profile (screen, profile);
+    
+      if (title)
+        terminal_screen_set_dynamic_title (screen, title);
+    
+      if (working_dir)
+        terminal_screen_set_working_dir (screen, working_dir);
+      
+      if (override_command)    
+        terminal_screen_set_override_command (screen, override_command);
+    
+      terminal_screen_set_font_scale (screen, zoom);
+    
+      terminal_window_add_screen (window, screen);
 
-  terminal_window_set_active (window, screen);
+      g_object_unref (G_OBJECT (screen));
+    
+      terminal_window_set_active (window, screen);
+    }
+  else
+   {
+      TerminalWindow *src_win = terminal_screen_get_window (screen);
+      TerminalNotebook *src_notebook = terminal_window_get_notebook (src_win);
+      TerminalNotebook *dest_notebook = terminal_window_get_notebook (window);
+      
+      terminal_notebook_move_tab (src_notebook, dest_notebook, screen, 0);
+    }
 
   if (geometry)
     {
@@ -1979,7 +1996,8 @@ terminal_app_new_terminal (TerminalApp  
   if (window_created)
     gtk_window_present (GTK_WINDOW (window));
 
-  terminal_screen_launch_child (screen);
+  if (screen_created)
+    terminal_screen_launch_child (screen);
 }
 
 static GList*
--- orig/src/terminal.h
+++ mod/src/terminal.h
@@ -42,6 +42,7 @@ void terminal_app_new_profile (TerminalA
 void terminal_app_new_terminal (TerminalApp     *app,
                                 TerminalProfile *profile,
                                 TerminalWindow  *window,
+                                TerminalScreen  *screen,
                                 gboolean         force_menubar_state,
                                 gboolean         forced_menubar_state,
                                 gboolean         start_fullscreen,

* added files

--- /dev/null
+++ mod/src/terminal-notebook.c
@@ -0,0 +1,670 @@
+/*
+ *  Copyright (C) 2002 Christophe Fergeau
+ *  Copyright (C) 2003, 2004 Marco Pesenti Gritti
+ *  Copyright (C) 2003, 2004 Christian Persch
+ *  Copyright (C) 2005 Tony Tsui
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "terminal-notebook.h"
+#include "terminal-window.h"
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+#include <glib/gprintf.h>
+#define LOG g_printf
+
+#define AFTER_ALL_TABS -1
+#define NOT_IN_APP_WINDOWS -2
+
+#define TERMINAL_NOTEBOOK_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), TERMINAL_TYPE_NOTEBOOK, TerminalNotebookPrivate))
+
+struct _TerminalNotebookPrivate
+{
+  gulong   motion_notify_handler_id;
+  gint     x_start, y_start;
+  gboolean drag_in_progress;
+};
+
+static void terminal_notebook_init           (TerminalNotebook *notebook);
+static void terminal_notebook_class_init     (TerminalNotebookClass *klass);
+static void terminal_notebook_finalize       (GObject *object);
+static void move_tab_to_another_notebook     (TerminalNotebook *src,
+                                              TerminalNotebook *dest,
+                                              GdkEventMotion   *event,
+                                              int               dest_position);
+
+/* Local variables */
+static GdkCursor *cursor = NULL;
+
+enum
+{
+  TAB_ADDED,
+  TAB_REMOVED,
+  TABS_REORDERED,
+  TAB_DETACHED,
+  TAB_DELETE,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static GObjectClass *parent_class = NULL;
+
+GType
+terminal_notebook_get_type (void)
+{
+  static GType type = 0;
+
+  if (G_UNLIKELY (type == 0))
+    {
+      static const GTypeInfo our_info =
+        {
+          sizeof (TerminalNotebookClass),
+          NULL, /* base_init */
+          NULL, /* base_finalize */
+          (GClassInitFunc) terminal_notebook_class_init,
+          NULL,
+          NULL, /* class_data */
+          sizeof (TerminalNotebook),
+          0, /* n_preallocs */
+          (GInstanceInitFunc) terminal_notebook_init
+        };
+  
+      type = g_type_register_static (GTK_TYPE_NOTEBOOK,
+                                     "TerminalNotebook",
+                                     &our_info, 0);
+  
+    }
+
+  return type;
+}
+
+static void
+terminal_notebook_class_init (TerminalNotebookClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = terminal_notebook_finalize;
+
+  signals[TAB_ADDED] =
+    g_signal_new ("tab_added",
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (TerminalNotebookClass, tab_added),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1,
+                  TERMINAL_TYPE_SCREEN);
+  signals[TAB_REMOVED] =
+    g_signal_new ("tab_removed",
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (TerminalNotebookClass, tab_removed),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1,
+                  TERMINAL_TYPE_SCREEN);
+  signals[TAB_DETACHED] =
+    g_signal_new ("tab_detached",
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (TerminalNotebookClass, tab_detached),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE,
+                  1,
+                  TERMINAL_TYPE_SCREEN);
+  signals[TABS_REORDERED] =
+    g_signal_new ("tabs_reordered",
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (TerminalNotebookClass, tabs_reordered),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE,
+                  0);
+
+  g_type_class_add_private (object_class, sizeof(TerminalNotebookPrivate));
+}
+
+static TerminalNotebook *
+find_notebook_at_pointer (gint abs_x, gint abs_y)
+{
+  GdkWindow *win_at_pointer, *toplevel_win;
+  gpointer toplevel = NULL;
+  gint x, y;
+
+  /* FIXME multi-head */
+  win_at_pointer = gdk_window_at_pointer (&x, &y);
+  if (win_at_pointer == NULL)
+    {
+      /* We are outside all windows containing a notebook */
+      return NULL;
+    }
+
+  toplevel_win = gdk_window_get_toplevel (win_at_pointer);
+
+  /* get the GtkWidget which owns the toplevel GdkWindow */
+  gdk_window_get_user_data (toplevel_win, &toplevel);
+
+  /* toplevel should be an TerminalWindow */
+  if (toplevel != NULL && TERMINAL_IS_WINDOW (toplevel))
+    {
+      return TERMINAL_NOTEBOOK (terminal_window_get_notebook
+                                (TERMINAL_WINDOW (toplevel)));
+    }
+
+  return NULL;
+}
+
+static gboolean
+is_in_notebook_window (TerminalNotebook *notebook,
+                       gint abs_x, gint abs_y)
+{
+  TerminalNotebook *nb_at_pointer;
+
+  nb_at_pointer = find_notebook_at_pointer (abs_x, abs_y);
+
+  return nb_at_pointer == notebook;
+}
+
+static gint
+find_tab_num_at_pos (TerminalNotebook *notebook, gint abs_x, gint abs_y)
+{
+  GtkPositionType tab_pos;
+  int page_num = 0;
+  GtkNotebook *nb = GTK_NOTEBOOK (notebook);
+  GtkWidget *page;
+
+  tab_pos = gtk_notebook_get_tab_pos (GTK_NOTEBOOK (notebook));
+
+  if (GTK_NOTEBOOK (notebook)->first_tab == NULL)
+    {
+      return AFTER_ALL_TABS;
+    }
+
+  while ((page = gtk_notebook_get_nth_page (nb, page_num)))
+    {
+      GtkWidget *screen;
+      gint max_x, max_y;
+      gint x_root, y_root;
+  
+      screen = gtk_notebook_get_tab_label (nb, page);
+      g_return_val_if_fail (screen != NULL, -1);
+  
+      if (!GTK_WIDGET_MAPPED (GTK_WIDGET (screen)))
+       {
+         page_num++;
+         continue;
+       }
+  
+      gdk_window_get_origin (GDK_WINDOW (screen->window),
+                             &x_root, &y_root);
+  
+      max_x = x_root + screen->allocation.x + screen->allocation.width;
+      max_y = y_root + screen->allocation.y + screen->allocation.height;
+  
+      if (((tab_pos == GTK_POS_TOP) || (tab_pos == GTK_POS_BOTTOM))
+          &&(abs_x<=max_x))
+        {
+          return page_num;
+        }
+      else if (((tab_pos == GTK_POS_LEFT) || (tab_pos == GTK_POS_RIGHT))
+               && (abs_y<=max_y))
+        {
+          return page_num;
+        }
+  
+      page_num++;
+    }
+  return AFTER_ALL_TABS;
+}
+
+static gint find_notebook_and_tab_at_pos (gint abs_x, gint abs_y,
+                                          TerminalNotebook **notebook,
+                                          gint *page_num)
+{
+  *notebook = find_notebook_at_pointer (abs_x, abs_y);
+  if (*notebook == NULL)
+    {
+      return NOT_IN_APP_WINDOWS;
+    }
+  *page_num = find_tab_num_at_pos (*notebook, abs_x, abs_y);
+
+  if (*page_num < 0)
+    {
+      return *page_num;
+    }
+  else
+    {
+      return 0;
+    }
+}
+
+void
+terminal_notebook_move_tab (TerminalNotebook *src,
+                            TerminalNotebook *dest,
+                            TerminalScreen *screen,
+                            int dest_position)
+{
+  if (dest == NULL || src == dest)
+    {
+      gtk_notebook_reorder_child
+        (GTK_NOTEBOOK (src), GTK_WIDGET (screen), dest_position);
+      
+      if (src->priv->drag_in_progress == FALSE)
+        {
+          g_signal_emit (G_OBJECT (src), signals[TABS_REORDERED], 0);
+        }
+    }
+  else
+    {
+      GtkWidget *toplevel;
+
+      /* make sure the screen isn't destroyed while we move it */
+      g_object_ref (screen);
+
+      terminal_notebook_remove_tab (src, screen);
+
+      /* Set new window for screen so TerminalScreen widget realize function
+       * works.
+       */
+      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (dest));
+      
+      g_assert (GTK_WIDGET_TOPLEVEL (toplevel));
+      g_assert (TERMINAL_IS_WINDOW (toplevel));
+
+      terminal_screen_set_window (screen, TERMINAL_WINDOW(toplevel));
+   
+      terminal_notebook_add_tab (dest, screen, dest_position, TRUE);
+      g_object_unref (screen);
+    }
+}
+
+static void
+drag_start (TerminalNotebook *notebook)
+{
+  notebook->priv->drag_in_progress = TRUE;
+
+  /* get a new cursor, if necessary */
+  if (!cursor) cursor = gdk_cursor_new (GDK_FLEUR);
+
+  /* grab the pointer */
+  gtk_grab_add (GTK_WIDGET (notebook));
+  if (!gdk_pointer_is_grabbed ())
+    {
+      gdk_pointer_grab (GDK_WINDOW(GTK_WIDGET (notebook)->window),
+                        FALSE,
+                        GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
+                        NULL, cursor, GDK_CURRENT_TIME);
+    }
+}
+
+static void
+drag_stop (TerminalNotebook *notebook)
+{
+  if (notebook->priv->drag_in_progress)
+    {
+      g_signal_emit (G_OBJECT (notebook), signals[TABS_REORDERED], 0);
+    }
+
+  notebook->priv->drag_in_progress = FALSE;
+  if (notebook->priv->motion_notify_handler_id != 0)
+    {
+      g_signal_handler_disconnect (G_OBJECT (notebook),
+                                   notebook->priv->motion_notify_handler_id);
+      notebook->priv->motion_notify_handler_id = 0;
+    }
+}
+
+/* this function is only called during dnd, we don't need to emit TABS_REORDERED
+ * here, instead we do it on drag_stop
+ */
+static void
+move_tab (TerminalNotebook *notebook,
+          int dest_position)
+{
+  gint cur_page_num;
+
+  cur_page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
+
+  if (dest_position != cur_page_num)
+    {
+      GtkWidget *cur_tab;
+      
+      cur_tab = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook),
+                                           cur_page_num);
+      terminal_notebook_move_tab (TERMINAL_NOTEBOOK (notebook), NULL,
+                                  TERMINAL_SCREEN (cur_tab),
+                                  dest_position);
+    }
+}
+
+static gboolean
+motion_notify_cb (TerminalNotebook *notebook,
+                  GdkEventMotion *event,
+                  gpointer data)
+{
+  TerminalNotebook *dest;
+  gint page_num;
+  gint result;
+
+  if (notebook->priv->drag_in_progress == FALSE)
+    {
+      if (gtk_drag_check_threshold (GTK_WIDGET (notebook),
+                                    notebook->priv->x_start,
+                                    notebook->priv->y_start,
+                                    event->x_root, event->y_root))
+        {
+          drag_start (notebook);
+        }
+      else
+        {
+          return FALSE;
+        }
+    }
+
+  result = find_notebook_and_tab_at_pos ((gint)event->x_root,
+                                         (gint)event->y_root,
+                                         &dest, &page_num);
+
+  if (result != NOT_IN_APP_WINDOWS)
+    {
+      if (dest != notebook)
+        {
+          move_tab_to_another_notebook (notebook, dest,
+                                        event, page_num);
+        }
+      else
+        {
+          g_assert (page_num >= -1);
+          move_tab (notebook, page_num);
+        }
+    }
+
+  return FALSE;
+}
+
+static void
+move_tab_to_another_notebook (TerminalNotebook *src,
+                              TerminalNotebook *dest,
+                              GdkEventMotion *event,
+                              int dest_position)
+{
+  GtkWidget *screen;
+  int cur_page;
+
+  /* This is getting tricky, the screen was dragged in a notebook
+   * in another window of the same app, we move the screen
+   * to that new notebook, and let this notebook handle the
+   * drag
+  */
+  g_assert (TERMINAL_IS_NOTEBOOK (dest));
+  g_assert (dest != src);
+
+  cur_page = gtk_notebook_get_current_page (GTK_NOTEBOOK (src));
+  screen = gtk_notebook_get_nth_page (GTK_NOTEBOOK (src), cur_page);
+
+  /* stop drag in origin window */
+  /* ungrab the pointer if it's grabbed */
+  drag_stop (src);
+  if (gdk_pointer_is_grabbed ())
+    {
+      gdk_pointer_ungrab (event->time);
+    }
+  gtk_grab_remove (GTK_WIDGET (src));
+
+  terminal_notebook_move_tab (src, dest, TERMINAL_SCREEN (screen),
+                              dest_position);
+
+  /* start drag handling in dest notebook */
+  drag_start (dest);
+
+  dest->priv->motion_notify_handler_id =
+    g_signal_connect (G_OBJECT (dest),
+                      "motion-notify-event",
+                      G_CALLBACK (motion_notify_cb),
+                      NULL);
+}
+
+static gboolean
+button_release_cb (TerminalNotebook *notebook,
+                   GdkEventButton *event,
+                   gpointer data)
+{
+  if (notebook->priv->drag_in_progress)
+    {
+      gint cur_page_num;
+      GtkWidget *cur_page;
+  
+      cur_page_num =
+        gtk_notebook_get_current_page (GTK_NOTEBOOK (notebook));
+      cur_page = gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook),
+                                            cur_page_num);
+  
+      if (!is_in_notebook_window (notebook, event->x_root, event->y_root)
+          && gtk_notebook_get_n_pages (GTK_NOTEBOOK (notebook)) > 1)
+        {
+          /* Emit reordered signal in case the Tab was reordered
+           * before being detached.
+           */
+          g_signal_emit (G_OBJECT (notebook), signals[TABS_REORDERED], 0);
+    
+          /* Tab was detached */
+          g_signal_emit (G_OBJECT (notebook),
+                         signals[TAB_DETACHED], 0, cur_page);
+        }
+  
+      /* ungrab the pointer if it's grabbed */
+      if (gdk_pointer_is_grabbed ())
+        {
+          gdk_pointer_ungrab (event->time);
+          gtk_grab_remove (GTK_WIDGET (notebook));
+        }
+    }
+
+  /* This must be called even if a drag isn't happening */
+  drag_stop (notebook);
+
+  return FALSE;
+}
+
+static gboolean
+button_press_cb (TerminalNotebook *notebook,
+                 GdkEventButton *event,
+                 gpointer data)
+{
+  gint tab_clicked = find_tab_num_at_pos (notebook,
+                                          event->x_root,
+                                          event->y_root);
+
+  if (notebook->priv->drag_in_progress)
+    {
+      return TRUE;
+    }
+
+  if ((event->button == 1) && (event->type == GDK_BUTTON_PRESS)
+      && (tab_clicked >= 0))
+    {
+      notebook->priv->x_start = event->x_root;
+      notebook->priv->y_start = event->y_root;
+      notebook->priv->motion_notify_handler_id =
+        g_signal_connect (G_OBJECT (notebook),
+                          "motion-notify-event",
+                          G_CALLBACK (motion_notify_cb), NULL);
+    }
+  else if (GDK_BUTTON_PRESS == event->type && 3 == event->button)
+    {
+      if (tab_clicked == -1)
+        {
+          /* consume event, so that we don't pop up the context menu when
+           * the mouse if not over a screen label
+           */
+          return TRUE;
+        }
+      else
+        {
+          /* switch to the page the mouse is over, but don't consume the event
+           */
+          gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), tab_clicked);
+        }
+    }
+
+  return FALSE;
+}
+
+GtkWidget *
+terminal_notebook_new (void)
+{
+  return GTK_WIDGET (g_object_new (TERMINAL_TYPE_NOTEBOOK, NULL));
+}
+
+/*
+ * update_tabs_visibility: Hide tabs if there is only one screen
+ * and the pref is not set.
+ */
+static void
+update_tabs_visibility (TerminalNotebook *nb, gboolean before_inserting)
+{
+  gboolean show_tabs;
+  guint num;
+
+  num = gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb));
+
+  if (before_inserting) num++;
+
+  show_tabs = (num > 1);
+  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), show_tabs);
+}
+
+static void
+terminal_notebook_init (TerminalNotebook *notebook)
+{
+  notebook->priv = TERMINAL_NOTEBOOK_GET_PRIVATE (notebook);
+
+  gtk_notebook_set_scrollable (GTK_NOTEBOOK (notebook), TRUE);
+  gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
+
+  g_signal_connect (notebook, "button-press-event",
+                    (GCallback)button_press_cb, NULL);
+  g_signal_connect (notebook, "button-release-event",
+                    (GCallback)button_release_cb, NULL);
+  gtk_widget_add_events (GTK_WIDGET (notebook), GDK_BUTTON1_MOTION_MASK);
+
+}
+
+static void
+terminal_notebook_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+sync_label (TerminalScreen *screen, GtkWidget *label)
+{
+  const char *title;
+
+  if (label == NULL) return;
+
+  title = terminal_screen_get_title (screen);
+
+  if (title)
+    {
+      gtk_label_set_text (GTK_LABEL (label), title);
+    }
+}
+
+void
+terminal_notebook_add_tab (TerminalNotebook *nb,
+                           TerminalScreen *screen,
+                           int position,
+                           gboolean jump_to)
+{
+  GtkWidget *label;
+
+  g_return_if_fail (TERMINAL_IS_SCREEN (screen));
+
+  label = gtk_label_new (terminal_screen_get_title (screen));
+  gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+  gtk_widget_show (label);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+  update_tabs_visibility (nb, TRUE);
+
+  gtk_notebook_insert_page (GTK_NOTEBOOK (nb), GTK_WIDGET (screen),
+                            label, position);
+
+  gtk_notebook_set_tab_label_packing (GTK_NOTEBOOK (nb),
+                                      GTK_WIDGET (screen),
+                                      TRUE, TRUE, GTK_PACK_START);
+
+  g_signal_connect (G_OBJECT (screen),
+                    "title-changed",
+                    G_CALLBACK (sync_label),
+                    label);
+
+  g_signal_emit (G_OBJECT (nb), signals[TAB_ADDED], 0, screen);
+
+  /* The signal handler may have reordered the tabs */
+  position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (screen));
+
+  if (jump_to)
+    {
+      gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), position);
+      g_object_set_data (G_OBJECT (screen), "jump_to",
+                         GINT_TO_POINTER (jump_to));
+
+    }
+}
+
+void
+terminal_notebook_remove_tab (TerminalNotebook *nb,
+                              TerminalScreen *screen)
+{
+  int position, curr;
+  GtkWidget *label;
+
+  g_return_if_fail (TERMINAL_IS_NOTEBOOK (nb));
+  g_return_if_fail (TERMINAL_IS_SCREEN (screen));
+
+  position = gtk_notebook_page_num (GTK_NOTEBOOK (nb), GTK_WIDGET (screen));
+  curr = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb));
+
+  label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (nb), GTK_WIDGET (screen));
+
+  g_signal_handlers_disconnect_by_func (screen,
+                                        G_CALLBACK (sync_label), label);
+
+  /**
+   * we ref the screen so that it's still alive while the tabs_removed
+   * signal is processed.
+   */
+  g_object_ref (screen);
+
+  gtk_notebook_remove_page (GTK_NOTEBOOK (nb), position);
+
+  update_tabs_visibility (nb, FALSE);
+
+  g_signal_emit (G_OBJECT (nb), signals[TAB_REMOVED], 0, screen);
+
+  g_object_unref (screen);
+}
--- /dev/null
+++ mod/src/terminal-notebook.h
@@ -0,0 +1,91 @@
+/*
+ *  Copyright (C) 2002 Christophe Fergeau
+ *  Copyright (C) 2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003, 2004 Christian Persch
+ *  Copyright (C) 2005 Tony Tsui
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *  $Id: terminal-notebook.h,v 1.2 2005/05/24 22:51:04 tony Exp $
+ */
+
+#ifndef TERMINAL_NOTEBOOK_H
+#define TERMINAL_NOTEBOOK_H
+
+#include <glib.h>
+#include <gtk/gtknotebook.h>
+
+#include "terminal-screen.h"
+
+G_BEGIN_DECLS
+
+#define TERMINAL_TYPE_NOTEBOOK         (terminal_notebook_get_type ())
+#define TERMINAL_NOTEBOOK(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), TERMINAL_TYPE_NOTEBOOK, TerminalNotebook))
+#define TERMINAL_NOTEBOOK_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), TERMINAL_TYPE_NOTEBOOK, TerminalNotebookClass))
+#define TERMINAL_IS_NOTEBOOK(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), TERMINAL_TYPE_NOTEBOOK))
+#define TERMINAL_IS_NOTEBOOK_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TERMINAL_TYPE_NOTEBOOK))
+#define TERMINAL_NOTEBOOK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TERMINAL_TYPE_NOTEBOOK, TerminalNotebookClass))
+
+typedef struct _TerminalNotebookClass    TerminalNotebookClass;
+typedef struct _TerminalNotebook         TerminalNotebook;
+typedef struct _TerminalNotebookPrivate  TerminalNotebookPrivate;
+
+struct _TerminalNotebook
+{
+  GtkNotebook parent;
+
+  /*< private >*/
+  TerminalNotebookPrivate *priv;
+};
+
+struct _TerminalNotebookClass
+{
+  GtkNotebookClass parent_class;
+
+  /* Signals */
+  void     (* tab_added)      (TerminalNotebook *notebook,
+                               TerminalScreen   *screen);
+  void     (* tab_removed)    (TerminalNotebook *notebook,
+                               TerminalScreen   *screen);
+  void     (* tab_detached)   (TerminalNotebook *notebook,
+                               TerminalScreen   *screen);
+  void     (* tabs_reordered) (TerminalNotebook *notebook);
+  gboolean (* tab_delete)     (TerminalNotebook *notebook,
+                               TerminalScreen   *screen);
+};
+
+GType           terminal_notebook_get_type       (void);
+
+GtkWidget      *terminal_notebook_new            (void);
+
+void            terminal_notebook_add_tab        (TerminalNotebook *nb,
+                                                  TerminalScreen   *screen,
+                                                  int               positionl,
+                                                  gboolean          jump_to);
+
+void            terminal_notebook_remove_tab     (TerminalNotebook *nb,
+                                                  TerminalScreen   *screen);
+
+void            terminal_notebook_move_tab       (TerminalNotebook *src,
+                                                  TerminalNotebook *dest,
+                                                  TerminalScreen   *screen,
+                                                  int               dest_position);
+
+void            terminal_notebook_set_show_tabs  (TerminalNotebook *nb,
+                                                  gboolean          show_tabs);
+
+G_END_DECLS
+
+#endif /* TERMINAL_NOTEBOOK_H */
