Index: src/vte.c
===================================================================
RCS file: /cvs/gnome/vte/src/vte.c,v
retrieving revision 1.485
diff -u -p -r1.485 vte.c
--- src/vte.c	31 Aug 2006 20:03:10 -0000	1.485
+++ src/vte.c	2 Sep 2006 21:20:50 -0000
@@ -97,6 +97,8 @@ static void vte_terminal_stop_processing
 static void vte_terminal_start_processing (VteTerminal *terminal);
 static gboolean vte_terminal_is_processing (VteTerminal *terminal);
 
+static void _vte_setup_cursor_blink (VteTerminal *terminal);
+
 static gpointer parent_class;
 
 /* Indexes in the "palette" color array for the dim colors.
@@ -496,38 +498,19 @@ vte_invalidate_cursor_periodic(gpointer 
 {
 	VteTerminal *terminal;
 	GtkWidget *widget;
-	GtkSettings *settings;
-	gint blink_cycle = 1000;
 
 	g_assert(VTE_IS_TERMINAL(data));
 	widget = GTK_WIDGET(data);
-	if (!GTK_WIDGET_REALIZED(widget)) {
-		return TRUE;
-	}
-	if (!GTK_WIDGET_HAS_FOCUS(widget)) {
-		return TRUE;
-	}
-
 	terminal = VTE_TERMINAL(widget);
-	if (terminal->pvt->cursor_blinks) {
-		_vte_invalidate_cursor_once(terminal, TRUE);
-	}
-
-	settings = gtk_widget_get_settings(GTK_WIDGET(data));
-	if (G_IS_OBJECT(settings)) {
-		g_object_get(G_OBJECT(settings), "gtk-cursor-blink-time",
-			     &blink_cycle, NULL);
-	}
-
-	if (terminal->pvt->cursor_blink_timeout != blink_cycle) {
-		terminal->pvt->cursor_blink_tag = g_timeout_add_full(G_PRIORITY_LOW,
-								     blink_cycle / 2,
-								     vte_invalidate_cursor_periodic,
-								     terminal,
-								     NULL);
-		terminal->pvt->cursor_blink_timeout = blink_cycle;
+	if (!GTK_WIDGET_REALIZED(widget) ||
+			!GTK_WIDGET_HAS_FOCUS(widget) ||
+			!terminal->pvt->cursor_blinks) {
+		terminal->pvt->cursor_blink_timeout = 0;
+		terminal->pvt->cursor_blink_tag = 0;
 		return FALSE;
 	} else {
+		_vte_invalidate_cursor_once(terminal, TRUE);
+		_vte_setup_cursor_blink(terminal);
 		return TRUE;
 	}
 }
@@ -6056,6 +6043,7 @@ vte_terminal_focus_in(GtkWidget *widget,
 		   just after the one we're about to perform. */
 		terminal->pvt->cursor_force_fg = 2;
 		_vte_invalidate_cursor_once(terminal, FALSE);
+		_vte_setup_cursor_blink(terminal);
 	}
 	return FALSE;
 }
@@ -6084,6 +6072,14 @@ vte_terminal_focus_out(GtkWidget *widget
 		gtk_im_context_focus_out(terminal->pvt->im_context);
 		_vte_invalidate_cursor_once(terminal, FALSE);
 	}
+
+	/* kill the blinking cursor */
+	if (terminal->pvt->cursor_blink_tag) {
+		g_source_remove (terminal->pvt->cursor_blink_tag);
+		terminal->pvt->cursor_blink_tag = 0;
+		terminal->pvt->cursor_blink_timeout = 0;
+	}
+
 	return FALSE;
 }
 
