Index: src/Makefile.am
===================================================================
RCS file: /local/cvsroot/gnome-terminal/src/Makefile.am,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -p -r1.1.1.1 -r1.2
--- src/Makefile.am	19 Apr 2005 08:11:58 -0000	1.1.1.1
+++ src/Makefile.am	23 Apr 2005 06:05:41 -0000	1.2
@@ -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)
Index: src/Makefile.in
===================================================================
RCS file: /local/cvsroot/gnome-terminal/src/Makefile.in,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -p -r1.1.1.1 -r1.2
--- src/Makefile.in	19 Apr 2005 08:11:58 -0000	1.1.1.1
+++ src/Makefile.in	22 Apr 2005 14:20:30 -0000	1.2
@@ -60,7 +60,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 =
@@ -291,6 +291,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)
Index: src/terminal-notebook.c
===================================================================
RCS file: src/terminal-notebook.c
diff -N src/terminal-notebook.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/terminal-notebook.c	23 Apr 2005 05:47:13 -0000	1.5
@@ -0,0 +1,698 @@
+/*
+ *  Copyright (C) 2002 Christophe Fergeau
+ *  Copyright (C) 2003, 2004 Marco Pesenti Gritti
+ *  Copyright (C) 2003, 2004 Christian Persch
+ *
+ *  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);
+/* XXX: Remove for now until I know what to do with terminal_marshal_BOOLEAN__OBJECT
+	signals[TAB_DELETE] =
+		g_signal_new ("tab_delete",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (TerminalNotebookClass, tab_delete),
+			      g_signal_accumulator_true_handled, NULL,
+			      terminal_marshal_BOOLEAN__OBJECT,
+			      G_TYPE_BOOLEAN,
+			      1,
+			      TERMINAL_TYPE_SCREEN);
+*/
+	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;
+	}
+
+// XXX: Not sure this is relevant to us
+	/* For some reason unfullscreen + quick click can
+	   cause a wrong click event to be reported to the screen */
+	if (!is_in_notebook_window(notebook, abs_x, abs_y))
+	{
+		return NOT_IN_APP_WINDOWS;
+	}
+
+	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)
+{
+  gpointer term_win;
+  GdkWindow *window;
+  
+	g_fprintf(stderr, "%s():%i\n", __PRETTY_FUNCTION__, __LINE__);
+	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
+	{
+		/* 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. XXX: Can this be avoided
+     */
+    window = gtk_widget_get_parent_window (GTK_WIDGET (dest));
+    gdk_window_get_user_data (window, &term_win);
+    terminal_screen_set_window (screen, TERMINAL_WINDOW(term_win));
+
+		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;
+
+	g_fprintf (stderr, "moving screen from notebook %p to notebook %p at %d",
+	     src, dest, dest_position);
+
+	/* 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));
+
+  if (TERMINAL_IS_SCREEN(screen))
+    g_fprintf(stderr, "%s() TERMINAL_IS_SCREEN(screen) passed\n", __PRETTY_FUNCTION__);
+
+	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)
+		{
+			/* 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++;
+
+// XXX: Not sure what the point of: && nb->priv->show_tabs == TRUE;
+//	show_tabs = (num > 1) && nb->priv->show_tabs == TRUE;
+	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;
+
+	g_return_if_fail (label != NULL);
+
+	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_fprintf(stderr, "%s():%i\n", __PRETTY_FUNCTION__, __LINE__);
+	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_fprintf(stderr, "%s():%i\n", __PRETTY_FUNCTION__, __LINE__);
+	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);
+
+// XXX Do we need to do this here. teminal_window_remove_screen() does the same thing.
+	/* if that was the last screen, destroy the window */
+//	if (gtk_notebook_get_n_pages (GTK_NOTEBOOK (nb)) == 0)
+//	{
+//		gtk_widget_destroy (gtk_widget_get_toplevel (GTK_WIDGET (nb)));
+//	}
+}
Index: src/terminal-notebook.h
===================================================================
RCS file: src/terminal-notebook.h
diff -N src/terminal-notebook.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/terminal-notebook.h	19 Apr 2005 08:51:51 -0000	1.1
@@ -0,0 +1,90 @@
+/*
+ *  Copyright (C) 2002 Christophe Fergeau
+ *  Copyright (C) 2003 Marco Pesenti Gritti
+ *  Copyright (C) 2003, 2004 Christian Persch
+ *
+ *  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.1 2005/04/19 08:51:51 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 position,
+						 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 */
Index: src/terminal-screen.c
===================================================================
RCS file: /local/cvsroot/gnome-terminal/src/terminal-screen.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -u -p -r1.1.1.1 -r1.4
--- src/terminal-screen.c	19 Apr 2005 08:11:58 -0000	1.1.1.1
+++ src/terminal-screen.c	23 Apr 2005 05:47:32 -0000	1.4
@@ -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,8 +228,55 @@ 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);
+
+  g_fprintf (stderr, "%s() widget_request = %dx%d\n", __PRETTY_FUNCTION__,
+           widget_request.width, widget_request.height);
+
+  requisition->width = widget_request.width;
+  requisition->height = widget_request.height;
+}
+
+static void
+terminal_screen_size_allocate (GtkWidget *widget,
+      GtkAllocation *allocation)
+{
+  GtkWidget *child;
+  GtkAllocation invalid = { -1, -1, 1, 1 };
+
+g_fprintf (stderr, "%s()\n", __PRETTY_FUNCTION__);
+  widget->allocation = *allocation;
+
+  child = GTK_BIN (widget)->child;
+  g_return_if_fail (child != NULL);
+
+g_fprintf(stderr, "%s() allocation = %d,%d %dx%d\n", __PRETTY_FUNCTION__,
+          allocation->x, allocation->y,
+          allocation->width, allocation->height);
+
+  /* only resize if we're mapped (bug #128191),
+   * or if this is the initial size-allocate (bug #156854).
+   */
+  if (GTK_WIDGET_MAPPED (child) ||
+      memcmp (&child->allocation, &invalid, sizeof (GtkAllocation)) == 0)
+  {
+    g_fprintf (stderr, "%s() Calling gtk_widget_size_allocate()\n", __PRETTY_FUNCTION__);
+    gtk_widget_size_allocate (child, allocation);
+  }
+}
+
+static void
 terminal_screen_init (TerminalScreen *screen)
 {
+  // XXX: Call TERMINAL_SCREEN_GET_PRIVATE(screen) if we use g_type_class_add_private()
   screen->priv = g_new0 (TerminalScreenPrivate, 1);
 
   screen->priv->working_dir = g_get_current_dir ();
@@ -235,9 +289,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 +359,32 @@ 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",
@@ -364,6 +430,8 @@ terminal_screen_class_init (TerminalScre
                   NULL, NULL,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);  
+
+// XXX: Do we need to g_type_class_add_private()
 }
 
 static void
