[evolution/webkit: 117/124] Improve autoresizing of webviews



commit b0d4058e42bc4c889a1a51efc2a45e9d05893a83
Author: Dan VrÃtil <dvratil redhat com>
Date:   Fri Jan 13 17:22:33 2012 +0100

    Improve autoresizing of webviews
    
    This is still has some issues with HTML email (especially various outlets and
    similar webpage-like emails), but works very very well with standard emails.

 data/webview.css          |    6 +++
 mail/e-mail-display.c     |   56 ++++++++++++++++++--------------
 widgets/misc/Makefile.am  |    1 +
 widgets/misc/e-web-view.c |   77 ++++++++++++++++++++++++++++++++++++++++++++-
 widgets/misc/e-web-view.h |    1 -
 5 files changed, 115 insertions(+), 26 deletions(-)
---
diff --git a/data/webview.css b/data/webview.css
index 2abf346..cd396cf 100644
--- a/data/webview.css
+++ b/data/webview.css
@@ -71,4 +71,10 @@ img.navigable {
 
 .attachments-list th {
   font-weight: bold;
+}
+
+#_evo_bottom_element {
+  clear: both;
+  width: 100%;
+  height: 2px;
 }
\ No newline at end of file
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index 4b8aa0e..408dc18 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -692,6 +692,7 @@ mail_display_setup_webview (EMailDisplay *display,
 	GError *error = NULL;
 
 	web_view = E_WEB_VIEW (e_web_view_new ());
+	webkit_web_view_set_full_content_zoom (WEBKIT_WEB_VIEW (web_view), TRUE);
 	e_web_view_set_settings (web_view, display->priv->settings);
 
 	g_signal_connect (web_view, "navigation-policy-decision-requested",
@@ -752,19 +753,29 @@ mail_display_setup_webview (EMailDisplay *display,
 }
 
 static void
-mail_display_on_web_view_vadjustment_changed (GtkAdjustment* adjustment,
-					      gpointer user_data)
+mail_display_on_web_view_sw_vadjustment_changed (GtkAdjustment* adjustment,
+						 gpointer user_data)
 {
-	GtkWidget *widget = user_data;
-	int upper = gtk_adjustment_get_upper (GTK_ADJUSTMENT (adjustment));
-	int page_size = gtk_adjustment_get_page_size (GTK_ADJUSTMENT (adjustment));
-	int widget_height = gtk_widget_get_allocated_height (widget);
-
-	if (page_size < upper) {
-		gtk_widget_set_size_request (GTK_WIDGET (widget), -1, upper + (widget_height - page_size));
-		gtk_widget_queue_resize (GTK_WIDGET (widget));
+	GtkWidget *scrolled_window = user_data;
+	GtkWidget *hscrollbar;
+	GtkWidget *web_view;
+	gint new_height;
+
+	web_view = gtk_bin_get_child (GTK_BIN (scrolled_window));
+	gtk_widget_get_preferred_height (web_view, &new_height, NULL);
+
+	/* We now have height of the webview's view, but to correctly resize the
+	 * parent scrolled window we need to add height of horizontal scrollbar (if visible) */
+	hscrollbar = gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW (scrolled_window));
+	if (hscrollbar && gtk_widget_get_visible (hscrollbar)) {
+		gint scrollbar_height;
+		gtk_widget_get_preferred_height (hscrollbar, &scrollbar_height, NULL);
+		new_height += scrollbar_height;
 	}
-	
+
+	g_message ("WebView want height %d", new_height);
+
+	gtk_widget_set_size_request (scrolled_window, -1, new_height);
 }
 
 static GtkWidget*
@@ -772,26 +783,23 @@ mail_display_insert_web_view (EMailDisplay *display,
 			      EWebView *web_view)
 {
 	GtkWidget *scrolled_window;
-	GtkAdjustment *web_view_vadjustment;
+	GtkAdjustment *vadjustment;
         GdkWindow *window;
 
 	display->priv->webviews = g_list_append (display->priv->webviews, web_view);
 	scrolled_window = gtk_scrolled_window_new (NULL, NULL);
 	g_object_set (G_OBJECT (scrolled_window),
-		"hscrollbar-policy", GTK_POLICY_AUTOMATIC,
-		"vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+		"vexpand", FALSE,
+		"vexpand-set", TRUE,
 		"shadow-type", GTK_SHADOW_NONE,
-		"hexpand", TRUE,
-		      "vexpand", FALSE,
-		      "vexpand-set", TRUE,
 		NULL);
-	g_object_set (G_OBJECT (web_view),
-		      "vscroll-policy", GTK_SCROLL_NATURAL,
-		      NULL);
-		//"min-content-height", 300, NULL);
-	web_view_vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window));
-	g_signal_connect (G_OBJECT (web_view_vadjustment), "changed",
-			  G_CALLBACK (mail_display_on_web_view_vadjustment_changed), scrolled_window);
+
+	vadjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window));
+	g_signal_connect (G_OBJECT (vadjustment), "changed",
+		G_CALLBACK (mail_display_on_web_view_sw_vadjustment_changed), scrolled_window);
+	g_signal_connect (G_OBJECT (vadjustment), "value-changed",
+		G_CALLBACK (mail_display_on_web_view_sw_vadjustment_changed), scrolled_window);
+	
 	gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (web_view));
 
         gtk_box_pack_start (GTK_BOX (display->priv->box), scrolled_window, FALSE, TRUE, 0);
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index 9e76e8b..240146c 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -77,6 +77,7 @@ libemiscwidgets_la_CPPFLAGS =						\
 	-I$(top_srcdir)/widgets						\
 	-DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\"			\
 	-DEVOLUTION_UIDIR=\""$(uidir)"\"				\
+	-DEVOLUTION_PRIVDATADIR=\""$(privdatadir)"\"    		\
 	-DG_LOG_DOMAIN=__FILE__						\
 	$(EVOLUTION_DATA_SERVER_CFLAGS)					\
 	$(GNOME_PLATFORM_CFLAGS)					\
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
index 6d633c8..41bc624 100644
--- a/widgets/misc/e-web-view.c
+++ b/widgets/misc/e-web-view.c
@@ -22,6 +22,8 @@
 
 #include "e-web-view.h"
 
