diff -aur vte-0.32.2.orig/src/vte.c vte-0.32.2/src/vte.c
--- vte-0.32.2.orig/src/vte.c	2012-05-29 19:44:17.000000000 +0200
+++ vte-0.32.2/src/vte.c	2012-08-06 20:26:24.933090051 +0200
@@ -5831,22 +5831,20 @@
 }
 
 static void
-vte_terminal_get_mouse_tracking_info (VteTerminal   *terminal,
-				      int            button,
-				      long           col,
-				      long           row,
-				      unsigned char *pb,
-				      long          *px,
-				      long          *py)
+vte_terminal_feed_mouse_event(VteTerminal *terminal,
+			      int          button,
+			      gboolean     is_drag,
+			      gboolean     is_release,
+			      long         col,
+			      long         row)
 {
 	unsigned char cb = 0;
 	long cx, cy;
+	char buf[LINE_MAX];
+	gint len = 0;
 
 	/* Encode the button information in cb. */
 	switch (button) {
-	case 0:			/* Release/no buttons. */
-		cb = 3;
-		break;
 	case 1:			/* Left. */
 		cb = 0;
 		break;
@@ -5863,7 +5861,12 @@
 		cb = 65;	/* Scroll down. */
 		break;
 	}
-	cb += 32; /* 32 for normal */
+
+	/* With the exception of the 1006 mode, button release is also encoded here. */
+	/* Note that if multiple extensions are enabled, the 1006 is used, so it's okay to check for only that. */
+	if (is_release && !terminal->pvt->mouse_xterm_extension) {
+		cb = 3;
+	}
 
 	/* Encode the modifiers. */
 	if (terminal->pvt->modifiers & GDK_SHIFT_MASK) {
@@ -5876,32 +5879,27 @@
 		cb |= 16;
 	}
 
-	/* Clamp the cursor coordinates. */
+	/* Encode a drag event. */
+	if (is_drag) {
+		cb |= 32;
+	}
+
+	/* Clamp the cursor coordinates. Make them 1-based. */
 	cx = CLAMP(1 + col,
 		   1, terminal->column_count);
 	cy = CLAMP(1 + row,
 		   1, terminal->row_count);
 
-	*pb = cb;
-	*px = cx;
-	*py = cy;
-}
-
-static void
-vte_terminal_feed_mouse_event(VteTerminal *terminal,
-                              int          cb,
-                              long         cx,
-                              long         cy)
-{
-	char buf[LINE_MAX];
-	gint len = 0;
-
-	if (terminal->pvt->mouse_urxvt_extension) {
+	/* Check the extensions in decreasing order of preference. Encoding the release event above assumes that 1006 comes first. */
+	if (terminal->pvt->mouse_xterm_extension) {
+		/* xterm's extended mode (1006) */
+		len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "<%d;%ld;%ld%c", cb, cx, cy, is_release ? 'm' : 'M');
+	} else if (terminal->pvt->mouse_urxvt_extension) {
 		/* urxvt's extended mode (1015) */
-		len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "%d;%ld;%ldM", cb, cx, cy);
+		len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "%d;%ld;%ldM", 32 + cb, cx, cy);
 	} else if (cx <= 231 && cy <= 231) {
 		/* legacy mode */
-		len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "M%c%c%c", cb, 32 + (guchar)cx, 32 + (guchar)cy);
+		len = g_snprintf(buf, sizeof(buf), _VTE_CAP_CSI "M%c%c%c", 32 + cb, 32 + (guchar)cx, 32 + (guchar)cy);
 	}
 
 	/* Send event direct to the child, this is binary not text data */
@@ -5911,20 +5909,16 @@
 static void
 vte_terminal_send_mouse_button_internal(VteTerminal *terminal,
 					int          button,
+					gboolean     is_release,
 					long         x,
 					long         y)
 {
-	unsigned char cb;
-	long cx, cy;
 	int width = terminal->char_width;
 	int height = terminal->char_height;
 	long col = (x - terminal->pvt->inner_border.left) / width;
 	long row = (y - terminal->pvt->inner_border.top) / height;
 
-	vte_terminal_get_mouse_tracking_info (terminal,
-					      button, col, row,
-					      &cb, &cx, &cy);
-	vte_terminal_feed_mouse_event(terminal, cb, cx, cy);
+	vte_terminal_feed_mouse_event(terminal, button, FALSE /* not drag */, is_release, col, row);
 }
 
 /* Send a mouse button click/release notification. */
