Index: src/vte-private.h
===================================================================
--- src/vte-private.h	(revision 1487)
+++ src/vte-private.h	(working copy)
@@ -354,6 +354,15 @@
 	GdkVisibilityState visibility_state;
 
 	gboolean has_fonts;
+
+	/* pending text signals */
+	gint emit_text_scrolled_delta;
+	guint emit_text_scrolled_tag;
+	guint emit_text_inserted_tag;
+	guint emit_text_deleted_tag;
+	guint emit_text_modified_tag;
+	guint emit_status_line_changed_tag;
+	guint emit_contents_changed_tag;
 };
 
 
@@ -368,10 +377,10 @@
 VteRowData * _vte_new_row_data(VteTerminal *terminal);
 VteRowData * _vte_new_row_data_sized(VteTerminal *terminal, gboolean fill);
 void _vte_terminal_adjust_adjustments(VteTerminal *terminal, gboolean immediate);
-void _vte_terminal_emit_contents_changed(VteTerminal *terminal);
-void _vte_terminal_emit_status_line_changed(VteTerminal *terminal);
-void _vte_terminal_emit_text_deleted(VteTerminal *terminal);
-void _vte_terminal_emit_text_inserted(VteTerminal *terminal);
+void _vte_terminal_queue_contents_changed(VteTerminal *terminal);
+void _vte_terminal_queue_status_line_changed(VteTerminal *terminal);
+void _vte_terminal_queue_text_deleted(VteTerminal *terminal);
+void _vte_terminal_queue_text_inserted(VteTerminal *terminal);
 void _vte_terminal_insert_char(VteTerminal *terminal, gunichar c,
 			       gboolean force_insert_mode,
 			       gboolean invalidate_cells,
Index: src/vte.c
===================================================================
--- src/vte.c	(revision 1487)
+++ src/vte.c	(working copy)
@@ -760,8 +760,8 @@
 }
 
 /* Emit a "contents_changed" signal. */
-void
-_vte_terminal_emit_contents_changed(VteTerminal *terminal)
+static gboolean
+vte_terminal_emit_contents_changed(VteTerminal *terminal)
 {
 #ifdef VTE_DEBUG
 	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
@@ -769,8 +769,26 @@
 	}
 #endif
 	g_signal_emit_by_name(terminal, "contents-changed");
+
+	terminal->pvt->emit_contents_changed_tag = VTE_INVALID_SOURCE;
+	return FALSE;
 }
+void
+_vte_terminal_queue_contents_changed(VteTerminal *terminal)
+{
+#ifdef VTE_DEBUG
+	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
+		g_printerr("Queueing `contents-changed'.\n");
+	}
+#endif
 
+	if (terminal->pvt->emit_contents_changed_tag == VTE_INVALID_SOURCE) {
+		terminal->pvt->emit_contents_changed_tag = g_idle_add (
+				(GSourceFunc) vte_terminal_emit_contents_changed,
+				terminal);
+	}
+}
+
 /* Emit a "cursor_moved" signal. */
 static void
 vte_terminal_emit_cursor_moved(VteTerminal *terminal)
@@ -809,9 +827,8 @@
 			      width, height);
 }
 
-/* Emit a "status-line-changed" signal. */
-void
-_vte_terminal_emit_status_line_changed(VteTerminal *terminal)
+static gboolean
+vte_terminal_emit_status_line_changed(VteTerminal *terminal)
 {
 #ifdef VTE_DEBUG
 	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
@@ -819,7 +836,20 @@
 	}
 #endif
 	g_signal_emit_by_name(terminal, "status-line-changed");
+
+	terminal->pvt->emit_status_line_changed_tag = VTE_INVALID_SOURCE;
+	return FALSE;
 }
+/* Emit a "status-line-changed" signal. */
+void
+_vte_terminal_queue_status_line_changed(VteTerminal *terminal)
+{
+	if (terminal->pvt->emit_status_line_changed_tag == VTE_INVALID_SOURCE) {
+		terminal->pvt->emit_status_line_changed_tag =
+			g_idle_add ((GSourceFunc) vte_terminal_emit_status_line_changed,
+					terminal);
+	}
+}
 
 /* Emit an "increase-font-size" signal. */
 static void
@@ -846,63 +876,141 @@
 }
 
 /* Emit a "text-inserted" signal. */
+static gboolean
+vte_terminal_emit_text_inserted (VteTerminal *terminal)
+{
+#ifdef VTE_DEBUG
+	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
+		g_printerr("Emitting `text-inserted'.\n");
+	}
+#endif
+	g_signal_emit_by_name(terminal, "text-inserted");
+
+	terminal->pvt->emit_text_inserted_tag = VTE_INVALID_SOURCE;
+	return FALSE;
+}
 void