@@ -372,6 +440,7 @@ terminal_screen_finalize (GObject *objec
   TerminalScreen *screen;
   GConfClient *conf;
 
+g_fprintf(stderr, "%s()\n", __PRETTY_FUNCTION__);
   screen = TERMINAL_SCREEN (object);
 
   conf = gconf_client_get_default ();
@@ -390,8 +459,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 +502,20 @@ terminal_screen_new (void)
   return screen;
 }
 
+static void
+terminal_screen_map (GtkWidget *widget)
+{
+  GtkWidget *child;
+
+g_fprintf (stderr, "%s()\n", __PRETTY_FUNCTION__);
+  g_return_if_fail (GTK_WIDGET_REALIZED (widget));
+
+  child = GTK_BIN (widget)->child;
+  g_return_if_fail (child != NULL);
+
+  GTK_WIDGET_CLASS (parent_class)->map (widget);
+}
+
 int
 terminal_screen_get_id (TerminalScreen *screen)
 {
@@ -508,7 +589,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);
     }
@@ -2379,6 +2460,49 @@ terminal_screen_setup_dnd (TerminalScree
                      GDK_ACTION_COPY);
 }
 
+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	
Index: src/terminal-screen.h
===================================================================
RCS file: /local/cvsroot/gnome-terminal/src/terminal-screen.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -p -r1.1.1.1 -r1.2
--- src/terminal-screen.h	19 Apr 2005 08:11:58 -0000	1.1.1.1
+++ src/terminal-screen.h	19 Apr 2005 08:51:51 -0000	1.2
@@ -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,15 @@ typedef struct _TerminalScreenPrivate Te
 
 struct _TerminalScreen
 {
-  GObject parent_instance;
+//  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 +113,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)
Index: src/terminal-window.c
===================================================================
RCS file: /local/cvsroot/gnome-terminal/src/terminal-window.c,v
retrieving revision 1.1.1.1
retrieving revision 1.5
diff -u -p -r1.1.1.1 -r1.5
--- src/terminal-window.c	19 Apr 2005 08:11:58 -0000	1.1.1.1
+++ src/terminal-window.c	23 Apr 2005 05:58:38 -0000	1.5
@@ -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>
@@ -101,27 +102,29 @@ 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_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,
@@ -790,7 +793,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 +829,22 @@ 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_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);
 