+#include <math.h>
+
 #include <JavaScriptCore/JavaScript.h>
 
 #include <string.h>
@@ -39,6 +41,7 @@
 
 #include "e-popup-action.h"
 #include "e-selectable.h"
+#include <stdlib.h>
 
 #define E_WEB_VIEW_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -837,6 +840,73 @@ web_view_scroll_event (GtkWidget *widget,
 	return FALSE;
 }
 
+static void
+web_view_get_preferred_height (GtkWidget *widget,
+			       gint *minimum_height,
+			       gint *natural_height)
+{
+	WebKitWebView *web_view;
+	WebKitDOMDocument *document;
+	WebKitDOMElement *body, *last_el;
+	gint doc_height;
+
+	if (!minimum_height && !natural_height)
+		return;
+
+	web_view = WEBKIT_WEB_VIEW (widget);
+	document = webkit_web_view_get_dom_document (web_view);
+	if (!document)
+		goto chainup;
+
+	body = WEBKIT_DOM_ELEMENT (webkit_dom_document_get_body (document));
+	if (!body)
+		goto chainup;
+
+	/* Last element in DOM != the undermost element displayed.
+	 * Thus we create our own element which is guaranteed to be displayed
+	 * at the very bottom */
+	last_el = webkit_dom_document_get_element_by_id (document, "_evo_bottom_element");
+	if (!last_el) {
+		last_el = webkit_dom_document_create_element (document, "DIV", NULL);
+		webkit_dom_html_element_set_id (WEBKIT_DOM_HTML_ELEMENT (last_el),
+			"_evo_bottom_element");
+		webkit_dom_node_append_child (WEBKIT_DOM_NODE (body),
+			WEBKIT_DOM_NODE (last_el), NULL);
+	}
+
+	/* The _actual_ height of page content is top + height of the
+	 * very last element in body */
+	/* FIXME: This seems to throw warnings, but it's the only method that
+	 * actually works */
+	doc_height = webkit_dom_element_get_offset_top (last_el) +
+			webkit_dom_element_get_offset_height (last_el);
+
+
+	/* Hardcoded bottom padding */
+	doc_height += 8;
+
+	/* When full content zoom is enabled then the elements are not resized
+	 * but rather scaled (thus they still claim their original height),
+	 * but we need to know the real current height */
+	if (webkit_web_view_get_full_content_zoom (web_view)) {
+		doc_height = ceil((gfloat) doc_height * webkit_web_view_get_zoom_level (web_view));
+	}
+
+	if (minimum_height)
+		*minimum_height = doc_height;
+
+	if (natural_height)
+		*natural_height = doc_height;
+
+	return;
+
+chainup:
+	if (GTK_WIDGET_CLASS (widget)->get_preferred_height) {
+		GTK_WIDGET_CLASS(widget)->get_preferred_height(widget,
+			minimum_height, natural_height);
+	}
+}
+
 static GtkWidget *
 web_view_create_plugin_widget (EWebView *web_view,
                                const gchar *mime_type,
@@ -1315,6 +1385,7 @@ e_web_view_class_init (EWebViewClass *class)
 	widget_class = GTK_WIDGET_CLASS (class);
 	widget_class->button_press_event = web_view_button_press_event;
 	widget_class->scroll_event = web_view_scroll_event;
+	widget_class->get_preferred_height = web_view_get_preferred_height;
 
 #if 0  /* WEBKIT */
 	html_class = GTK_HTML_CLASS (class);
@@ -2661,6 +2732,7 @@ e_web_view_get_default_settings(GtkWidget *parent_widget)
 	GtkStyleContext *context;
 	const PangoFontDescription *font;
 	WebKitWebSettings *settings;
+	const gchar *stylesheet;
 
 	g_return_val_if_fail (GTK_IS_WIDGET (parent_widget), NULL);
 
@@ -2670,10 +2742,13 @@ e_web_view_get_default_settings(GtkWidget *parent_widget)
 	context = gtk_widget_get_style_context (parent_widget);
 	font = gtk_style_context_get_font (context, GTK_STATE_FLAG_NORMAL);
 
+	stylesheet = EVOLUTION_PRIVDATADIR "/theme/webview.css";
+
 	g_object_set (G_OBJECT (settings),
 		      "default-font-size", (pango_font_description_get_size (font) / PANGO_SCALE),
 		      "default-monospace-font-size", (pango_font_description_get_size (font) / PANGO_SCALE),
-		      "enable-frame-flattening", TRUE, NULL);
+		      "enable-frame-flattening", TRUE,
+		      "user-stylesheet-uri", stylesheet, NULL);
 
 	return settings;	
 }
diff --git a/widgets/misc/e-web-view.h b/widgets/misc/e-web-view.h
index a54d53e..6b32501 100644
--- a/widgets/misc/e-web-view.h
+++ b/widgets/misc/e-web-view.h
@@ -218,7 +218,6 @@ gchar*          e_web_view_get_selection_html   (EWebView *web_view);
 
 void		e_web_view_set_settings		(EWebView *web_view,
 						 WebKitWebSettings *settings);
-
 WebKitWebSettings*
 		e_web_view_get_default_settings ();
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]