# HG changeset patch
# User Sadrul Habib Chowdhury <imadil@gmail.com>
# Date 1258832403 0
# Node ID ed0c4defd3ddd6dccf403ddb5c63f3ba81693a8c
# Parent  a5ddf6a99bfa86ea8c64e8c655769a85464d3efb
Fix scrolling bug for very busy chat rooms.

The bug shows up only when smooth-scrolling is enabled. When the imhtml
widget is still scrolling (such that an entire line still needs to be
scrolled), and a new message comes in, it thinks the user isn't looking
at the end of the buffer, so it doesn't scroll for the new message. The
fix is to detect that and not disable the scrolling in such cases.

diff -r a5ddf6a99bfa -r ed0c4defd3dd ChangeLog
--- a/ChangeLog	Fri Nov 20 21:49:36 2009 +0000
+++ b/ChangeLog	Sat Nov 21 19:40:03 2009 +0000
@@ -64,6 +64,8 @@
 	* The userlist in a multiuser chat can be styled via gtkrc by using the
 	  widget name "pidgin_conv_userlist". (Heiko Schmitt)
 	* Add a hold button to the media window.
+	* Fix a bug where the conversation backlog stops scrolling in a very busy
+	  chat room.
 
 	Pidgin Preference and Preference Window Changes:
 	* Removed the "Use font from theme" and "Conversation Font" preferences
diff -r a5ddf6a99bfa -r ed0c4defd3dd pidgin/gtkimhtml.c
--- a/pidgin/gtkimhtml.c	Fri Nov 20 21:49:36 2009 +0000
+++ b/pidgin/gtkimhtml.c	Sat Nov 21 19:40:03 2009 +0000
@@ -2423,6 +2423,8 @@
 	return proto ? proto->length : 0;
 }
 
+static gboolean smooth_scroll_cb(gpointer data);
+
 /*
  <KingAnt> marv: The two IM image functions in oscar are purple_odc_send_im and purple_odc_incoming
 
@@ -2477,7 +2479,14 @@
 
 		if (((y + height) - (rect.y + rect.height)) > height &&
 				gtk_text_buffer_get_char_count(imhtml->text_buffer)) {
-			options |= GTK_IMHTML_NO_SCROLL;
+			/* If we are in the middle of smooth-scrolling, then take a scroll step.
+			 * If we are not in the middle of smooth-scrolling, that means we were
+			 * not looking at the end of the buffer before the new text was added,
+			 * so do not scroll. */
+			if (imhtml->scroll_time)
+				smooth_scroll_cb(imhtml);
+			else
+				options |= GTK_IMHTML_NO_SCROLL;
 		}
 	}
 
@@ -2506,7 +2515,7 @@
  *
  * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom.
  */
-static gboolean scroll_cb(gpointer data)
+static gboolean smooth_scroll_cb(gpointer data)
 {
 	GtkIMHtml *imhtml = data;
 	GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
@@ -2520,6 +2529,8 @@
 		gtk_adjustment_set_value(adj, max_val);
 		g_timer_destroy(imhtml->scroll_time);
 		imhtml->scroll_time = NULL;
+		g_source_remove(imhtml->scroll_src);
+		imhtml->scroll_src = 0;
 		return FALSE;
 	}
 
@@ -2528,13 +2539,6 @@
 	return TRUE;
 }
 
-static gboolean smooth_scroll_idle_cb(gpointer data)
-{
-	GtkIMHtml *imhtml = data;
-	imhtml->scroll_src = g_timeout_add(SCROLL_DELAY, scroll_cb, imhtml);
-	return FALSE;
-}
-
 static gboolean scroll_idle_cb(gpointer data)
 {
 	GtkIMHtml *imhtml = data;
@@ -2554,7 +2558,7 @@
 		g_source_remove(imhtml->scroll_src);
 	if(smooth) {
 		imhtml->scroll_time = g_timer_new();
-		imhtml->scroll_src = g_idle_add_full(G_PRIORITY_LOW, smooth_scroll_idle_cb, imhtml, NULL);
+		imhtml->scroll_src = g_timeout_add_full(G_PRIORITY_LOW, SCROLL_DELAY, smooth_scroll_cb, imhtml, NULL);
 	} else {
 		imhtml->scroll_time = NULL;
 		imhtml->scroll_src = g_idle_add_full(G_PRIORITY_LOW, scroll_idle_cb, imhtml, NULL);