@@ -1270,7 +1288,7 @@ 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);
+//  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->priv->notebook), !single);
 }
 
 static void
@@ -1287,7 +1305,6 @@ static void
 title_changed_callback (TerminalScreen *screen,
                         TerminalWindow *window)
 {
-  GtkWidget *label;
   GtkWidget *mi;
   
   if (screen == window->priv->active_term) 
@@ -1300,9 +1317,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))),
@@ -1374,10 +1388,9 @@ terminal_window_add_screen (TerminalWind
 {
   TerminalWindow *old;
   GtkWidget *term;
-  GtkWidget *hbox;
-  GtkWidget *scrollbar;
-  GtkWidget *label;  
-  
+ 
+g_fprintf (stderr, "%s():%i\n", __PRETTY_FUNCTION__, __LINE__);  
+ 
   old = terminal_screen_get_window (screen);
 
   if (old == window)
@@ -1385,6 +1398,7 @@ terminal_window_add_screen (TerminalWind
 
   g_object_ref (G_OBJECT (screen)); /* make our own new refcount */
 
+// XXX not sure the point of this
   if (old)
     terminal_window_remove_screen (old, screen);
 
@@ -1396,17 +1410,6 @@ 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),
@@ -1426,35 +1429,24 @@ terminal_window_add_screen (TerminalWind
                     "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 (GTK_WIDGET (screen));
+  terminal_screen_update_scrollbar (screen);
 
-  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);
+
+  terminal_notebook_add_tab (TERMINAL_NOTEBOOK (window->priv->notebook),
+                             screen,
+                             -1,
+                             FALSE);
 
   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.
    */
+  term = terminal_screen_get_widget (screen);
   gtk_widget_realize (GTK_WIDGET (term));
 
   {
@@ -1484,6 +1476,7 @@ terminal_window_remove_screen (TerminalW
   int old_grid_width;
   int old_grid_height;
   
+g_fprintf(stderr, "%s()\n", __PRETTY_FUNCTION__);
   g_return_if_fail (terminal_screen_get_window (screen) == window);
 
   old_grid_width = -1;
@@ -1518,16 +1511,14 @@ terminal_window_remove_screen (TerminalW
                                         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));
+    terminal_notebook_remove_tab (TERMINAL_NOTEBOOK (window->priv->notebook),
+                                  screen);
+  
+// XXX: Not sure why this unref is not required. We do a ref in add_screen()
+//  g_object_unref (G_OBJECT (screen));
   
   update_notebook (window);
 
@@ -1544,7 +1535,7 @@ terminal_window_remove_screen (TerminalW
   if (window->priv->active_term)
     {
 #ifdef DEBUG_GEOMETRY
-      g_print ("setting size with forced grid after removing a terminal\n");
+      g_fprintf (stderr,"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);
@@ -1597,7 +1588,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 +1600,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 +1638,13 @@ 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);
   
+  g_fprintf (stderr,"set size: toplevel %dx%d\n",
+           toplevel_request.width, toplevel_request.height); // XXX
   /* 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 +1657,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
@@ -1668,6 +1668,9 @@ terminal_window_set_size_force_grid (Ter
   terminal_widget_get_cell_size (widget, &char_width, &char_height);
   terminal_widget_get_size (widget, &grid_width, &grid_height);
 
+  g_fprintf (stderr,"set size: grid_ %dx%d char_ %dx%d \n",
+           grid_width, grid_height, char_width, char_height);
+
   if (force_grid_width >= 0)
     grid_width = force_grid_width;
   if (force_grid_height >= 0)
@@ -1679,14 +1682,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
@@ -1725,11 +1730,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 +1754,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 +1763,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,6 +1802,8 @@ notebook_page_selected_callback (GtkWidg
   old_grid_width = -1;
   old_grid_height = -1;
 
+  g_fprintf (stderr, "%s()\n", __PRETTY_FUNCTION__);
+
   if (window->priv->active_term)
     {
       old_widget = terminal_screen_get_widget (window->priv->active_term);
@@ -1853,7 +1815,7 @@ notebook_page_selected_callback (GtkWidg
 
   g_assert (page_widget);
 
-  screen = find_screen_by_hbox (window, page_widget);
+  screen = TERMINAL_SCREEN (page_widget);
 
   g_assert (screen);
 
@@ -1863,7 +1825,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 +1838,165 @@ 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;
+  
+// XXX: Factor out common code between here and terminal_window_add_screen()
 
-  profile = terminal_screen_get_profile (screen);
+  // XXX: Called from terminal_window_add_screen()
+  if (find_screen (window, screen) != NULL)
+    return;
+g_fprintf(stderr, "%s()\n", __PRETTY_FUNCTION__);
 
-  if (profile == 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);
+
+  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);
+  
+  /* ZvtTerm is a broken POS and requires this realize to get
+   * the size request right.
+   */
+  term = terminal_screen_get_widget (screen);
+  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);
+  }
+}
+
+static void
+notebook_tab_removed_callback (GtkWidget       *notebook,
+                               TerminalScreen  *screen,
+                               TerminalWindow  *window)
+{  
+  int old_grid_width;
+  int old_grid_height;
+
+// XXX: Factor out common code between here and terminal_window_remove_screen()
+
+  // XXX: Called from terminal_window_remove_screen()
+  if (find_screen (window, screen) == NULL)
     return;
   
-  scrollbar = screen_get_scrollbar (screen);
-  hbox = screen_get_hbox (screen);
+g_fprintf(stderr, "%s()\n", __PRETTY_FUNCTION__);
+  g_return_if_fail (terminal_screen_get_window (screen) == window);
+
+  old_grid_width = -1;
+  old_grid_height = -1;
   
-  g_object_ref (G_OBJECT (scrollbar));
+  if (window->priv->active_term == screen)
+    {
+      GtkWidget *old_active_widget;
+      
+      window->priv->active_term = NULL;
 
-  if (scrollbar->parent)
-    gtk_container_remove (GTK_CONTAINER (hbox), scrollbar);
+      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);
+
+  screen_set_menuitem (screen, NULL);
   
-  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;
+// XXX: Not sure why this unref is not required. We do a ref in add_screen()
+//  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_fprintf (stderr,"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);
     }
 
-  g_object_unref (G_OBJECT (scrollbar));
+  reset_tab_menuitems (window);
+  update_tab_sensitivity (window);
+
+}
+
+static void
+notebook_tabs_reordered_callback (GtkWidget       *notebook,
+                                 TerminalWindow  *window)
+{
+	reset_tab_menuitems(window);
 }
 
 void
@@ -2012,7 +2086,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 +2102,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 +2248,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));
Index: src/terminal-window.h
===================================================================
RCS file: /local/cvsroot/gnome-terminal/src/terminal-window.h,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -p -r1.1.1.1 -r1.3
--- src/terminal-window.h	19 Apr 2005 08:11:58 -0000	1.1.1.1
+++ src/terminal-window.h	22 Apr 2005 14:20:30 -0000	1.3
@@ -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,
