soc.2009.webkitmessageview: b7d6654d: webkit: Scroll to end when appending htm...
masca at cpw.pidgin.im
masca at cpw.pidgin.im
Sat Feb 6 17:26:24 EST 2010
-----------------------------------------------------------------
Revision: b7d6654d1d021c7532b71594ebcd325ee7b14456
Ancestor: bb76fe6ad2d9f7f8803db3d7bd34444111107caa
Author: masca at cpw.pidgin.im
Date: 2010-02-06T22:18:05
Branch: im.pidgin.soc.2009.webkitmessageview
URL: http://d.pidgin.im/viewmtn/revision/info/b7d6654d1d021c7532b71594ebcd325ee7b14456
Modified files:
pidgin/gtkconv.c pidgin/gtkwebview.c pidgin/gtkwebview.h
ChangeLog:
webkit: Scroll to end when appending html.
Most of the code was taken from imhtml.
-------------- next part --------------
============================================================
--- pidgin/gtkconv.c 1bbb2ffbe149b9c0824d354e70029702f4046a33
+++ pidgin/gtkconv.c ce21c33ba93a87f354c433c07274f4f923609f5e
@@ -4915,6 +4915,8 @@ setup_common_pane(PidginConversation *gt
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (webview_sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtkconv->webview = gtk_webview_new ();
+ gtk_webview_set_vadjustment(GTK_WEBVIEW(gtkconv->webview),
+ gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(webview_sw)));
gtk_container_add (GTK_CONTAINER (webview_sw), gtkconv->webview);
gtk_widget_set_size_request(gtkconv->webview, -1, 0);
============================================================
--- pidgin/gtkwebview.c bfedf0416858968394db3ae3083643f37fda14e1
+++ pidgin/gtkwebview.c 65d96c09c04829a05e1b4838e57a3aa90466f2f8
@@ -48,6 +48,9 @@ struct GtkWebViewPriv {
/* JS execute queue */
GQueue *js_queue;
gboolean is_loading;
+ GtkAdjustment *vadj;
+ guint scroll_src;
+ GTimer *scroll_time;
};
GtkWidget* gtk_webview_new (void)
@@ -290,6 +293,10 @@ char *gtk_webview_quote_js_string(const
return g_string_free (str, FALSE);
}
+void gtk_webview_set_vadjustment(GtkWebView *webview, GtkAdjustment *vadj)
+{
+ webview->priv->vadj = vadj;
+}
/* this is a "hack", my plan is to eventually handle this
* correctly using a signals and a plugin: the plugin will have
@@ -304,6 +311,7 @@ gtk_webview_append_html (GtkWebView* vie
printf ("script: %s\n", script);
webkit_web_view_execute_script (WEBKIT_WEB_VIEW (view), script);
view->priv->empty = FALSE;
+ gtk_webview_scroll_to_end(view, TRUE);
g_free (script);
g_free (escaped);
}
@@ -313,6 +321,65 @@ gboolean gtk_webview_is_empty (GtkWebVie
return view->priv->empty;
}
+#define MAX_SCROLL_TIME 0.4 /* seconds */
+#define SCROLL_DELAY 33 /* milliseconds */
+
+/*
+ * Smoothly scroll a WebView.
+ *
+ * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom.
+ */
+static gboolean smooth_scroll_cb(gpointer data)
+{
+ struct GtkWebViewPriv *priv = data;
+ GtkAdjustment *adj = priv->vadj;
+ gdouble max_val = adj->upper - adj->page_size;
+ gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3);
+
+ g_return_val_if_fail(priv->scroll_time != NULL, FALSE);
+
+ if (g_timer_elapsed(priv->scroll_time, NULL) > MAX_SCROLL_TIME || scroll_val >= max_val) {
+ /* 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;
+ g_source_remove(priv->scroll_src);
+ priv->scroll_src = 0;
+ return FALSE;
+ }
+
+ /* scroll by 1/3rd the remaining distance */
+ gtk_adjustment_set_value(adj, scroll_val);
+ return TRUE;
+}
+
+static gboolean scroll_idle_cb(gpointer data)
+{
+ struct GtkWebViewPriv *priv = data;
+ GtkAdjustment *adj = priv->vadj;
+ if(adj) {
+ gtk_adjustment_set_value(adj, adj->upper - adj->page_size);
+ }
+ priv->scroll_src = 0;
+ return FALSE;
+}
+
+void gtk_webview_scroll_to_end(GtkWebView *webview, gboolean smooth)
+{
+ struct GtkWebViewPriv *priv = webview->priv;
+ if (priv->scroll_time)
+ g_timer_destroy(priv->scroll_time);
+ if (priv->scroll_src)
+ g_source_remove(priv->scroll_src);
+ if(smooth) {
+ priv->scroll_time = g_timer_new();
+ priv->scroll_src = g_timeout_add_full(G_PRIORITY_LOW, SCROLL_DELAY, smooth_scroll_cb, priv, NULL);
+ } else {
+ priv->scroll_time = NULL;
+ priv->scroll_src = g_idle_add_full(G_PRIORITY_LOW, scroll_idle_cb, priv, NULL);
+ }
+}
+
GType gtk_webview_get_type (void)
{
static GType mview_type = 0;
============================================================
--- pidgin/gtkwebview.h 916745054254d00d1da0d77f4d7ce6a18a551cb3
+++ pidgin/gtkwebview.h e78dca4f64edf567173dd5421ba60614bd6edd39
@@ -73,6 +73,14 @@ GtkWidget* gtk_webview_new (void);
GtkWidget* gtk_webview_new (void);
/**
+ * Set the vertical adjustment for the GtkWebView.
+ *
+ * @param webview The GtkWebView.
+ * @param vadj The GtkAdjustment that control the webview.
+ */
+void gtk_webview_set_vadjustment(GtkWebView *webview, GtkAdjustment *vadj);
+
+/**
* A very basic routine to append html, which can be considered
* equivalent to a "document.write" using JavaScript.
*
@@ -124,4 +132,12 @@ char* gtk_webview_quote_js_string (const
*/
char* gtk_webview_quote_js_string (const char* str);
+/**
+ * Scrolls the Webview to the end of its contents.
+ *
+ * @param webview The GtkWebView.
+ * @param smoth A boolean indicating if smooth scrolling should be used.
+ */
+void gtk_webview_scroll_to_end(GtkWebView *webview, gboolean smooth);
+
#endif /* _PIDGIN_WEBVIEW_H_ */
More information about the Commits
mailing list