-_vte_terminal_emit_text_inserted(VteTerminal *terminal)
+_vte_terminal_queue_text_inserted (VteTerminal *terminal)
 {
 	if (!terminal->pvt->accessible_emit) {
 		return;
 	}
 #ifdef VTE_DEBUG
 	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
-		g_printerr("Emitting `text-inserted'.\n");
+		g_printerr("Queueing `text-inserted'.\n");
 	}
 #endif
-	g_signal_emit_by_name(terminal, "text-inserted");
+	if (terminal->pvt->emit_text_inserted_tag == VTE_INVALID_SOURCE) {
+		terminal->pvt->emit_text_inserted_tag = g_idle_add (
+				(GSourceFunc) vte_terminal_emit_text_inserted,
+				terminal);
+	}
 }
 
 /* Emit a "text-deleted" signal. */
+static gboolean
+vte_terminal_emit_text_deleted (VteTerminal *terminal)
+{
+#ifdef VTE_DEBUG
+	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
+		g_printerr("Emitting `text-deleted'.\n");
+	}
+#endif
+	g_signal_emit_by_name(terminal, "text-deleted");
+
+	terminal->pvt->emit_text_deleted_tag = VTE_INVALID_SOURCE;
+	return FALSE;
+}
+
 void
-_vte_terminal_emit_text_deleted(VteTerminal *terminal)
+_vte_terminal_queue_text_deleted (VteTerminal *terminal)
 {
 	if (!terminal->pvt->accessible_emit) {
 		return;
 	}
 #ifdef VTE_DEBUG
 	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
-		g_printerr("Emitting `text-deleted'.\n");
+		g_printerr("Queueing `text-deleted'.\n");
 	}
 #endif
-	g_signal_emit_by_name(terminal, "text-deleted");
+
+	if (terminal->pvt->emit_text_deleted_tag == VTE_INVALID_SOURCE) {
+		terminal->pvt->emit_text_deleted_tag = g_idle_add (
+				(GSourceFunc) vte_terminal_emit_text_deleted,
+				terminal);
+	}
 }
 
 /* Emit a "text-modified" signal. */
-static void
+static gboolean
 vte_terminal_emit_text_modified(VteTerminal *terminal)
 {
+#ifdef VTE_DEBUG
+	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
+		g_printerr("Emitting `text-modified'.\n");
+	}
+#endif
+	g_signal_emit_by_name(terminal, "text-modified");
+
+	terminal->pvt->emit_text_modified_tag = VTE_INVALID_SOURCE;
+	return FALSE;
+}
+
+static void
+vte_terminal_queue_text_modified(VteTerminal *terminal)
+{
 	if (!terminal->pvt->accessible_emit) {
 		return;
 	}
 #ifdef VTE_DEBUG
 	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
-		g_printerr("Emitting `text-modified'.\n");
+		g_printerr("Queueing `text-modified'.\n");
 	}
 #endif
-	g_signal_emit_by_name(terminal, "text-modified");
+
+	if (terminal->pvt->emit_text_modified_tag == VTE_INVALID_SOURCE) {
+		terminal->pvt->emit_text_modified_tag = g_idle_add (
+				(GSourceFunc) vte_terminal_emit_text_modified,
+				terminal);
+	}
 }
 
 /* Emit a "text-scrolled" signal. */
+static gboolean
+vte_terminal_emit_text_scrolled(VteTerminal *terminal)
+{
+	if (terminal->pvt->emit_text_scrolled_delta) {
+#ifdef VTE_DEBUG
+		if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
+			g_printerr("Emitting `text-scrolled'(%d).\n",
+					terminal->pvt->emit_text_scrolled_delta);
+		}
+#endif
+		g_signal_emit_by_name(terminal, "text-scrolled",
+			       	terminal->pvt->emit_text_scrolled_delta);
+		terminal->pvt->emit_text_scrolled_delta = 0;
+
+	}
+	terminal->pvt->emit_text_scrolled_tag = VTE_INVALID_SOURCE;
+	return FALSE;
+}
 static void
-vte_terminal_emit_text_scrolled(VteTerminal *terminal, gint delta)
+vte_terminal_queue_text_scrolled(VteTerminal *terminal, gint delta)
 {
 	if (!terminal->pvt->accessible_emit) {
 		return;
 	}
 #ifdef VTE_DEBUG
 	if (_vte_debug_on(VTE_DEBUG_SIGNALS)) {
-		g_printerr("Emitting `text-scrolled'(%d).\n", delta);
+		g_printerr("Queueing `text-scrolled'(%d).\n", delta);
 	}
 #endif
-	g_signal_emit_by_name(terminal, "text-scrolled", delta);
+	terminal->pvt->emit_text_scrolled_delta += delta;
+	if (terminal->pvt->emit_text_scrolled_tag == VTE_INVALID_SOURCE) {
+		terminal->pvt->emit_text_scrolled_tag = g_idle_add (
+				(GSourceFunc) vte_terminal_emit_text_scrolled,
+				terminal);
+	}
 }
 
 /* Deselect anything which is selected and refresh the screen if needed. */
