Skip to content

Fix measuring label min wfh with wrap+ellipsize+lines

Sergey Bugaev requested to merge bugaevc/gtk:label-measure-lines-ellipsize into main

This is the other label sizing fix that is a soft prereq for !6569. I initially had thought of, and implemented, a very different change, that made GtkLabel behave more like I expected it to. Yet, I saw that I was fundamentally missing a consistent model of how GtkLabel is supposed to behave when all three of wrap/ellipsize/lines are set. I got a better understanding of how this is supposed to work thanks to @matthiasc's explanations; based on that understanding, I looked for what goes wrong/differently in the actual implementation, and ended up with this patch.

I'm still not feeling entirely comfortable about this though, so please double-check that the explanation and the patch make sense to you!


GtkLabel's layout is influenced by the available horizontal space (allocated width), which affects both wrapping and ellipsization, but never the available vertical space (allocated height); instead, GtkLabel requests, as its minimum size in the vertical orientation, the exact height that it needs and is going to use for the layout.

For a label that has all of wrap, ellipsize, and lines set, this means that depending on the label text and the available width, the label may be wrapped into up to the specified number of lines. If there's still not enough space, the label will begin to ellipsize. Crucially, it won't start ellipsizing before reaching the specified number of lines. For example, if a label has lines = 5, it can take up anywhere between 1 to 5 lines, unellipsized, or 5 lines, ellipsized; but e.g. 2 lines, ellipsized is not a possible layout.

This has to be taken into account when measuring the label. If we're measuring width-for-height and the provided for_size (height) fits 2 lines, we must request enough width for the whole text to fit (into 2 lines), without any ellipsization happening. The existing logic instead assumed that when ellipsization is enabled, minimum width could always be set low. Change that to actually binary-search a layout width-for-height, just like it's done in the other branch.

This fixes another case of GtkLabel reporting inconsistent width-for-height and height-for-width measurements, which may break logic in the rest of the layout machinery.

Merge request reports