summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Villase?or <salinasv@pidgin.im>2015-06-25 22:03:17 -0700
committerJorge Villase?or <salinasv@pidgin.im>2015-06-25 22:03:17 -0700
commitbb9984da5fe906c5168eaf7275cc9e7025d496bb (patch)
tree5b7f26938c7bc9d01f1241f57face797ce93205c
parent662fb30f8b7eae59a1a546929a21aae8f75d4ade (diff)
downloadpidgin-bb9984da5fe906c5168eaf7275cc9e7025d496bb.tar.gz
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.
-rw-r--r--pidgin/gtkconv.c94
-rw-r--r--pidgin/gtkwebview.c39
-rw-r--r--pidgin/gtkwebview.h27
3 files changed, 105 insertions, 55 deletions
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
index 37c88f1955..32abe17ea3 100644
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -4932,73 +4932,53 @@ entry_popup_menu_cb(PidginWebView *webview, GtkMenu *menu, gpointer data)
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));
+ /* Get size of the characters to calculate initial minimum space for the entry */
+ font_size = pidgin_webview_get_font_size(webview);
- 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));
- height = CLAMP(height, MIN(min_height, max_height), max_height);
+ /* 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;
- 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;
+ /* 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;
+ }
- purple_debug_info("pidgin", "resizing to %d, %d lines, diff %d\n",
- diff + lower_hbox_allocation.height, min_lines, diff);
+ /* Calculate conv entry height */
+ height = CLAMP(height, MIN(min_height, max_height), max_height);
+ /* Add the size used by the toolbar so we always take it into consideration. */
+ height += toolbar_size;
- 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);
+ /* 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 *gtkconv)
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 char *name, PurplePrefType type,
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
index be9ab9302c..34366449cd 100644
--- a/pidgin/gtkwebview.c
+++ b/pidgin/gtkwebview.c
@@ -2259,6 +2259,45 @@ pidgin_webview_insert_image(PidginWebView *webview, PurpleImage *image)
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
index 4f8b0fbff0..436daecc23 100644
--- 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
*