GNOME Bugzilla – Bug 315462
GtkButton doesn't center its child when the child is too large for its allocation
Last modified: 2009-05-13 00:43:10 UTC
Please describe the problem: When an application manually sets the size of a button the button may become too small to entirely display its child. Currently the failure mode is to display the child component at the same x and y coordinates but make it smaller to fit. This can cause children with borders, which would otherwise display fine, to be slightly clipped. A better failure mode would be to display the child based on the button's alignment setting, e.g. centering the child component when the alignment is 0.5, cutting off the top/left when the alignment is 0.0 and cutting off the bottom/right when the alignment is 1.0. Steps to reproduce: 1. build and run attached test case Actual results: Expected results: Does this happen every time? Other information:
Created attachment 51927 [details] demonstrates text being clipped vertically when button is too small Run: gcc -g -Wall `pkg-config --cflags --libs gtk+-2.0` -o gtk-button-child-size gtk-button-child-size.c to build this test case.
This actually seems to be a problem with GtkLabel. The button does center its child properly but the label text is drawn too low vertically. The problem is that get_layout_location in gtklabel.c is never allowed to return a negative y value. Instead, the returned y value is at minimum (widget->allocation.y + (gint)misc->ypad) meaning that in these small-size situations the label text will be off-center vertically.
Created attachment 51997 [details] test case demonstrating button label behaviour at small button sizes Here is a better demonstration of the problem. Compile the test case with this command: gcc -g -Wall `pkg-config --cflags --libs gtk+-2.0` -o gtk-label-layout-location gtk-label-layout-location.c
Created attachment 51998 [details] [review] patch that fixes small size button label y offset Here is a patch that fixes this particular problem but it may not be safe in general; it allows get_layout_location to return a negative y value when the label's requisition height is greater than its allocation height.
Is there any news on this?
Patch works as intended. But the removal of the MAX clamp means that get_layout_location () may return -1 for y which I don't think is good. -1 has a special meaning as the default value before the GtkLabel is realized. I think the calculation should be change to this which makes y always >= 0 and preserves the good effects when the button containing the label is to small. y = MAX (floor (widget->allocation.y + (gint) misc->ypad + (widget->allocation.height - widget->requisition.height) * misc->yalign), 0);
*** Bug 524166 has been marked as a duplicate of this bug. ***
Created attachment 126693 [details] [review] gtk2-bnc310710-bgo524166-underallocated-gtklabel-position.diff Any news here? Opensuse is still applying attached patch in theit gtk+-2.14 build Thanks :-)
I've just committed openSUSE's patch to master and gtk-2-16. master - commit 26c10075f95268ed2d8dbfacadeb1cdc0f559da6 gtk-2-16 - commit 67e0a44100a288fd3374f932ba976c64e744474f Björn said: (In reply to comment #6) > Patch works as intended. But the removal of the MAX clamp means that > get_layout_location () may return -1 for y which I don't think is good. -1 has > a special meaning as the default value before the GtkLabel is realized. There is no such default; the label computes its layout location on the fly on every expose. Negative values are perfectly safe; you are drawing on the parent window anyway :) Finally, Thomas's patch is fine, but I think we can deal more gracefully with multi-line labels by giving preference to the first line. This is what the committed patch does. Someone may want to give more testing to this... we *may* need to set a clipping region equal to the label's allocation before the call to gtk_paint_layout(), to avoid labels overlapping a button's frame.