/pidgin/main: 7d46a8a4bc58: Set the size of the gtkconv entry

Jorge Villase?or salinasv at pidgin.im
Fri Jun 26 01:11:09 EDT 2015


Changeset: 7d46a8a4bc58d720526255021c5152090d818b84
Author:	 Jorge Villase?or <salinasv at pidgin.im>
Date:	 2015-06-25 22:03 -0700
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/7d46a8a4bc58

Description:

Set the size of the gtkconv entry

The change to Webkit on the conversation entry widget introduced a regression
that gave it a size of 0-1 pixels. This commit fixes that regression.

We set the min size of the widget based on the Webkit font size and the min_lines
preference. It then grows as the user add lines to the entry based on the
calculated DOM size up to half the conversation window height.

There are a couple of pieces missing, still this is better than the 0 pixels
height size.

TODO:
* The font padding and text padding are magic numbers, need to find a way to get
them from the DOM
* When removing one line <BR> the DOM does not calculate the new height immediately
we need to find a way to force that calculation.

diffstat:

 pidgin/gtkconv.c    |  104 ++++++++++++++++++++++------------------------------
 pidgin/gtkwebview.c |   39 +++++++++++++++++++
 pidgin/gtkwebview.h |   27 +++++++++++++
 3 files changed, 110 insertions(+), 60 deletions(-)

diffs (229 lines):

diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -4932,73 +4932,53 @@ entry_popup_menu_cb(PidginWebView *webvi
 static gboolean
 resize_webview_cb(PidginConversation *gtkconv)
 {
-#if 0
-	/* TODO WebKit: entry sizing */
-	GtkTextBuffer *buffer;
-	GtkTextIter iter;
-	int lines;
-	GdkRectangle oneline;
-	int height, diff;
-	int pad_top, pad_inside, pad_bottom;
-	int total_height;
-	int max_height;
-	int min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
-	int min_height;
-	gboolean interior_focus;
-	int focus_width;
+	WebKitWebView *webview;
+	gint min_lines;
+	gint max_height;
+	gint min_height;
+	gint font_size;
+	gint total_height;
+	gint height;
+	gint toolbar_size;
 	GtkAllocation webview_allocation;
 	GtkAllocation entry_allocation;
-	GtkAllocation lower_hbox_allocation;
-
+
+	webview = PIDGIN_WEBVIEW(gtkconv->entry);
+
+	/* Get text height from the DOM */
+	height = pidgin_webview_get_DOM_height(webview);
+
+	/* Find the height of the conversation window to calculate the maximum possible entry
+	 * size (1/2 of the window)
+	 */
 	gtk_widget_get_allocation(gtkconv->webview, &webview_allocation);
 	gtk_widget_get_allocation(gtkconv->entry, &entry_allocation);
-	gtk_widget_get_allocation(gtkconv->lower_hbox, &lower_hbox_allocation);
 	total_height = webview_allocation.height + entry_allocation.height;
 	max_height = total_height / 2;
 
-	pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(gtkconv->entry));
-	pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(gtkconv->entry));
-	pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(gtkconv->entry));
-
-	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
-	gtk_text_buffer_get_start_iter(buffer, &iter);
-	gtk_text_view_get_iter_location(GTK_TEXT_VIEW(gtkconv->entry), &iter, &oneline);
-
-	lines = gtk_text_buffer_get_line_count(buffer);
-
-	height = 0;
-	do {
-		int lineheight = 0;
-		gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(gtkconv->entry), &iter, NULL, &lineheight);
-		height += lineheight;
-		lines--;
-	} while (gtk_text_iter_forward_line(&iter));
-	height += lines * (oneline.height + pad_top + pad_bottom);
-
-	/* Make sure there's enough room for at least min_lines. Allocate enough space to
-	 * prevent scrolling when the second line is a continuation of the first line, or
-	 * is the beginning of a new paragraph. */
-	min_height = min_lines * (oneline.height + MAX(pad_inside, pad_top + pad_bottom));
+	/* Get size of the characters to calculate initial minimum space for the entry */
+	font_size = pidgin_webview_get_font_size(webview);
+
+	/* Allow to have a minimum of "min_lines" height as defined in the preference */
+	min_lines = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/minimum_entry_lines");
+	min_height = (font_size + WEBVIEW_DOM_FONT_PADDING) * min_lines + WEBVIEW_DOM_TEXT_PADDING;
+
+
+	/* Take into account the size of the formatting toolbar */
+	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar")) {
+		toolbar_size = gtk_widget_get_allocated_height(pidgin_webview_get_toolbar(webview));
+	} else {
+		toolbar_size = 0;
+	}
+
+	/* Calculate conv entry height */
 	height = CLAMP(height, MIN(min_height, max_height), max_height);