@@ -5952,7 +5946,8 @@
 	}
 
 	vte_terminal_send_mouse_button_internal(terminal,
-					        (event->type == GDK_BUTTON_PRESS) ? event->button : 0,
+						event->button,
+						event->type == GDK_BUTTON_RELEASE,
 						event->x, event->y);
 }
 
@@ -5960,8 +5955,6 @@
 static void
 vte_terminal_maybe_send_mouse_drag(VteTerminal *terminal, GdkEventMotion *event)
 {
-	unsigned char cb;
-	long cx, cy;
 	int width = terminal->char_width;
 	int height = terminal->char_height;
 	long col = ((long) event->x - terminal->pvt->inner_border.left) / width;
@@ -5990,12 +5983,9 @@
 		break;
 	}
 
-	vte_terminal_get_mouse_tracking_info (terminal,
-					      terminal->pvt->mouse_last_button, col, row,
-					      &cb, &cx, &cy);
-	cb += 32; /* for movement */
-
-	vte_terminal_feed_mouse_event(terminal, cb, cx, cy);
+	vte_terminal_feed_mouse_event(terminal, terminal->pvt->mouse_last_button,
+				      TRUE /* drag */, FALSE /* not release */,
+				      col, row);
 }
 
 /* Clear all match hilites. */
@@ -11417,6 +11407,7 @@
 			/* Encode the parameters and send them to the app. */
 			vte_terminal_send_mouse_button_internal(terminal,
 								button,
+								FALSE /* not release */,
 								event->x,
 								event->y);
 		}
@@ -14132,6 +14123,7 @@
 	pvt->mouse_last_button = 0;
 	pvt->mouse_last_x = 0;
 	pvt->mouse_last_y = 0;
+	pvt->mouse_xterm_extension = FALSE;
 	pvt->mouse_urxvt_extension = FALSE;
 	/* Clear modifiers. */
 	pvt->modifiers = 0;
diff -aur vte-0.32.2.orig/src/vte-private.h vte-0.32.2/src/vte-private.h
--- vte-0.32.2.orig/src/vte-private.h	2012-05-23 22:43:04.000000000 +0200
+++ vte-0.32.2/src/vte-private.h	2012-08-06 19:36:50.524966738 +0200
@@ -305,6 +305,7 @@
 	long mouse_last_x, mouse_last_y;
 	gboolean mouse_autohide;
 	guint mouse_autoscroll_tag;
+	gboolean mouse_xterm_extension;
 	gboolean mouse_urxvt_extension;
 
 	/* State variables for handling match checks. */
diff -aur vte-0.32.2.orig/src/vteseq.c vte-0.32.2/src/vteseq.c
--- vte-0.32.2.orig/src/vteseq.c	2012-05-23 22:43:04.000000000 +0200
+++ vte-0.32.2/src/vteseq.c	2012-08-06 18:50:10.644850659 +0200
@@ -685,6 +685,11 @@
 		 GINT_TO_POINTER(0),
 		 GINT_TO_POINTER(MOUSE_TRACKING_ALL_MOTION_TRACKING),
 		 NULL, NULL,},
+		/* 1006: Extended mouse coordinates. */
+		{1006, &terminal->pvt->mouse_xterm_extension, NULL, NULL,
+		 GINT_TO_POINTER(FALSE),
+		 GINT_TO_POINTER(TRUE),
+		 NULL, NULL,},
 		/* 1010/rxvt: disallowed, scroll-on-output is set by user. */
 		{1010, NULL, NULL, NULL, NULL, NULL, NULL, NULL,},
 		/* 1011/rxvt: disallowed, scroll-on-keypress is set by user. */
