diff -urP irssi-0.8.10-rc5/src/fe-text/gui-readline.c irssi-0.8.10-rc5-mouse_xterm/src/fe-text/gui-readline.c
--- irssi-0.8.10-rc5/src/fe-text/gui-readline.c	2004-03-24 17:24:57.000000000 +0000
+++ irssi-0.8.10-rc5-mouse_xterm/src/fe-text/gui-readline.c	2005-04-05 02:20:58.000000000 +0100
@@ -38,6 +38,10 @@
 #include "gui-windows.h"
 #include "utf8.h"
 
+#include "statusbar.h"
+char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight);
+static void key_change_window(const char *data);
+
 #include <signal.h>
 
 typedef void (*ENTRY_REDIRECT_KEY_FUNC) (int key, void *data, SERVER_REC *server, WI_ITEM_REC *item);
@@ -69,6 +73,12 @@
 
 static void sig_input(void);
 
+#include <math.h>
+static int mouse_xterm_status = -1; /* -1:off 0,1,2:filling mouse_xterm_combo */
+static unichar mouse_xterm_combo[3]; /* 0:button 1:x 2:y */
+static unichar mouse_xterm_previous[3]; /* previous contents of mouse_xterm_combo */
+static int old_window_refnum = -1;
+
 void input_listen_init(int handle)
 {
         GIOChannel *stdin_channel;
@@ -442,6 +452,129 @@
 	return paste_state == 2;
 }
 
+/* Check if the "act" item exists in the statusbar and if the mouse is over
+   it. If it is, then set the current window to the window with the number
+   which has been clicked, if any. */
+static void mouse_check_act(STATUSBAR_REC *bar, int mouse_xpos)
+{
+	GSList *l_item;
+	char *actlist;
+	SBAR_ITEM_REC *item;
+	int i, status, pos;
+
+	for (l_item = bar->items; l_item != NULL; l_item = l_item->next) {
+		item = l_item->data;
+		if (strcmp (item->config->name, "act") != 0 || item->size == 0 || mouse_xpos <= item->xpos || mouse_xpos >= item->xpos+item->size)
+			continue;
+		actlist = get_activity_list(item->bar->parent_window, TRUE, TRUE);
+		if (actlist == NULL)
+			continue;
+		/* Match mouse coordinates with window numbers in actlist.
+		   FIXME: it assumes the default act template "{sb Act: $0-}"
+		   is used. To minimize things, I assume $0- is at the end
+		   anyway, and parse actlist in reverse order. */
+		status = -1;
+		pos = 0;
+		/* Parse from the end to the beginning */
+		for (i = strlen(actlist)-1; i >= 0; i--) {
+			/* Tricky because it may be part of a window number >10 */
+			if (isdigit(actlist[i])) {
+				if (status == -1) {
+					status = actlist[i]-'0';
+				} else
+					status = status + (actlist[i]-'0')*10;
+				if (item->xpos+item->size-2-pos == mouse_xpos) {
+					/* look-ahead */
+					while (i > 0 && isdigit(actlist[i-1])) {
+						status = status + (actlist[i-1]-'0')*10;
+						i--;
+					}
+					ltoa(actlist, status);
+					key_change_window(actlist);
+					i = -1;
+					break;
+				}
+				pos++;
+			} else if (actlist[i] == ',') {
+				if (item->xpos-2-pos == mouse_xpos)
+					break;
+				status = -1;
+				pos++;
+			}
+		}
+		g_free_not_null(actlist);
+		break;
+	}
+}
+
+/* Handle mouse click from a received xterm tracking sequence */
+static void mouse_xterm_action(void)
+{
+	GSList *l_bar;
+
+	/* match screen coordinates */
+	mouse_xterm_combo[1]--;
+	mouse_xterm_combo[2]--;
+
+	/* proceed only if a button is being released */
+	if (mouse_xterm_combo[0] != 3)
+		return;
+
+	switch (mouse_xterm_previous[0]) {
+	/* left button */
+	case 0:
+		/* if it was a click in a single point */
+		if (mouse_xterm_combo[1] == mouse_xterm_previous[1] && mouse_xterm_combo[2] == mouse_xterm_previous[2])
+			for (l_bar = active_mainwin->statusbars; l_bar != NULL; l_bar = l_bar->next) {
+				STATUSBAR_REC *bar = l_bar->data;
+				/* mouse is somewhere over the statusbar */
+				if (bar->real_ypos == mouse_xterm_combo[2])
+					/* but is it over the "act" item? */
+					mouse_check_act (bar, mouse_xterm_combo[1]);
+			}
+		/* otherwise, the mouse was moved while pressed */
+		else {
+			int xd = mouse_xterm_combo[1] - mouse_xterm_previous[1];
+			int yd = -1 * (mouse_xterm_combo[2] - mouse_xterm_previous[2]);
+			double distance = sqrt(xd*xd + yd*yd), angle;
+			/* ignore small gestures */
+			if (distance < 3)
+				break;
+			angle = asin(yd/distance) * 180 / 3.14159265358979;
+			if (angle < 20 && angle > -20 && xd > 0) {
+				signal_emit("command window next", 3, "", active_win->active_server, active_win->active);
+				/* long gesture, step another window */
+				if (distance > 40)
+					signal_emit("command window next", 3, "", active_win->active_server, active_win->active);
+			} else if (angle < 20 && angle > -20 && xd < 0) {
+				signal_emit("command window previous", 3, "", active_win->active_server, active_win->active);
+				if (distance > 40)
+					signal_emit("command window previous", 3, "", active_win->active_server, active_win->active);
+			} else if (angle > 40) {
+				char buf[20];
+				if (old_window_refnum == -1)
+					break;
+				ltoa(buf,old_window_refnum);
+				key_change_window(buf);
+			} else if (angle < -40) {
+				signal_emit("command window goto", 3, "active", active_win->active_server, active_win->active);
+			}
+		}
+		break;
+	/* middle button (in 3-button mice) */
+	case 1:
+		break;
+	/* mouse wheel up */
+	case 64:
+		window_prev_page();
+		break;
+	/* mouse wheel down */
+	case 65:
+		window_next_page();
+		break;
+	}
+}
+
 static void sig_gui_key_pressed(gpointer keyp)
 {
 	GTimeVal now;
@@ -456,6 +589,18 @@
 		return;
 	}
 
