diff -ur xchat-1.9.8/src/common/cfgfiles.c xchat-1.9.8-treeview/src/common/cfgfiles.c
--- xchat-1.9.8/src/common/cfgfiles.c	2002-12-25 09:17:05.000000000 +0000
+++ xchat-1.9.8-treeview/src/common/cfgfiles.c	2003-01-02 13:02:58.000000000 +0000
@@ -437,6 +437,7 @@
 	{"text_show_sep", P_OFFINT (show_separator), TYPE_BOOL},
 	{"text_stripcolor", P_OFFINT (stripcolor), TYPE_BOOL},
 	{"text_wordwrap", P_OFFINT (wordwrap), TYPE_BOOL},
+	{"treeview", P_OFFINT (treeview), TYPE_BOOL},
 
 	{0, 0, 0},
 };
diff -ur xchat-1.9.8/src/common/xchat.h xchat-1.9.8-treeview/src/common/xchat.h
--- xchat-1.9.8/src/common/xchat.h	2002-12-27 09:04:53.000000000 +0000
+++ xchat-1.9.8-treeview/src/common/xchat.h	2003-01-02 13:02:40.000000000 +0000
@@ -246,6 +246,7 @@
 	unsigned int persist_chans;
 	unsigned int wait_on_exit;
 	unsigned int utf8_locale;
+	unsigned int treeview;
 
 	unsigned int ctcp_number_limit;	/*flood */
 	unsigned int ctcp_time_limit;	/*seconds of floods */
diff -ur xchat-1.9.8/src/fe-gtk/fe-gtk.c xchat-1.9.8-treeview/src/fe-gtk/fe-gtk.c
--- xchat-1.9.8/src/fe-gtk/fe-gtk.c	2002-12-25 09:46:17.000000000 +0000
+++ xchat-1.9.8-treeview/src/fe-gtk/fe-gtk.c	2003-01-01 20:12:44.000000000 +0000
@@ -35,6 +35,9 @@
 #include <gtk/gtkbox.h>
 #include <gtk/gtklabel.h>
 #include <gtk/gtktogglebutton.h>
+#include <gtk/gtktreeview.h>
+#include <gtk/gtktreestore.h>
+#include <gtk/gtktreemodel.h>
 
 #include "../common/xchat.h"
 #include "../common/fe.h"
@@ -353,10 +356,17 @@
 void
 fe_set_hilight (struct session *sess)
 {
+	GtkTreeIter iter;
+	
 	if (sess->gui->is_tab)
 	{
 		sess->nick_said = TRUE;
 		tab_set_attrlist (sess->res->tab, nickseen_list);
+		if (treeview_iter_get (sess, &iter) == 0)
+			gtk_tree_store_set (
+				GTK_TREE_STORE (G_tree_model),
+				&iter,
+				1, "blue", -1);
 	}
 }
 
@@ -477,6 +487,7 @@
 void
 fe_print_text (struct session *sess, char *text)
 {
+	GtkTreeIter iter;
 	PrintTextRaw (sess->res->buffer, text, prefs.indent_nicks);
 
 	if (prefs.limitedtabhighlight && !sess->highlight_tab)
@@ -488,10 +499,23 @@
 		 sess->gui->is_tab && !sess->nick_said)
 	{
 		sess->new_data = TRUE;
-		if (sess->msg_said)
+
+		if (sess->msg_said) {
 			tab_set_attrlist (sess->res->tab, newmsg_list);
-		else
+			if (treeview_iter_get (sess, &iter) == 0)
+				gtk_tree_store_set (
+					GTK_TREE_STORE (G_tree_model),
+					&iter,
+					1, "red", -1);
+		} else {
+			/* I'm not sure when this gets called -agl */
 			tab_set_attrlist (sess->res->tab, newdata_list);
+			if (treeview_iter_get (sess, &iter) == 0)
+				gtk_tree_store_set (
+					GTK_TREE_STORE (G_tree_model),
+					&iter,
+					1, "blue", -1);
+		}
 	}
 }
 
diff -ur xchat-1.9.8/src/fe-gtk/fe-gtk.h xchat-1.9.8-treeview/src/fe-gtk/fe-gtk.h
--- xchat-1.9.8/src/fe-gtk/fe-gtk.h	2002-12-18 15:29:01.000000000 +0000
+++ xchat-1.9.8-treeview/src/fe-gtk/fe-gtk.h	2003-01-01 20:14:41.000000000 +0000
@@ -38,6 +38,11 @@
 #define flag_b flag_wid[8]
 #define NUM_FLAG_WIDS 9
 
