GNOME Bugzilla – Bug 322580
GtkLabel doesn't wrap when width_chars is set
Last modified: 2007-01-07 00:54:09 UTC
Please describe the problem: I want to define a width in characters of a GtkLabel widget, and I would like the string it shows to wrap if it is too long. However, the string doesn't wrap. Instead, only a part of it is shown. Steps to reproduce: 1. Create a GtkLabel widget and put a very long string inside it. 2. Set wrapping to true, and width in chars to something small (say, 20 or 10). 3. Just for fun, set single line mode to false and ellipsize to none :) 4. Display the form with the widget. Actual results: The widget is displayed with only one line that displays just a part of the string. Expected results: The widget should be in the width I wanted, but with several lines displaying the wrapped string. Does this happen every time? yes. Other information:
It doesn't quite work as you would expect, since we don't do width-for-height geometry management. If you want the line to be wrapped to a certain width, you have to set the size of the widget, doing something like gtk_widget_set_usize (label, 50, -1);
I don't understand how width-for-height geometry managment is related. What is the difference between setting the width of the widget in pixels to setting the width of the widget in chars?
I am sorry, I would really like to recieve some kind of answer to my last question...
When I checked the code of GtkLabel and GtkWidget I noticed that both gtk_widget_set_usize and gtk_label_set_width_chars call gtk_widget_queue_resize. That's why I don't understand the difference between the two methods of width setting, nor why wrapping works in one case and not in the other.
If I understand it correctly, width_chars is not "the width of the label in chars" but instead "the amount of chars allowed in the label". Probably just unfortunate legacy naming from before line-wrapping was in place or simply a bad one.
By reading the code and the documentation, width_chars IS the width of the widget in average-char-width-units. When there is an option to limit the length of the string in characters it is usually called max_length or max_chars... something like that anyway :) The code as I read it was actually requesting a new width the same way any other width requisition is made, when the width was calculated by the number of chars wanted times the width of an average character (I haven't read that code for a long time, don't remember exactly, but it's something like that). Itai.
I think this is a GtkLabel bug: static void gtk_label_ensure_layout (GtkLabel *label) { [....] [ Gets the width set by gtk_widget_set_usize(); ] aux_info = _gtk_widget_get_aux_info (widget, FALSE); if (aux_info && aux_info->width > 0) pango_layout_set_width (label->layout, aux_info->width * PANGO_SCALE); [ No width, pick something based on font, screen size etc ] else { } But it probably needs a: else if (private->width_chars > 0 || private->max_width_chars > 0) { } there. The interaction between width_chars and max_width_chars would have to be thought through. width_chars and max_width_chars were added for ellipsization so probably have never been tested for wrapping.
hmm... I actually think it would be smart to allow every textual widget to have size-by-chars properties. Both width AND height. It generally makes sense that you would like to define a text area's base size to be, say, 50 chars wide and 5 lines high. And the same goes for many other widgets (lists and trees, labels, etc.) Actually, it might apply to all widgets, since you just might want to synchronize the size of widgets in your application, and it would make more sense to synchronize the sizes by textual units (char's width and height) than by pixels... But then again, this has already been proposed in the "Units other than pixels" bug... Maybe its time :) Itai.
2007-01-06 Matthias Clasen <mclasen@redhat.com> * gtk/gtklabel.c: Make line wrapping work with width-chars and max-width-chars, and simplify the storage of wrap-width. (#322580, Itai Bar-Haim)