changeset 28607:ed0c4defd3dd

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.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Sat, 21 Nov 2009 19:40:03 +0000
parents a5ddf6a99bfa
children 21294012f8cc
files ChangeLog pidgin/gtkimhtml.c
diffstat 2 files changed, 16 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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);