+struct _GtkTreeStore;
+
+/* Global model for the treeview */
+extern struct _GtkTreeStore *G_tree_model;
+
 struct server_gui
 {
 	GtkWidget *rawlog_window;
diff -ur xchat-1.9.8/src/fe-gtk/maingui.c xchat-1.9.8-treeview/src/fe-gtk/maingui.c
--- xchat-1.9.8/src/fe-gtk/maingui.c	2002-12-26 03:28:43.000000000 +0000
+++ xchat-1.9.8-treeview/src/fe-gtk/maingui.c	2003-01-02 13:56:10.000000000 +0000
@@ -39,6 +39,14 @@
 #include <gtk/gtkmessagedialog.h>
 #include <gtk/gtkcheckmenuitem.h>
 #include <gtk/gtkvscrollbar.h>
+#include <gtk/gtktree.h>
+#include <gtk/gtktreeitem.h>
+#include <gtk/gtktreemodel.h>
+#include <gtk/gtktreestore.h>
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkcellrenderer.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtktreeselection.h>
 
 #include "../common/xchat.h"
 #include "../common/fe.h"
@@ -59,7 +67,7 @@
 #include "xtext.h"
 
 static void mg_create_entry (session *sess, GtkWidget *box);
-
+static void treeview_black (void *p);
 
 static session_gui static_mg_gui;
 static session_gui *mg_gui = NULL;	/* the shared irc tab */
@@ -75,6 +83,7 @@
 PangoAttrList *newmsg_list = NULL;
 static PangoAttrList *plain_list = NULL;
 
+GtkTreeStore *G_tree_model;
 
 static PangoAttrList *
 mg_attr_list_create (GdkColor *col)
@@ -269,6 +278,7 @@
 		sess->msg_said = FALSE;
 		sess->new_data = FALSE;
 		tab_set_attrlist (sess->res->tab, plain_list);
+		treeview_black (sess);
 	}
 }
 
@@ -1765,11 +1775,60 @@
 }
 
 static void
