GNOME Bugzilla – Bug 104188
Add height-for-width geometry management
Last modified: 2010-04-14 07:33:12 UTC
In some cases, GTK+ really needs the idea of height-for-width geometry management. Height-for-width geometry management would involve a second pass of, once the width of a widget has been decided, figuring out the desired heights of the widgets. This would be done, most likely, as an optional extended-geometry management interface that widgets could optionally implement and check for on their children. Just adding it GtkLabel and making GtkVBox understand it would already help quite a bit. It probably makes sense to add width-for-height management at the same time. There may also be some other things that could be put in the extended geometry interface. When setting the geometry widget of a toplevel to a widget, having the widget provide all the different toplevel hints can be interesting, though you can't really propagate those up a heirarchy.
Putting on 2.4 API freeze for the moment.
Another thing that could be put in such an interface is "baseline", so that it would be possible to align widget by baseline.
Adding some more details here at the request of Charles Lambert: The basic idea of height-for-width is that you have an interface like: struct _GtkExtLayoutIface { GtkFlags (*get_flags) (GtkExtLayout *layout); gint (*height_for_width) (GtkExtLayout *layout, gint width); gint (*width_for_height) (GtkExtLayout *layout, gint height); }; (Flags would contain hints about whether the width depends on the height, or the height depends on the width, etc.) Then when GtkVBox got a size_allocate(), instead of simply computing the allocations of its children from their requisitions, it would check to see if its children support GtkExtLayout - for children that support GtkExtLayout, it would use for a height: child.height_for_width (vbox->allocation.width) GtkVBox itself would also support GtkExtLayout - it just takes the sum of height_for_width() of all its children. Similarly GtkHBox could easily support width_for_height(). Just doing this for GtkVBox and GtkLabel pretty easily fixes one well-known problem ... the problem of a stack of wrapped labels in a GtkVBox, but there are some sticky issues as well: - Right now, the requisition of a widget acts both as its minimum size and its default size. But width height-for-width, this works much less well, since a wrapped label would have, say, minimum_width = 100 pixels minimum_height = 10 pixels But you might want a default size of 500 pixels wide and 200 pixels tall. - How does this work at the level of a toplevel window? X doesn't really have the idea of height-for-width in the application/window manager interface, though it may work fine to simply change the hints reported to the window manager in response to configure events. - To what GTK+ containers can the idea be extended? What is the right algorithm for GtkTable, for example? - How does this interact with GtkSizeGroup?
I'd like to work on this bug. Regarding "the right algorithm for GtkTable": Guess GtkTable would have to ask the child for its preferred orientation and then call width_for_height or height_for_width accordingly? Well and regarding GtkSizeGroup: Don't really know this object yet, but from looking at its docs, calling width_for_height or height_for_width would have to be choosen on basis of the group's GtkSizeGroupMode. If that mode is none, "horizontal" or "vertical": Easy going. For "both" we are in the same mess as for GtkTable, I guess.
A GtkTable conceivably could contain a mix of width-for-height and height-for-width children. You'd have to figure out an algorithm for deciding whether the overall table acted as width-for-height or height-for-width, then how to do the computation. If you read the code, you'll find that GtkSizeGroup is actually intimitly intertwined with the workings of the current code .. gtk_widget_size_request, for example, simply calls: _gtk_size_group_compute_requisition (widget, requisition); So the question about it is to some extent, really about implementation then interface. But at the behavior level, I think it's a little more complex then what you've sketched out. Say we have two height-for-width labels. Then if they are grouped horizontal, then we'd expect to ask both for a desired width, take the max of those two width, ask each label for a desired height for that max width, and allocate at (max_width,height1) (max_width,height2). If we group them vertically, then we ask both for a desired width, ask them for a desired height for that width, the take the max of the two heights and allocate at (width1, max_height) (width2, max_height)_ So the operation of the size group appears at a different point in get-width, get-height-for-width, allocate pass in the two cases. One of the first steps in this would be to sit down, create some sample configurations, and figure out what behavior one would expect for each sample configuration.
Created attachment 97470 [details] [review] The extended layout manager patch in its full glory. Attaching the new layout manager patch in its full glory. Currently in the process of splitting it into smaller pieces for easy review. http://live.gnome.org/MathiasHasselmann/NewLayoutManager
The splitted up patches attached to bug 101968 by accident.
I believe that Mathias also posted an alternative version of the patch that matched Havoc's preference for how to do this, on the mailing list. That should really be here.
Created attachment 113800 [details] [review] Support ellipsizing and wrapping on labels rotated by multiples of 90°. This topic also is addressed in bug 508242, AFAIR.
Created attachment 113801 [details] [review] Merge nearly identical size-allocation loops for start and end packing in GtkHBox.
Created attachment 113802 [details] [review] Introduce GtkExtendedLayout interface. Extended layout management, Havoc/Behdad style. See also: http://mail.gnome.org/archives/gtk-devel-list/2008-January/msg00043.html
I attached to http://bugzilla.gnome.org/show_bug.cgi?id=101968 three patches that fix bugs on extended-layout branch See also http://permalink.gmane.org/gmane.comp.gnome.gtk+.devel.general/15790 http://permalink.gmane.org/gmane.comp.gnome.gtk+.devel.general/15791 http://permalink.gmane.org/gmane.comp.gnome.gtk+.devel.general/15792
punting to 3.0
I am closing this as a duplicate of #101968 because that's where most of the activity is. *** This bug has been marked as a duplicate of bug 101968 ***