Index: libempathy-gtk/gossip-chat-view.c =================================================================== --- libempathy-gtk/gossip-chat-view.c (revision 138) +++ libempathy-gtk/gossip-chat-view.c (working copy) @@ -57,6 +57,8 @@ #define TIMESTAMP_INTERVAL 300 #define MAX_LINES 800 +#define MAX_SCROLL_TIME 0.4 /* seconds */ +#define SCROLL_DELAY 33 /* milliseconds */ #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CHAT_VIEW, GossipChatViewPriv)) @@ -77,6 +79,8 @@ BlockType last_block_type; gboolean allow_scrolling; + guint scroll_src; + GTimer *scroll_time; gboolean is_group_chat; GtkTextMark *find_mark_previous; @@ -1629,13 +1633,36 @@ allow_scrolling ? "enabled" : "disabled"); } +static gboolean +chat_view_scroll_cb(GossipChatView *view) +{ + GossipChatViewPriv *priv; + GtkAdjustment *adj; + gdouble max_val; + + priv = GET_PRIV (view); + adj = GTK_TEXT_VIEW(view)->vadjustment; + max_val = adj->upper - adj->page_size; + + g_return_val_if_fail(priv->scroll_time != NULL, FALSE); + + if (g_timer_elapsed (priv->scroll_time, NULL) > MAX_SCROLL_TIME) { + /* time's up. jump to the end and kill the timer */ + gtk_adjustment_set_value (adj, max_val); + g_timer_destroy (priv->scroll_time); + priv->scroll_time = NULL; + return FALSE; + } + + /* scroll by 1/3rd the remaining distance */ + gtk_adjustment_set_value (adj, gtk_adjustment_get_value (adj) + ((max_val - gtk_adjustment_get_value (adj)) / 3)); + return TRUE; +} + void gossip_chat_view_scroll_down (GossipChatView *view) { GossipChatViewPriv *priv; - GtkTextBuffer *buffer; - GtkTextIter iter; - GtkTextMark *mark; g_return_if_fail (GOSSIP_IS_CHAT_VIEW (view)); @@ -1647,22 +1674,17 @@ gossip_debug (DEBUG_DOMAIN, "Scrolling down"); - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); + if (priv->scroll_time) { + g_timer_destroy(priv->scroll_time); + } + if (priv->scroll_src) { + g_source_remove(priv->scroll_src); + } - gtk_text_buffer_get_end_iter (buffer, &iter); - mark = gtk_text_buffer_create_mark (buffer, - NULL, - &iter, - FALSE); - - gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view), - mark, - 0.0, - FALSE, - 0, - 0); - - gtk_text_buffer_delete_mark (buffer, mark); + priv->scroll_time = g_timer_new(); + priv->scroll_src = g_timeout_add(SCROLL_DELAY, + (GSourceFunc) chat_view_scroll_cb, + view); } gboolean