+tree_row_cb (GtkTreeSelection *selection, gpointer data)
+{
+	GtkTreeIter iter;
+	session *sess;
+
+	if (gtk_tree_selection_get_selected (selection, NULL, &iter)) {
+		if (gtk_tree_model_iter_has_child (
+			    GTK_TREE_MODEL (G_tree_model), &iter))
+			return;
+		gtk_tree_model_get (GTK_TREE_MODEL (G_tree_model),
+				    &iter, 2, &sess, -1);
+		if (sess->gui->is_tab)
+			mg_bring_tofront (sess->res->tab);
+		else
+			gtk_window_present(GTK_WINDOW (sess->gui->window));
+	}
+}
+
+static void
+mg_create_treeview (session *sess, GtkWidget *hbox)
+{
+	GtkWidget *tree;
+	GtkTreeViewColumn *column;
+	GtkTreeSelection *select;
+
+	if (!G_tree_model)
+	    G_tree_model = gtk_tree_store_new (3, G_TYPE_STRING,
+					       G_TYPE_STRING,
+					       G_TYPE_POINTER);
+
+	tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(G_tree_model));
+
+	select = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
+	gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
+	g_signal_connect (G_OBJECT (select), "changed",
+			  G_CALLBACK (tree_row_cb),
+			  NULL);
+	
+	column = gtk_tree_view_column_new_with_attributes
+	    ("Channel", gtk_cell_renderer_text_new(),
+	     "text", 0,
+	     "foreground", 1,
+	     NULL);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+	gtk_container_add (GTK_CONTAINER (hbox), tree);
+	gtk_widget_show (tree);
+}
+
+static void
 mg_create_topwindow (session *sess)
 {
 	GtkWidget *win;
 	GtkWidget *vbox;
-	GtkWidget *vvbox;
+	GtkWidget *vvbox, *paned, *hbox;
 
 	win = gtkutil_window_new ("X-Chat ["VERSION"]", prefs.mainwindow_width,
 									  prefs.mainwindow_height, FALSE);
@@ -1786,9 +1845,21 @@
 
 	vbox = gtk_vbox_new (FALSE, 1);
 	gtk_container_add (GTK_CONTAINER (win), vbox);
-
+	
 	vvbox = gtk_vbox_new (FALSE, 1);
-	gtk_container_add (GTK_CONTAINER (vbox), vvbox);
+	if (prefs.treeview) {
+		paned = gtk_hpaned_new ();
+		gtk_container_add (GTK_CONTAINER (vbox), paned);
+		hbox = gtk_hbox_new (FALSE, 1);
+		gtk_paned_add1 (GTK_PANED (paned), hbox);
+		mg_create_treeview (sess, hbox);
+		gtk_paned_add2 (GTK_PANED (paned), vvbox);
+		gtk_widget_show (paned);
+		gtk_widget_show (hbox);
+		gtk_widget_show (vvbox);
+	} else {
+		gtk_container_add (GTK_CONTAINER (vbox), vvbox);
+	}
 
 	mg_create_topicbar (sess, vvbox, sess->channel);
 	mg_create_center (sess, sess->gui, vvbox);
@@ -1895,7 +1966,7 @@
 mg_create_tabwindow (session *sess)
 {
 	GtkWidget *win;
-	GtkWidget *vbox;
+	GtkWidget *vbox, *paned, *hbox, *right_vbox;
 	GtkWidget *book;
 
 	win = gtkutil_window_new ("X-Chat ["VERSION"]", prefs.mainwindow_width,
@@ -1921,10 +1992,25 @@
 	sess->gui->main_vbox = vbox = gtk_vbox_new (FALSE, 1);
 	gtk_container_add (GTK_CONTAINER (win), vbox);
 
+	if (prefs.treeview) {
+	    paned = gtk_hpaned_new ();
+	    gtk_container_add (GTK_CONTAINER (vbox), paned);
+            hbox = gtk_hbox_new (FALSE, 1);
+            gtk_paned_add1 (GTK_PANED (paned), hbox);
+	    mg_create_treeview (sess, hbox);
+	    right_vbox = gtk_vbox_new (FALSE, 1);
+	    gtk_paned_add2 (GTK_PANED (paned), right_vbox);
+	    gtk_widget_show (paned);
+	    gtk_widget_show (hbox);
+	    gtk_widget_show (right_vbox);
+	} else {
+	    right_vbox = vbox;
+	}
+
 	sess->gui->note_book = book = gtk_notebook_new ();
 	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (book), FALSE);
 	gtk_notebook_set_show_border (GTK_NOTEBOOK (book), FALSE);
-	gtk_container_add (GTK_CONTAINER (vbox), book);
+	gtk_container_add (GTK_CONTAINER (right_vbox), book);
 
 	mg_create_irctab (sess, book);
 	mg_create_tabs (sess->gui, vbox);
@@ -2006,6 +2092,104 @@
 		gui->button_box = mg_create_userlistbuttons (gui->button_box_parent);
 }
 
+/* Treeview code:
+
+   There is a global GtkTreeStore called G_tree_store which is used by
+   all the GtkTreeViews. This store is updated even if prefs.treeview
+   is false.
+
+   The store has 3 columns: name (string), colour (string) and serv/sess
+   (pointer). If a row has children then the pointer is a server, other-
+   wise it's a session.
+*/
+
+/* Recurse down the TreeStore for a row who's pointer equals @cp. Store
+   the iterator of that row in @o_i. Return 1 if not found, 0 if found.*/
+char
+treeview_iter_get (void *cp, GtkTreeIter *o_i)
+{
+	GtkTreeIter i, i2;
+	void *p;
+	gboolean valid, valid2;
+
+	valid =gtk_tree_model_get_iter_first(GTK_TREE_MODEL(G_tree_model),
+					     &i);
+
+	while (valid) {
+		gtk_tree_model_get (GTK_TREE_MODEL (G_tree_model), &i,
+				    2, &p, -1);
+		if (p == cp) {
+			memcpy (o_i, &i, sizeof (i));
+			return 0;
+		}
+		valid2 = 1;
+		if (gtk_tree_model_iter_children (
+			    GTK_TREE_MODEL (G_tree_model), &i2, &i))
+			while (valid2) {
+				gtk_tree_model_get (
+					GTK_TREE_MODEL (G_tree_model),&i2,
+					2, &p, -1);
+				if (p == cp) {
+					memcpy (o_i, &i2, sizeof (i2));
+					return 0;
+				}
+				valid2 = gtk_tree_model_iter_next (
+					GTK_TREE_MODEL (G_tree_model),
+					&i2);
+			}
+		valid = gtk_tree_model_iter_next (
+			GTK_TREE_MODEL (G_tree_model),
+			&i);
+	}
+
+	return 1;
+}
+
+/* Remove the row with the given pointer (session or server) */
+static void
+treeview_sess_remove (void *sess)
+{
+	GtkTreeIter iter;
+
+	if (treeview_iter_get (sess, &iter))
+		return;
+	gtk_tree_store_remove (GTK_TREE_STORE (G_tree_model), &iter);
+}
+
+/* For a given row (@i), set the string and pointer */
+static void
+treeview_update (GtkTreeIter *i, char *str, void *ptr)
+{
+	gtk_tree_store_set (G_tree_model, i,
+			    0, strcmp(str,"")==0?"<none>":str,
+			    1, "black",
+			    2, ptr,
+			    -1);
+}
+
+static void
+treeview_update_ptr (void *p, char *str, void *ptr)
+{
+	GtkTreeIter iter;
+
+	if (treeview_iter_get (p, &iter))
+		return;
+	treeview_update (&iter, str, ptr);
+}
+
+/* Search for a row with pointer equal to @p and set its colour to black*/
+static void
+treeview_black (void *p)
+{
+	GtkTreeIter i;
+
+	if (treeview_iter_get (p, &i))
+		return;
+	gtk_tree_store_set (GTK_TREE_STORE (G_tree_model), &i,
+			    1, "black",
+			    -1);
+}
+
 void
 fe_clear_channel (session *sess)
 {
@@ -2028,6 +2212,7 @@
 	}
 	else
 		strcpy (tbuf, _("<none>"));
+	treeview_update_ptr (sess, tbuf, sess);
 	tab_rename (sess->res->tab, tbuf);
 
 	if (!sess->gui->is_tab || sess == current_tab)
@@ -2162,11 +2347,16 @@
 		g_utf8_offset_to_pointer(buf, prefs.truncchans)[0] = 0;
 		strcat (buf, "..");
 		tab_rename (sess->res->tab, buf);
+		treeview_update_ptr (sess, buf, sess);
 		free (buf);
 	} else
 	{
 		tab_rename (sess->res->tab, sess->channel);
+		treeview_update_ptr (sess, sess->channel,
+				     sess);
 	}