+	if (mouse_xterm_status != -1) {
+		if (mouse_xterm_status == 0)
+			memcpy(mouse_xterm_previous, mouse_xterm_combo, 3*sizeof(unichar));
+		mouse_xterm_combo[mouse_xterm_status] = key-32;
+		mouse_xterm_status++;
+		if (mouse_xterm_status == 3) {
+			mouse_xterm_status = -1;
+			mouse_xterm_action ();
+		}
+		return;
+	}
+
         g_get_current_time(&now);
 	diff = (now.tv_sec - last_keypress.tv_sec) * 1000 +
 		(now.tv_usec - last_keypress.tv_usec)/1000;
@@ -565,6 +710,11 @@
 {
 }
 
+static void key_mouse_xterm(void)
+{
+	mouse_xterm_status = 0;
+}
+
 static void key_backward_history(void)
 {
 	const char *text;
@@ -963,6 +1113,12 @@
         g_free(text);
 }
 
+static void sig_window_changed(WINDOW_REC *window, WINDOW_REC *old)
+{
+	if (old != NULL)
+		old_window_refnum = old->refnum;
+}
+
 static void sig_gui_entry_redirect(SIGNAL_FUNC func, const char *entry,
 				   void *flags, void *data)
 {
@@ -1034,6 +1190,7 @@
 	key_bind("key", NULL, "meta-[", "meta2", (SIGNAL_FUNC) key_combo);
 	key_bind("key", NULL, "meta-O", "meta2", (SIGNAL_FUNC) key_combo);
 	key_bind("key", NULL, "meta-[O", "meta2", (SIGNAL_FUNC) key_combo);
+	key_bind("key", NULL, "meta-[M", "mouse_xterm", (SIGNAL_FUNC) key_combo);
 
         /* arrow keys */
 	key_bind("key", NULL, "meta2-A", "up", (SIGNAL_FUNC) key_combo);
@@ -1137,10 +1294,12 @@
 
         /* misc */
 	key_bind("stop_irc", "Send SIGSTOP to client", "^Z", NULL, (SIGNAL_FUNC) key_sig_stop);
+	key_bind("mouse_xterm", "Beginning xterm mouse tracking sequence", "mouse_xterm", NULL, (SIGNAL_FUNC) key_mouse_xterm);
 
         key_configure_thaw();
 
 	signal_add("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
+	signal_add("window changed", (SIGNAL_FUNC) sig_window_changed);
 	signal_add("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
 	signal_add("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
 	signal_add("setup changed", (SIGNAL_FUNC) setup_changed);
@@ -1201,12 +1360,14 @@
 	key_unbind("insert_text", (SIGNAL_FUNC) key_insert_text);
 	key_unbind("change_window", (SIGNAL_FUNC) key_change_window);
 	key_unbind("stop_irc", (SIGNAL_FUNC) key_sig_stop);
+	key_unbind("mouse_xterm", (SIGNAL_FUNC) key_mouse_xterm);
 	keyboard_destroy(keyboard);
         g_array_free(paste_buffer, TRUE);
 
         key_configure_thaw();
 
 	signal_remove("window changed automatic", (SIGNAL_FUNC) sig_window_auto_changed);
+	signal_remove("window changed", (SIGNAL_FUNC) sig_window_changed);
 	signal_remove("gui entry redirect", (SIGNAL_FUNC) sig_gui_entry_redirect);
 	signal_remove("gui key pressed", (SIGNAL_FUNC) sig_gui_key_pressed);
 	signal_remove("setup changed", (SIGNAL_FUNC) setup_changed);
diff -urP irssi-0.8.10-rc5/src/fe-text/statusbar-items.c irssi-0.8.10-rc5-mouse_xterm/src/fe-text/statusbar-items.c
--- irssi-0.8.10-rc5/src/fe-text/statusbar-items.c	2002-12-31 12:36:36.000000000 +0000
+++ irssi-0.8.10-rc5-mouse_xterm/src/fe-text/statusbar-items.c	2005-04-05 02:21:05.000000000 +0100
@@ -68,7 +68,7 @@
 	}
 }
 
-static char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight)
+char *get_activity_list(MAIN_WINDOW_REC *window, int normal, int hilight)
 {
         THEME_REC *theme;
 	GString *str;
diff -urP irssi-0.8.10-rc5/src/fe-text/term.c irssi-0.8.10-rc5-mouse_xterm/src/fe-text/term.c
--- irssi-0.8.10-rc5/src/fe-text/term.c	2004-08-20 01:02:29.000000000 +0100
+++ irssi-0.8.10-rc5-mouse_xterm/src/fe-text/term.c	2005-04-05 02:20:51.000000000 +0100
@@ -42,6 +42,7 @@
 
 int term_use_colors;
 int term_type;
+int term_mouse_xterm = 0;
 
 static int force_colors;
 static int resize_dirty;
@@ -110,11 +111,21 @@
 	irssi_redraw();
 }
 
+static void mouse_xterm_tracking(int start)
+{
+	term_mouse_xterm = start;
+	if (start)
+		printf("\e[?1000h");
+	else
+		printf("\e[?1000l");
+}
+
 static void read_settings(void)
 {
         const char *str;
 	int old_colors = term_use_colors;
         int old_type = term_type;
+        int old_mouse_xterm = term_mouse_xterm;
 
         term_auto_detach(settings_get_bool("term_auto_detach"));
 
@@ -141,6 +152,32 @@
 
 	if (term_use_colors != old_colors)
 		irssi_redraw();
+
+	term_mouse_xterm = settings_get_bool("term_mouse_xterm");
+	if (term_mouse_xterm != old_mouse_xterm)
+		mouse_xterm_tracking(term_mouse_xterm);
+}
+
+/* Return 1 if $TERM is set to a xterm-compatible terminal, 0 otherwise */
+static int term_is_xterm_compatible(void)
+{
+	char *term;
+	int i;
+	static char *terms[] = {
+		"rxvt",
+		"screen",
+		"xterm",
+		"xterm-color",
+		NULL
+	};
+
+	term = getenv("TERM");
+	if (term == NULL)
+		return 0;
+	for (i = 0; terms[i] != NULL; i++)
+		if (strcmp(term, terms[i]) == 0)
+			return 1;
+	return 0;
 }
 
 void term_common_init(void)
@@ -148,6 +185,7 @@
 #ifdef SIGWINCH
 	struct sigaction act;
 #endif
+        settings_add_bool("lookandfeel", "term_mouse_xterm", TRUE);
 	settings_add_bool("lookandfeel", "colors", TRUE);
 	settings_add_bool("lookandfeel", "term_force_colors", FALSE);
         settings_add_bool("lookandfeel", "term_auto_detach", FALSE);
@@ -156,7 +194,11 @@
 
 	force_colors = FALSE;
 	term_use_colors = term_has_colors() && settings_get_bool("colors");
-        read_settings();
+	read_settings();
+
+	/* start xterm mouse tracking */
+	if (settings_get_bool("term_mouse_xterm") && term_is_xterm_compatible())
+		mouse_xterm_tracking(1);
 
 #if defined (HAVE_NL_LANGINFO) && defined(CODESET)
 	if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) {
@@ -180,6 +222,10 @@
 
 void term_common_deinit(void)
 {
+	/* stop xterm mouse tracking (whether term_mouse_xterm is on or off) */
+	if (term_is_xterm_compatible())
+		mouse_xterm_tracking(0);
+
 	command_unbind("resize", (SIGNAL_FUNC) cmd_resize);
 	command_unbind("redraw", (SIGNAL_FUNC) cmd_redraw);
 	signal_remove("beep", (SIGNAL_FUNC) term_beep);