@@ -1622,7 +1730,7 @@
 	/* Clear dingus match set. */
 	_vte_terminal_match_contents_clear(terminal);
 	/* Notify viewers that the contents have changed. */
-	_vte_terminal_emit_contents_changed(terminal);
+	_vte_terminal_queue_contents_changed(terminal);
 }
 
 /* Scroll so that the scroll delta is the minimum value. */
@@ -2328,7 +2436,7 @@
 	/* If this character is destined for the status line, save it. */
 	if (screen->status_line) {
 		g_string_append_unichar(screen->status_line_contents, c);
-		_vte_terminal_emit_status_line_changed(terminal);
+		_vte_terminal_queue_status_line_changed(terminal);
 		return;
 	}
 
@@ -3001,7 +3109,7 @@
 			g_printerr("Emitting buffered `text-modified'.\n");
 		}
 #endif
-		vte_terminal_emit_text_modified(terminal);
+		vte_terminal_queue_text_modified(terminal);
 		terminal->pvt->text_modified_flag = FALSE;
 	}
 	if (terminal->pvt->text_inserted_count) {
@@ -3011,7 +3119,7 @@
 				"(%ld).\n", terminal->pvt->text_inserted_count);
 		}
 #endif
-		_vte_terminal_emit_text_inserted(terminal);
+		_vte_terminal_queue_text_inserted(terminal);
 		terminal->pvt->text_inserted_count = 0;
 	}
 	if (terminal->pvt->text_deleted_count) {
@@ -3021,7 +3129,7 @@
 				"(%ld).\n", terminal->pvt->text_deleted_count);
 		}
 #endif
-		_vte_terminal_emit_text_deleted(terminal);
+		_vte_terminal_queue_text_deleted(terminal);
 		terminal->pvt->text_deleted_count = 0;
 	}
 }
