+static void
+chat_view_adjustment_changed_cb (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ EmpathyChat *chat = EMPATHY_CHAT (user_data);
+ EmpathyChatPriv *priv = GET_PRIV (chat);
+ guint page_size;
+
+ if (tpl_log_walker_is_end (priv->log_walker)) {
+ g_signal_handlers_disconnect_by_func (adjustment,
+ chat_view_adjustment_changed_cb, user_data);
+ return;
+ }
+
+ page_size = (guint) gtk_adjustment_get_page_size (adjustment);
+ if (page_size <= priv->max_page_size)
+ return;
+
+ /* We need to fetch more logs if the page size of the view
+ * increases, so that there is no empty space at the top.
+ */
+ if (G_LIKELY (priv->max_page_size != 0))
+ chat_schedule_logs (chat);
+
+ priv->max_page_size = page_size;
+}
+
+static void
+chat_view_adjustment_value_changed_cb (GtkAdjustment *adjustment,
+ gpointer user_data)
+{
+ EmpathyChat *chat = EMPATHY_CHAT (user_data);
+ EmpathyChatPriv *priv = GET_PRIV (chat);
+ guint lower;
+ guint value;
+
+ if (tpl_log_walker_is_end (priv->log_walker)) {
+ g_signal_handlers_disconnect_by_func (adjustment,
+ chat_view_adjustment_value_changed_cb, user_data);
+ return;
+ }
+
+ lower = (guint) gtk_adjustment_get_lower (adjustment);
+ value = (guint) gtk_adjustment_get_value (adjustment);
+ if (value != lower)
+ return;
+
+ /* Request for more logs to be fetched if the user hit the
+ * upper edge of the chat->view.
+ */
+ chat_schedule_logs (chat);
+}
+
+static gboolean
+chat_scrollable_connect (gpointer user_data)
+{
+ EmpathyChat *chat = EMPATHY_CHAT (user_data);
+ GtkAdjustment *adjustment;
+
+ adjustment = gtk_scrollable_get_vadjustment (
+ GTK_SCROLLABLE (chat->view));
+
+ g_signal_connect (adjustment, "changed",
+ G_CALLBACK (chat_view_adjustment_changed_cb), chat);
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (chat_view_adjustment_value_changed_cb), chat);
+
+ return G_SOURCE_REMOVE;