@@ -6805,7 +6801,6 @@ vte_terminal_init(VteTerminal *terminal,
 
 	/* Cursor blinking. */
 	pvt->cursor_visible = TRUE;
-	pvt->cursor_blink_timeout = 1000;
 
 	/* Input options. */
 	if (gettimeofday(&tv, &tz) == 0) {
@@ -7101,6 +7096,7 @@ vte_terminal_unrealize(GtkWidget *widget
 	if (terminal->pvt->cursor_blink_tag != 0) {
 		g_source_remove(terminal->pvt->cursor_blink_tag);
 		terminal->pvt->cursor_blink_tag = 0;
+		terminal->pvt->cursor_blink_timeout = 0;
 	}
 	terminal->pvt->cursor_force_fg = 0;
 
@@ -7360,6 +7356,43 @@ vte_terminal_finalize(GObject *object)
 	}
 }
 
+static void
+_vte_setup_cursor_blink(VteTerminal *terminal)
+{
+	VteTerminalPrivate *pvt = terminal->pvt;
+	if (!pvt->cursor_blinks ||
+			!GTK_WIDGET_REALIZED (terminal) ||
+			!GTK_WIDGET_HAS_FOCUS (terminal)) {
+		if (pvt->cursor_blink_tag) {
+			g_source_remove(pvt->cursor_blink_tag);
+			pvt->cursor_blink_tag = 0;
+			pvt->cursor_blink_timeout = 0;
+		}
+	} else {
+		GtkSettings *settings;
+		gint blink_cycle = 1000;
+
+		settings = gtk_widget_get_settings(GTK_WIDGET(terminal));
+		if (G_IS_OBJECT(settings))
+			g_object_get(G_OBJECT(settings),
+					"gtk-cursor-blink-time", &blink_cycle,
+					NULL);
+
+		if (blink_cycle != pvt->cursor_blink_timeout) {
+			if (pvt->cursor_blink_tag)
+				g_source_remove(pvt->cursor_blink_tag);
+
+			pvt->cursor_blink_tag = g_timeout_add_full(
+					G_PRIORITY_LOW,
+					blink_cycle / 2,
+					vte_invalidate_cursor_periodic,
+					terminal,
+					NULL);
+			pvt->cursor_blink_timeout = blink_cycle;
+		}
+	}
+}
+
 /* Handle realizing the widget.  Most of this is copy-paste from GGAD. */
 static void
 vte_terminal_realize(GtkWidget *widget)
@@ -7368,9 +7401,7 @@ vte_terminal_realize(GtkWidget *widget)
 	GdkWindowAttr attributes;
 	GdkPixmap *bitmap;
 	GdkColor black = {0,0,0}, color;
-	GtkSettings *settings;
 	int attributes_mask = 0, i;
-	gint blink_cycle = 1000;
 	VteBg *bg;
 
 #ifdef VTE_DEBUG
@@ -7464,17 +7495,7 @@ vte_terminal_realize(GtkWidget *widget)
 		vte_terminal_set_color_internal(terminal, i, &color);
 	}
 
-	/* Setup cursor blink */
-	settings = gtk_widget_get_settings(GTK_WIDGET(terminal));
-	if (G_IS_OBJECT(settings)) {
-		g_object_get(G_OBJECT(settings), "gtk-cursor-blink-time",
-			     &blink_cycle, NULL);
-	}
-	terminal->pvt->cursor_blink_tag = g_timeout_add_full(G_PRIORITY_LOW,
-							     blink_cycle / 2,
-							     vte_invalidate_cursor_periodic,
-							     terminal,
-							     NULL);
+	_vte_setup_cursor_blink(terminal);
 
 	/* Set up input method support.  FIXME: do we need to handle the
 	 * "retrieve-surrounding" and "delete-surrounding" events? */
@@ -10504,7 +10525,12 @@ void
 vte_terminal_set_cursor_blinks(VteTerminal *terminal, gboolean blink)
 {
 	g_return_if_fail(VTE_IS_TERMINAL(terminal));
-	terminal->pvt->cursor_blinks = blink;
+	blink = !!blink;
+	if (terminal->pvt->cursor_blinks != blink) {
+		terminal->pvt->cursor_blinks = blink;
+		_vte_invalidate_cursor_once(terminal, FALSE);
+		_vte_setup_cursor_blink(terminal);
+	}
 }
 
 /**