@@ -3346,7 +3454,7 @@
 	if (modified || (screen != terminal->pvt->screen)) {
 		/* Signal that the visible contents changed. */
 		_vte_terminal_match_contents_clear(terminal);
-		_vte_terminal_emit_contents_changed(terminal);
+		_vte_terminal_queue_contents_changed(terminal);
 	}
 
 	if ((cursor.col != terminal->pvt->screen->cursor_current.col) ||
@@ -6264,6 +6372,11 @@
 vte_terminal_ensure_font (VteTerminal *terminal)
 {
 	if (terminal->pvt->fontdirty) {
+#ifdef VTE_DEBUG
+		if (_vte_debug_on(VTE_DEBUG_MISC)) {
+			g_printerr("Actually setting the font.");
+		}
+#endif
 		terminal->pvt->fontdirty = FALSE;
 		_vte_draw_set_text_font(terminal->pvt->draw, 
 				terminal->pvt->fontdesc,
@@ -6480,7 +6593,7 @@
 		terminal->column_count = columns;
 	}
 	/* Our visible text changed. */
-	vte_terminal_emit_text_modified(terminal);
+	vte_terminal_queue_text_modified(terminal);
 }
 
 /* Redraw the widget. */
@@ -6512,8 +6625,8 @@
 		_vte_terminal_match_contents_clear(terminal);
 		_vte_terminal_scroll_region(terminal, screen->scroll_delta,
 					   terminal->row_count, -dy);
-		vte_terminal_emit_text_scrolled(terminal, dy);
-		_vte_terminal_emit_contents_changed(terminal);
+		vte_terminal_queue_text_scrolled(terminal, dy);
+		_vte_terminal_queue_contents_changed(terminal);
 	}
 #ifdef VTE_DEBUG
 	else if (_vte_debug_on(VTE_DEBUG_IO)) {
@@ -6929,6 +7042,15 @@
 	/* Assume we're visible unless we're told otherwise. */
 	pvt->visibility_state = GDK_VISIBILITY_UNOBSCURED;
 
+	/* set text signals source to invalid */
+	pvt->emit_text_scrolled_tag = VTE_INVALID_SOURCE;
+	pvt->emit_text_inserted_tag = VTE_INVALID_SOURCE;
+	pvt->emit_text_deleted_tag = VTE_INVALID_SOURCE;
+	pvt->emit_text_modified_tag = VTE_INVALID_SOURCE;
+	pvt->emit_status_line_changed_tag = VTE_INVALID_SOURCE;
+	pvt->emit_contents_changed_tag = VTE_INVALID_SOURCE;
+
+
 	/* Listen for hierarchy change notifications. */
 	g_signal_connect(terminal, "hierarchy-changed",
 			 G_CALLBACK(vte_terminal_hierarchy_changed),
@@ -7237,6 +7359,26 @@
 		g_free(terminal->pvt->bg_file);
 	}
 
+	/* stop any pending signals */
+	if (terminal->pvt->emit_text_scrolled_tag != VTE_INVALID_SOURCE) {
+		g_source_remove (terminal->pvt->emit_text_scrolled_tag);
+	}
+	if (terminal->pvt->emit_text_inserted_tag != VTE_INVALID_SOURCE) {
+		g_source_remove (terminal->pvt->emit_text_inserted_tag);
+	}
+	if (terminal->pvt->emit_text_deleted_tag != VTE_INVALID_SOURCE) {
+		g_source_remove (terminal->pvt->emit_text_deleted_tag);
+	}
+	if (terminal->pvt->emit_text_modified_tag != VTE_INVALID_SOURCE) {
+		g_source_remove (terminal->pvt->emit_text_modified_tag);
+	}
+	if (terminal->pvt->emit_status_line_changed_tag) {
+		g_source_remove(terminal->pvt->emit_status_line_changed_tag);
+	}
+	if (terminal->pvt->emit_contents_changed_tag) {
+		g_source_remove(terminal->pvt->emit_contents_changed_tag);
+	}
+
 	/* Free the font description. */
 	if (terminal->pvt->fontdesc != NULL) {
 		pango_font_description_free(terminal->pvt->fontdesc);
@@ -7284,6 +7426,7 @@
 		g_source_remove(terminal->pvt->adjustment_changed_tag);
 	}
 
+
 	/* Tabstop information. */
 	if (terminal->pvt->tabstops != NULL) {
 		g_hash_table_destroy(terminal->pvt->tabstops);
@@ -10522,7 +10665,7 @@
 		/* Clear the matching view. */
 		_vte_terminal_match_contents_clear(terminal);
 		/* Notify viewers that the contents have changed. */
-		_vte_terminal_emit_contents_changed(terminal);
+		_vte_terminal_queue_contents_changed(terminal);
 	}
 	terminal->pvt->scrollback_lines = lines;
 
@@ -10717,6 +10860,8 @@
 void
 vte_terminal_reset(VteTerminal *terminal, gboolean full, gboolean clear_history)
 {
+	gboolean emit;
+
 	g_return_if_fail(VTE_IS_TERMINAL(terminal));
 	/* Stop processing any of the data we've got backed up. */
 	vte_terminal_stop_processing (terminal);
@@ -10807,6 +10952,8 @@
 			      TRUE);
 	}
 	terminal->pvt->alternate_screen.status_line_contents = g_string_new(NULL);
+	_vte_terminal_queue_status_line_changed (terminal);
+
 	/* Do more stuff we refer to as a "full" reset. */
 	if (full) {
 		vte_terminal_set_default_tabstops(terminal);
Index: src/vteseq.c
===================================================================
--- src/vteseq.c	(revision 1487)
+++ src/vteseq.c	(working copy)
@@ -777,7 +777,7 @@
 		/* Clear the matching view. */
 		_vte_terminal_match_contents_clear(terminal);
 		/* Notify viewers that the contents have changed. */
-		_vte_terminal_emit_contents_changed(terminal);
+		_vte_terminal_queue_contents_changed(terminal);
 		break;
 	case 9:
 	case 1000:
@@ -2531,7 +2531,7 @@
 {
 	terminal->pvt->screen->status_line = TRUE;
 	g_string_truncate(terminal->pvt->screen->status_line_contents, 0);
-	_vte_terminal_emit_status_line_changed(terminal);
+	_vte_terminal_queue_status_line_changed(terminal);
 	return FALSE;
 }
 
@@ -3695,14 +3695,14 @@
 		if (rowdata->cells->len > 0) {
 			g_array_set_size(rowdata->cells, 0);
 		}
-		_vte_terminal_emit_text_deleted(terminal);
+		_vte_terminal_queue_text_deleted(terminal);
 		/* Fill this row. */
 		cell = screen->basic_defaults;
 		cell.c = 'E';
 		cell.columns = 1;
 		cell.empty = 0;
 		vte_g_array_fill(rowdata->cells, &cell, terminal->column_count);
-		_vte_terminal_emit_text_inserted(terminal);
+		_vte_terminal_queue_text_inserted(terminal);
 	}
 	_vte_invalidate_all(terminal);
 
