diff options
author | Jorge Villase?or <salinasv@pidgin.im> | 2015-06-25 22:03:17 -0700 |
---|---|---|
committer | Jorge Villase?or <salinasv@pidgin.im> | 2015-06-25 22:03:17 -0700 |
commit | bb9984da5fe906c5168eaf7275cc9e7025d496bb (patch) | |
tree | 5b7f26938c7bc9d01f1241f57face797ce93205c | |
parent | 662fb30f8b7eae59a1a546929a21aae8f75d4ade (diff) | |
download | pidgin-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.c | 94 | ||||
-rw-r--r-- | pidgin/gtkwebview.c | 39 | ||||
-rw-r--r-- | pidgin/gtkwebview.h | 27 |
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 * |