-
-	gtk_widget_style_get(gtkconv->entry,
-	                     "interior-focus", &interior_focus,
-	                     "focus-line-width", &focus_width,
-	                     NULL);
-	if (!interior_focus)
-		height += 2 * focus_width;
-
-	diff = height - entry_allocation.height;
-	if (ABS(diff) < oneline.height / 2)
-		return FALSE;
-
-	purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n",
-	                  diff + lower_hbox_allocation.height, min_lines, diff);
-
-	gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
-		diff + lower_hbox_allocation.height);
-#endif
-	gtk_widget_set_size_request(gtkconv->lower_hbox, -1, -1);
+	/* Add the size used by the toolbar so we always take it into consideration. */
+	height += toolbar_size;
+
+	/* Actually set the size of the gtkconv entry widget. */
+	gtk_widget_set_size_request(gtkconv->lower_hbox, -1, height);
+	purple_debug_info("pidgin", "resizing to %d, %d lines\n", height, min_lines);
 
 	return FALSE;
 }
@@ -5718,6 +5698,10 @@ setup_common_pane(PidginConversation *gt
 	g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "size-allocate",
 				 G_CALLBACK(resize_webview_cb), gtkconv);
 #endif
+	g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "changed",
+				 G_CALLBACK(resize_webview_cb), gtkconv);
+	g_signal_connect_swapped(G_OBJECT(gtkconv->entry), "size-allocate",
+				 G_CALLBACK(resize_webview_cb), gtkconv);
 
 	default_formatize(gtkconv);
 	g_signal_connect_after(G_OBJECT(gtkconv->entry), "format-cleared",
@@ -8135,7 +8119,7 @@ show_formatting_toolbar_pref_cb(const ch
 		else
 			pidgin_webview_hide_toolbar(PIDGIN_WEBVIEW(gtkconv->entry));
 
-		g_idle_add((GSourceFunc)resize_webview_cb, gtkconv);
+		resize_webview_cb(gtkconv);
 	}
 }
 
diff --git a/pidgin/gtkwebview.c b/pidgin/gtkwebview.c
--- a/pidgin/gtkwebview.c
+++ b/pidgin/gtkwebview.c
@@ -2259,6 +2259,45 @@ pidgin_webview_insert_image(PidginWebVie
 	g_free(img);
 }
 
+static WebKitDOMCSSStyleDeclaration*
+pidgin_webview_get_DOM_CSS_style(PidginWebView *webview)
+{
+	//WebKitDOMCSSStyleDeclaration *style;
+	WebKitDOMDocument *document;
+	WebKitDOMElement *dom_element;
+	WebKitDOMDOMWindow *dom_window;
+
+	document = webkit_web_view_get_dom_document(webview);
+	dom_window = webkit_dom_document_get_default_view(document);
+
+	dom_element = webkit_dom_document_get_document_element(document);
+	return webkit_dom_dom_window_get_computed_style(dom_window, dom_element, 0);
+}
+
+gint
+pidgin_webview_get_DOM_height(PidginWebView *webview)
+{
+	gchar *value;
+	WebKitDOMCSSStyleDeclaration *style;
+
+	style = pidgin_webview_get_DOM_CSS_style(webview);
+	value = webkit_dom_css_style_declaration_get_property_value(style, "height");
+
+	return g_ascii_strtoll(value, NULL, 0);
+}
+
+gint
+pidgin_webview_get_font_size(PidginWebView *webview)
+{
+	gchar *value;
+	WebKitDOMCSSStyleDeclaration *style;
+
+	style = pidgin_webview_get_DOM_CSS_style(webview);
+	value = webkit_dom_css_style_declaration_get_property_value(style, "font-size");
+
+	return g_ascii_strtoll(value, NULL, 0);
+}
+
 void
 pidgin_webview_set_toolbar(PidginWebView *webview, GtkWidget *toolbar)
 {
diff --git a/pidgin/gtkwebview.h b/pidgin/gtkwebview.h
--- a/pidgin/gtkwebview.h
+++ b/pidgin/gtkwebview.h
@@ -42,6 +42,11 @@
 #define PIDGIN_IS_WEBVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PIDGIN_TYPE_WEBVIEW))
 #define PIDGIN_WEBVIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), PIDGIN_TYPE_WEBVIEW, PidginWebViewClass))
 
+
+/*salinasv: this are partially magic numbers, we need to find how to get them from the DOM */
+#define WEBVIEW_DOM_FONT_PADDING 3
+#define WEBVIEW_DOM_TEXT_PADDING 16
+
 typedef enum {
 	PIDGIN_WEBVIEW_BOLD          = 1 << 0,
 	PIDGIN_WEBVIEW_ITALIC        = 1 << 1,
@@ -586,6 +591,28 @@ void
 pidgin_webview_insert_image(PidginWebView *webview, PurpleImage *image);
 
 /**
+ * pidgin_webview_get_DOM_height:
+ * @webview: the PidginWebView.
+ *
+ * Look for the calculated height for the DOM on the webview.
+ *
+ * Returns the total height of the DOM in the webview.
+ */
+gint
+pidgin_webview_get_DOM_height(PidginWebView *webview);
+
+/**
+ * pidgin_webview_get_DOM_height:
+ * @webview: the PidginWebView.
+ *
+ * Look for the font size used on the current webview
+ *
+ * Returns the font size for the webview.
+ */
+gint
+pidgin_webview_get_font_size(PidginWebView *webview);
+
+/**
  * pidgin_webview_get_protocol_name:
  * @webview: The PidginWebView
  *



More information about the Commits mailing list