+	treeview_update_ptr (sess->server, sess->server->hostname,
+			     sess->server);
 }
 
 void
@@ -2174,6 +2364,7 @@
 {
 	int first_run = FALSE;
 	session_gui *gui;
+	GtkTreeIter iter1, iter2;
 
 	if (!res)
 	{
@@ -2194,7 +2385,7 @@
 		sess->gui = gui;
 		mg_create_topwindow (sess);
 		fe_set_title (sess);
-		return;
+		goto treeview_insert;
 	}
 
 	if (mg_gui == NULL)
@@ -2216,6 +2407,21 @@
 
 	if (first_run || prefs.newtabstofront)
 		tab_focus (res->tab);
+
+ treeview_insert:
+	if (!G_tree_model)
+		G_tree_model = gtk_tree_store_new (3,
+						   G_TYPE_STRING,
+						   G_TYPE_STRING,
+						   G_TYPE_POINTER);
+	
+	if (treeview_iter_get (sess->server, &iter1))
+		gtk_tree_store_append(G_tree_model, &iter1, NULL);
+	treeview_update (&iter1, sess->server->hostname,
+			 sess->server);
+	
+	gtk_tree_store_append (G_tree_model, &iter2, &iter1);
+	treeview_update (&iter2, sess->channel, sess);
 }
 
 GtkWidget *
@@ -2300,6 +2506,7 @@
 
 	if (serv->gui->rawlog_window)
 		gtk_widget_destroy (serv->gui->rawlog_window);
+	treeview_sess_remove (serv);
 
 	free (serv->gui);
 }
@@ -2330,7 +2537,10 @@
 	if (sess->gui->bartag)
 		fe_timeout_remove (sess->gui->bartag);
 
+	treeview_sess_remove (sess); 
+
 	if (sess->gui != mg_gui)
 		free (sess->gui);
+
 	free (sess->res);
 }
diff -ur xchat-1.9.8/src/fe-gtk/maingui.h xchat-1.9.8-treeview/src/fe-gtk/maingui.h
--- xchat-1.9.8/src/fe-gtk/maingui.h	2002-12-19 07:19:13.000000000 +0000
+++ xchat-1.9.8-treeview/src/fe-gtk/maingui.h	2003-01-01 20:16:53.000000000 +0000
@@ -20,3 +20,7 @@
 void mg_link_cb (GtkWidget *but, gpointer userdata);
 void mg_progressbar_create (session_gui *gui);
 void mg_progressbar_destroy (session_gui *gui);
+
+struct _GtkTreeIter;
+char treeview_iter_get (void *cp, struct _GtkTreeIter *o_i);
+
diff -ur xchat-1.9.8/src/fe-gtk/setup.c xchat-1.9.8-treeview/src/fe-gtk/setup.c
--- xchat-1.9.8/src/fe-gtk/setup.c	2002-12-25 09:40:06.000000000 +0000
+++ xchat-1.9.8-treeview/src/fe-gtk/setup.c	2003-01-02 13:06:37.000000000 +0000
@@ -161,6 +161,7 @@
 	{ST_TOGGLE, N_("Only highlight tabs on channel messages"), P_OFFINT(limitedtabhighlight), 0, 0, 0},
 	{ST_TOGGLE, N_("Open tab for server notices"), P_OFFINT(notices_tabs), 0, 0, 0},
 	{ST_TOGGLE, N_("Pop new tabs to front"), P_OFFINT(newtabstofront), 0, 0, 0},
+	{ST_TOGGLE, N_("Use Treeview"), P_OFFINT(treeview), 0, 0, 0},
 	{ST_END, 0, 0, 0, 0, 0}
 };
 
