From 208ba9bb50227a2681515b9847c651dd943c7127 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Fri, 6 Aug 2010 15:58:12 -0400 Subject: [PATCH 1/9] Make GtkFrame allocate its label considering natural size requests Also like the GtkExpander, the label widget is allocated the minimum height for its allocated width and the remaining space is given to the child, test case included. --- gtk/gtkframe.c | 131 ++++++++++++++++++++++++++++++------- tests/testheightforwidth.c | 43 ++++++++++++ 2 files changed, 150 insertions(+), 24 deletions(-) diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c index 7f6c0e2098..76cf1fd958 100644 --- a/gtk/gtkframe.c +++ b/gtk/gtkframe.c @@ -47,6 +47,7 @@ struct _GtkFramePriv /* Properties */ GtkAllocation child_allocation; + GtkAllocation label_allocation; }; enum { @@ -99,6 +100,15 @@ static void gtk_frame_get_width (GtkSizeRequest *widget static void gtk_frame_get_height (GtkSizeRequest *widget, gint *minimum_size, gint *natural_size); +static void gtk_frame_get_height_for_width (GtkSizeRequest *layout, + gint width, + gint *minimum_height, + gint *natural_height); +static void gtk_frame_get_width_for_height (GtkSizeRequest *layout, + gint width, + gint *minimum_height, + gint *natural_height); + G_DEFINE_TYPE_WITH_CODE (GtkFrame, gtk_frame, GTK_TYPE_BIN, G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, @@ -597,24 +607,21 @@ gtk_frame_paint (GtkWidget *widget, if (priv->label_widget) { - GtkRequisition child_requisition; gfloat xalign; gint height_extra; gint x2; - gtk_widget_get_child_requisition (priv->label_widget, &child_requisition); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) xalign = priv->label_xalign; else xalign = 1 - priv->label_xalign; - height_extra = MAX (0, child_requisition.height - widget->style->ythickness) - - priv->label_yalign * child_requisition.height; + height_extra = MAX (0, priv->label_allocation.height - widget->style->ythickness) + - priv->label_yalign * priv->label_allocation.height; y -= height_extra; height += height_extra; - x2 = widget->style->xthickness + (priv->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD; + x2 = widget->style->xthickness + (priv->child_allocation.width - priv->label_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_SIDE_PAD; /* If the label is completely over or under the frame we can omit the gap */ if (priv->label_yalign == 0.0 || priv->label_yalign == 1.0) @@ -628,7 +635,7 @@ gtk_frame_paint (GtkWidget *widget, area, widget, "frame", x, y, width, height, GTK_POS_TOP, - x2, child_requisition.width + 2 * LABEL_PAD); + x2, priv->label_allocation.width + 2 * LABEL_PAD); } else gtk_paint_shadow (widget->style, widget->window, @@ -688,25 +695,32 @@ gtk_frame_size_allocate (GtkWidget *widget, if (priv->label_widget && gtk_widget_get_visible (priv->label_widget)) { - GtkRequisition child_requisition; - GtkAllocation child_allocation; + gint nat_width, width, height; gfloat xalign; - gtk_widget_get_child_requisition (priv->label_widget, &child_requisition); - if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) xalign = priv->label_xalign; else xalign = 1 - priv->label_xalign; - child_allocation.x = priv->child_allocation.x + LABEL_SIDE_PAD + - (priv->child_allocation.width - child_requisition.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_PAD; - child_allocation.width = MIN (child_requisition.width, new_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD); + gtk_size_request_get_width (GTK_SIZE_REQUEST (priv->label_widget), NULL, &nat_width); + width = new_allocation.width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD; + width = MIN (width, nat_width); - child_allocation.y = priv->child_allocation.y - MAX (child_requisition.height, widget->style->ythickness); - child_allocation.height = child_requisition.height; + gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (priv->label_widget), width, + &height, NULL); - gtk_widget_size_allocate (priv->label_widget, &child_allocation); + + priv->label_allocation.x = priv->child_allocation.x + LABEL_SIDE_PAD + + (new_allocation.width - width - 2 * LABEL_PAD - 2 * LABEL_SIDE_PAD) * xalign + LABEL_PAD; + + priv->label_allocation.width = width; + + + priv->label_allocation.y = priv->child_allocation.y - MAX (height, widget->style->ythickness); + priv->label_allocation.height = height; + + gtk_widget_size_allocate (priv->label_widget, &priv->label_allocation); } } @@ -727,19 +741,30 @@ gtk_frame_real_compute_child_allocation (GtkFrame *frame, GtkFramePriv *priv = frame->priv; GtkWidget *widget = GTK_WIDGET (frame); GtkAllocation *allocation = &widget->allocation; - GtkRequisition child_requisition; gint top_margin; guint border_width; + border_width = gtk_container_get_border_width (GTK_CONTAINER (frame)); + if (priv->label_widget) { - gtk_widget_get_child_requisition (priv->label_widget, &child_requisition); - top_margin = MAX (child_requisition.height, widget->style->ythickness); + gint nat_width, width, height; + + gtk_size_request_get_width (GTK_SIZE_REQUEST (priv->label_widget), NULL, &nat_width); + + width = widget->allocation.width; + width -= 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD; + width -= (border_width + GTK_WIDGET (widget)->style->xthickness) * 2; + + width = MIN (width, nat_width); + + gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (priv->label_widget), width, + &height, NULL); + + top_margin = MAX (height, widget->style->ythickness); } else top_margin = widget->style->ythickness; - - border_width = gtk_container_get_border_width (GTK_CONTAINER (frame)); child_allocation->x = border_width + widget->style->xthickness; child_allocation->width = MAX(1, (gint)allocation->width - child_allocation->x * 2); @@ -846,9 +871,67 @@ gtk_frame_get_height (GtkSizeRequest *widget, gtk_frame_get_size (widget, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } + +static void +gtk_frame_get_height_for_width (GtkSizeRequest *request, + gint width, + gint *minimum_height, + gint *natural_height) +{ + GtkWidget *widget = GTK_WIDGET (request); + GtkWidget *child; + GtkFrame *frame = GTK_FRAME (widget); + GtkFramePriv *priv = frame->priv; + GtkBin *bin = GTK_BIN (widget); + gint child_min, child_nat, label_width; + gint minimum, natural; + guint border_width; + + border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); + minimum = (border_width + GTK_WIDGET (widget)->style->ythickness) * 2; + natural = (border_width + GTK_WIDGET (widget)->style->ythickness) * 2; + + width -= (border_width + GTK_WIDGET (widget)->style->xthickness) * 2; + label_width = width - 2 * LABEL_PAD + 2 * LABEL_SIDE_PAD; + + if (priv->label_widget && gtk_widget_get_visible (priv->label_widget)) + { + gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (priv->label_widget), + label_width, &child_min, &child_nat); + minimum += child_min; + natural += child_nat; + } + + child = gtk_bin_get_child (bin); + if (child && gtk_widget_get_visible (child)) + { + gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (priv->label_widget), + width, &child_min, &child_nat); + minimum += child_min; + natural += child_nat; + } + + if (minimum_height) + *minimum_height = minimum; + + if (natural_height) + *natural_height = natural; +} + +static void +gtk_frame_get_width_for_height (GtkSizeRequest *widget, + gint height, + gint *minimum_width, + gint *natural_width) +{ + gtk_size_request_get_width (widget, minimum_width, natural_width); +} + static void gtk_frame_size_request_init (GtkSizeRequestIface *iface) { - iface->get_width = gtk_frame_get_width; - iface->get_height = gtk_frame_get_height; + iface->get_width = gtk_frame_get_width; + iface->get_height = gtk_frame_get_height; + iface->get_height_for_width = gtk_frame_get_height_for_width; + iface->get_width_for_height = gtk_frame_get_width_for_height; } diff --git a/tests/testheightforwidth.c b/tests/testheightforwidth.c index e59d3bb6f7..f784864b6b 100644 --- a/tests/testheightforwidth.c +++ b/tests/testheightforwidth.c @@ -615,6 +615,49 @@ TestInterface interfaces[] = { "", NULL }, + + { + "Wrapping Frame Label", + "This test demonstrates how the frame label can fill to its natural width " + "and also trade height for width.", + "" + "" + " " + " " + " " + " 400" + " 150" + " " + " " + " True" + " 8" + " 0" + " " + " " + " True" + " 12" + " " + " " + " True" + " some content" + " " + " " + " " + " " + " " + " " + " True" + " A frame label that's a little long and wraps" + " True" + " True" + " " + " " + " " + " " + " " + "", + NULL + }, }; From 651bed57a4da840149caca5738c0915f937b2bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadej=20Borov=C5=A1ak?= Date: Fri, 6 Aug 2010 22:07:42 +0200 Subject: [PATCH 2/9] Implement fair extra space allocation --- gtk/gtkbox.c | 657 ++++++++++++++++++++++++++------------------------- 1 file changed, 335 insertions(+), 322 deletions(-) diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c index 9e43e73ece..be089009d2 100644 --- a/gtk/gtkbox.c +++ b/gtk/gtkbox.c @@ -407,224 +407,230 @@ gtk_box_size_allocate (GtkWidget *widget, gint nvis_children; gint nexpand_children; + guint border_width; + GtkTextDirection direction; + GtkAllocation child_allocation; + GtkRequestedSize *sizes; + + GtkPackType packing; + + gint size; + gint extra; + gint n_extra_widgets = 0; /* Number of widgets that receive 1 extra px */ + gint x = 0, y = 0, i; + gint child_size; + + widget->allocation = *allocation; count_expand_children (box, &nvis_children, &nexpand_children); - if (nvis_children > 0) + /* If there is no visible child, simply return. */ + if (nvis_children <= 0) + return; + + border_width = gtk_container_get_border_width (GTK_CONTAINER (box)); + direction = gtk_widget_get_direction (widget); + sizes = g_newa (GtkRequestedSize, nvis_children); + + if (private->orientation == GTK_ORIENTATION_HORIZONTAL) + size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing; + else + size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing; + + /* Retrieve desired size for visible children. */ + for (i = 0, children = private->children; children; children = children->next) { - guint border_width = gtk_container_get_border_width (GTK_CONTAINER (box)); - GtkTextDirection direction = gtk_widget_get_direction (widget); - GtkAllocation child_allocation; - GtkRequestedSize *sizes = g_newa (GtkRequestedSize, nvis_children); + child = children->data; - GtkPackType packing; - - gint size; - gint extra; - gint x = 0, y = 0, i; - gint child_size; + if (!gtk_widget_get_visible (child->widget)) + continue; if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing; + gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget), + allocation->height, + &sizes[i].minimum_size, + &sizes[i].natural_size); else - size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing; + gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child->widget), + allocation->width, + &sizes[i].minimum_size, + &sizes[i].natural_size); - /* Retrieve desired size for visible children */ - i = 0; - children = private->children; - while (children) + + /* Assert the api is working properly */ + if (sizes[i].minimum_size < 0) + g_error ("GtkBox child %s minimum %s: %d < 0 for %s %d", + gtk_widget_get_name (GTK_WIDGET (child->widget)), + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", + sizes[i].minimum_size, + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width", + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width); + + if (sizes[i].natural_size < sizes[i].minimum_size) + g_error ("GtkBox child %s natural %s: %d < minimum %d for %s %d", + gtk_widget_get_name (GTK_WIDGET (child->widget)), + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", + sizes[i].natural_size, + sizes[i].minimum_size, + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width", + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width); + + size -= sizes[i].minimum_size; + size -= child->padding * 2; + + sizes[i].data = child; + + i++; + } + + if (private->homogeneous) + { + /* If were homogenous we still need to run the above loop to get the + * minimum sizes for children that are not going to fill + */ + if (private->orientation == GTK_ORIENTATION_HORIZONTAL) + size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing; + else + size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing; + + extra = size / nvis_children; + n_extra_widgets = size % nvis_children; + } + else + { + /* Bring children up to size first */ + size = gtk_distribute_natural_allocation (size, nvis_children, sizes); + + /* Calculate space which hasn't distributed yet, + * and is available for expanding children. + */ + if (nexpand_children > 0) { - child = children->data; - children = children->next; + extra = size / nexpand_children; + n_extra_widgets = size % nexpand_children; + } + else + extra = 0; + } - if (gtk_widget_get_visible (child->widget)) - { - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget), - allocation->height, - &sizes[i].minimum_size, - &sizes[i].natural_size); - else - gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child->widget), - allocation->width, - &sizes[i].minimum_size, - &sizes[i].natural_size); - - - /* Assert the api is working properly */ - if (sizes[i].minimum_size < 0) - g_error ("GtkBox child %s minimum %s: %d < 0 for %s %d", - gtk_widget_get_name (GTK_WIDGET (child->widget)), - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", - sizes[i].minimum_size, - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width", - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width); - - if (sizes[i].natural_size < sizes[i].minimum_size) - g_error ("GtkBox child %s natural %s: %d < minimum %d for %s %d", - gtk_widget_get_name (GTK_WIDGET (child->widget)), - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", - sizes[i].natural_size, - sizes[i].minimum_size, - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width", - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width); - - size -= sizes[i].minimum_size; - size -= child->padding * 2; - - sizes[i].data = child; - - i += 1; - } + /* Allocate child positions. */ + for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing) + { + if (private->orientation == GTK_ORIENTATION_HORIZONTAL) + { + child_allocation.y = allocation->y + border_width; + child_allocation.height = MAX (1, allocation->height - border_width * 2); + if (packing == GTK_PACK_START) + x = allocation->x + border_width; + else + x = allocation->x + allocation->width - border_width; + } + else + { + child_allocation.x = allocation->x + border_width; + child_allocation.width = MAX (1, allocation->width - border_width * 2); + if (packing == GTK_PACK_START) + y = allocation->y + border_width; + else + y = allocation->y + allocation->height - border_width; } - if (private->homogeneous) + for (i = 0, children = private->children; + children; + children = children->next) { - /* If were homogenous we still need to run the above loop to get the minimum sizes - * for children that are not going to fill + child = children->data; + + /* If widget is not visible or it's packing is not right for current + * loop, skip it. */ - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - size = allocation->width - border_width * 2 - (nvis_children - 1) * private->spacing; - else - size = allocation->height - border_width * 2 - (nvis_children - 1) * private->spacing; - - extra = size / nvis_children; - } - else - { - /* Bring children up to size first */ - size = gtk_distribute_natural_allocation (size, nvis_children, sizes); + if (child->pack != packing || !gtk_widget_get_visible (child->widget)) + continue; - /* Calculate space which hasn't distributed yet, - * and is available for expanding children. - */ - if (nexpand_children > 0) - extra = size / nexpand_children; - else - extra = 0; - } - - /* Allocate child positions. */ - - for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing) - { - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - { - child_allocation.y = allocation->y + border_width; - child_allocation.height = MAX (1, allocation->height - border_width * 2); - if (packing == GTK_PACK_START) - x = allocation->x + border_width; - else - x = allocation->x + allocation->width - border_width; - } - else - { - child_allocation.x = allocation->x + border_width; - child_allocation.width = MAX (1, allocation->width - border_width * 2); - if (packing == GTK_PACK_START) - y = allocation->y + border_width; - else - y = allocation->y + allocation->height - border_width; - } - - i = 0; - children = private->children; - while (children) + /* Assign the child's size. */ + if (private->homogeneous) { - child = children->data; - children = children->next; + child_size = extra; - if (gtk_widget_get_visible (child->widget)) - { - if (child->pack == packing) - { - /* Assign the child's size. */ - if (private->homogeneous) - { - if (nvis_children == 1) - child_size = size; - else - child_size = extra; - - nvis_children -= 1; - size -= extra; - } - else - { - child_size = sizes[i].minimum_size + child->padding * 2; - - if (child->expand) - { - if (nexpand_children == 1) - child_size += size; - else - child_size += extra; - - nexpand_children -= 1; - size -= extra; - } - } - - /* Assign the child's position. */ - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - { - if (child->fill) - { - child_allocation.width = MAX (1, child_size - child->padding * 2); - child_allocation.x = x + child->padding; - } - else - { - child_allocation.width = sizes[i].minimum_size; - child_allocation.x = x + (child_size - child_allocation.width) / 2; - } - - if (packing == GTK_PACK_START) - { - x += child_size + private->spacing; - } - else - { - x -= child_size + private->spacing; - - child_allocation.x -= child_size; - } - - if (direction == GTK_TEXT_DIR_RTL) - child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width; - - } - else /* (private->orientation == GTK_ORIENTATION_VERTICAL) */ - { - if (child->fill) - { - child_allocation.height = MAX (1, child_size - child->padding * 2); - child_allocation.y = y + child->padding; - } - else - { - child_allocation.height = sizes[i].minimum_size; - child_allocation.y = y + (child_size - child_allocation.height) / 2; - } - - if (packing == GTK_PACK_START) - { - y += child_size + private->spacing; - } - else - { - y -= child_size + private->spacing; - - child_allocation.y -= child_size; - } - } - gtk_widget_size_allocate (child->widget, &child_allocation); - } - - i += 1; - } + if (n_extra_widgets > 0) + { + child_size++; + n_extra_widgets--; + } } + else + { + child_size = sizes[i].minimum_size + child->padding * 2; + + if (child->expand) + { + child_size += extra; + + if (n_extra_widgets > 0) + { + child_size++; + n_extra_widgets--; + } + } + } + + /* Assign the child's position. */ + if (private->orientation == GTK_ORIENTATION_HORIZONTAL) + { + if (child->fill) + { + child_allocation.width = MAX (1, child_size - child->padding * 2); + child_allocation.x = x + child->padding; + } + else + { + child_allocation.width = sizes[i].minimum_size; + child_allocation.x = x + (child_size - child_allocation.width) / 2; + } + + if (packing == GTK_PACK_START) + { + x += child_size + private->spacing; + } + else + { + x -= child_size + private->spacing; + + child_allocation.x -= child_size; + } + + if (direction == GTK_TEXT_DIR_RTL) + child_allocation.x = allocation->x + allocation->width - (child_allocation.x - allocation->x) - child_allocation.width; + + } + else /* (private->orientation == GTK_ORIENTATION_VERTICAL) */ + { + if (child->fill) + { + child_allocation.height = MAX (1, child_size - child->padding * 2); + child_allocation.y = y + child->padding; + } + else + { + child_allocation.height = sizes[i].minimum_size; + child_allocation.y = y + (child_size - child_allocation.height) / 2; + } + + if (packing == GTK_PACK_START) + { + y += child_size + private->spacing; + } + else + { + y -= child_size + private->spacing; + + child_allocation.y -= child_size; + } + } + gtk_widget_size_allocate (child->widget, &child_allocation); + + i++; } } } @@ -919,149 +925,156 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box, gint *minimum_size, gint *natural_size) { - GtkBoxPriv *private = box->priv; - GtkBoxChild *child; - GList *children; - gint nvis_children; - gint nexpand_children; - gint computed_minimum = 0, computed_natural = 0; - guint border_width = gtk_container_get_border_width (GTK_CONTAINER (box)); + GtkBoxPriv *private = box->priv; + GtkBoxChild *child; + GList *children; + gint nvis_children; + gint nexpand_children; + gint computed_minimum = 0, computed_natural = 0; + guint border_width = gtk_container_get_border_width (GTK_CONTAINER (box)); + GtkRequestedSize *sizes; + GtkPackType packing; + gint size, extra, i; + gint child_size, child_minimum, child_natural; + gint n_extra_widgets = 0; count_expand_children (box, &nvis_children, &nexpand_children); - if (nvis_children > 0) + if (nvis_children <= 0) + return; + + sizes = g_newa (GtkRequestedSize, nvis_children); + size = avail_size - border_width * 2 - (nvis_children - 1) * private->spacing; + + /* Retrieve desired size for visible children */ + for (i = 0, children = private->children; children; children = children->next) { - GtkRequestedSize *sizes = g_newa (GtkRequestedSize, nvis_children); - GtkPackType packing; - gint size, extra, i; - gint child_size, child_minimum, child_natural; + child = children->data; + + if (gtk_widget_get_visible (child->widget)) + { + if (private->orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget), + &sizes[i].minimum_size, + &sizes[i].natural_size); + else + gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget), + &sizes[i].minimum_size, + &sizes[i].natural_size); + /* Assert the api is working properly */ + if (sizes[i].minimum_size < 0) + g_error ("GtkBox child %s minimum %s: %d < 0", + gtk_widget_get_name (GTK_WIDGET (child->widget)), + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", + sizes[i].minimum_size); + + if (sizes[i].natural_size < sizes[i].minimum_size) + g_error ("GtkBox child %s natural %s: %d < minimum %d", + gtk_widget_get_name (GTK_WIDGET (child->widget)), + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", + sizes[i].natural_size, + sizes[i].minimum_size); + + size -= sizes[i].minimum_size; + size -= child->padding * 2; + + sizes[i].data = child; + + i += 1; + } + } + + if (private->homogeneous) + { + /* If were homogenous we still need to run the above loop to get the + * minimum sizes for children that are not going to fill + */ size = avail_size - border_width * 2 - (nvis_children - 1) * private->spacing; + extra = size / nvis_children; + n_extra_widgets = size % nvis_children; + } + else + { + /* Bring children up to size first */ + size = gtk_distribute_natural_allocation (size, nvis_children, sizes); - /* Retrieve desired size for visible children */ - for (i = 0, children = private->children; children; children = children->next) + /* Calculate space which hasn't distributed yet, + * and is available for expanding children. + */ + if (nexpand_children > 0) + { + extra = size / nexpand_children; + n_extra_widgets = size % nexpand_children; + } + else + extra = 0; + } + + /* Allocate child positions. */ + for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing) + { + for (i = 0, children = private->children; + children; + children = children->next) { child = children->data; - - if (gtk_widget_get_visible (child->widget)) + + if (child->pack != packing || !gtk_widget_get_visible (child->widget)) + continue; + + if (child->pack == packing) { - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - gtk_size_request_get_width (GTK_SIZE_REQUEST (child->widget), - &sizes[i].minimum_size, - &sizes[i].natural_size); + /* Assign the child's size. */ + if (private->homogeneous) + { + child_size = extra; + + if (n_extra_widgets > 0) + { + child_size++; + n_extra_widgets--; + } + } else - gtk_size_request_get_height (GTK_SIZE_REQUEST (child->widget), - &sizes[i].minimum_size, - &sizes[i].natural_size); - - /* Assert the api is working properly */ - if (sizes[i].minimum_size < 0) - g_error ("GtkBox child %s minimum %s: %d < 0", - gtk_widget_get_name (GTK_WIDGET (child->widget)), - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", - sizes[i].minimum_size); + { + child_size = sizes[i].minimum_size + child->padding * 2; - if (sizes[i].natural_size < sizes[i].minimum_size) - g_error ("GtkBox child %s natural %s: %d < minimum %d", - gtk_widget_get_name (GTK_WIDGET (child->widget)), - (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", - sizes[i].natural_size, - sizes[i].minimum_size); + if (child->expand) + { + child_size += extra; - size -= sizes[i].minimum_size; - size -= child->padding * 2; - - sizes[i].data = child; - - i += 1; - } - } - - if (private->homogeneous) - { - /* If were homogenous we still need to run the above loop to get the minimum sizes - * for children that are not going to fill - */ - size = avail_size - border_width * 2 - (nvis_children - 1) * private->spacing; - extra = size / nvis_children; - } - else - { - /* Bring children up to size first */ - size = gtk_distribute_natural_allocation (size, nvis_children, sizes); - - /* Calculate space which hasn't distributed yet, - * and is available for expanding children. - */ - if (nexpand_children > 0) - extra = size / nexpand_children; - else - extra = 0; - } - - /* Allocate child positions. */ - for (packing = GTK_PACK_START; packing <= GTK_PACK_END; ++packing) - { - for (i = 0, children = private->children; children; children = children->next) - { - child = children->data; - - if (gtk_widget_get_visible (child->widget)) - { - if (child->pack == packing) - { - /* Assign the child's size. */ - if (private->homogeneous) - { - if (nvis_children == 1) - child_size = size; - else - child_size = extra; - - nvis_children -= 1; - size -= extra; - } - else - { - child_size = sizes[i].minimum_size + child->padding * 2; - - if (child->expand) - { - if (nexpand_children == 1) - child_size += size; - else - child_size += extra; - - nexpand_children -= 1; - size -= extra; - } - } - - if (child->fill) + if (n_extra_widgets > 0) { - child_size = MAX (1, child_size - child->padding * 2); - } - else - { - child_size = sizes[i].minimum_size; + child_size++; + n_extra_widgets--; } + } + } + + if (child->fill) + { + child_size = MAX (1, child_size - child->padding * 2); + } + else + { + child_size = sizes[i].minimum_size; + } - /* Assign the child's position. */ - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child->widget), - child_size, &child_minimum, &child_natural); - else /* (private->orientation == GTK_ORIENTATION_VERTICAL) */ - gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget), - child_size, &child_minimum, &child_natural); + /* Assign the child's position. */ + if (private->orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child->widget), + child_size, &child_minimum, &child_natural); + else /* (private->orientation == GTK_ORIENTATION_VERTICAL) */ + gtk_size_request_get_width_for_height (GTK_SIZE_REQUEST (child->widget), + child_size, &child_minimum, &child_natural); - - computed_minimum = MAX (computed_minimum, child_minimum); - computed_natural = MAX (computed_natural, child_natural); - } - i += 1; - } + + computed_minimum = MAX (computed_minimum, child_minimum); + computed_natural = MAX (computed_natural, child_natural); } + i += 1; } } From 03dfaf3c3e53b892eeff9e72639aca3eab28f437 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Fri, 6 Aug 2010 18:57:41 -0400 Subject: [PATCH 3/9] Fixed bad typo causing bad vertical requests on frames with no label. --- gtk/gtkframe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c index 76cf1fd958..32b191b35d 100644 --- a/gtk/gtkframe.c +++ b/gtk/gtkframe.c @@ -905,7 +905,7 @@ gtk_frame_get_height_for_width (GtkSizeRequest *request, child = gtk_bin_get_child (bin); if (child && gtk_widget_get_visible (child)) { - gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (priv->label_widget), + gtk_size_request_get_height_for_width (GTK_SIZE_REQUEST (child), width, &child_min, &child_nat); minimum += child_min; natural += child_nat; From 35105ab2b44c50a96698cc55a77a68c2e816f56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadej=20Borov=C5=A1ak?= Date: Sat, 7 Aug 2010 01:58:29 +0200 Subject: [PATCH 4/9] Fix improperly unwinded loops --- gtk/gtkbox.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c index be089009d2..cdc5f1d46f 100644 --- a/gtk/gtkbox.c +++ b/gtk/gtkbox.c @@ -542,12 +542,19 @@ gtk_box_size_allocate (GtkWidget *widget, { child = children->data; - /* If widget is not visible or it's packing is not right for current - * loop, skip it. - */ - if (child->pack != packing || !gtk_widget_get_visible (child->widget)) + /* If widget is not visible, skip it. */ + if (!gtk_widget_get_visible (child->widget)) continue; + /* If widget is packed differently skip it, but still increment i, + * since widget is visible and will be handled in next loop iteration. + */ + if (child->pack != packing) + { + i++; + continue; + } + /* Assign the child's size. */ if (private->homogeneous) { @@ -1020,9 +1027,19 @@ gtk_box_compute_size_for_opposing_orientation (GtkBox *box, { child = children->data; - if (child->pack != packing || !gtk_widget_get_visible (child->widget)) + /* If widget is not visible, skip it. */ + if (!gtk_widget_get_visible (child->widget)) continue; + /* If widget is packed differently skip it, but still increment i, + * since widget is visible and will be handled in next loop iteration. + */ + if (child->pack != packing) + { + i++; + continue; + } + if (child->pack == packing) { /* Assign the child's size. */ From 32d365f4768137f3f7e36aa4e24014f12a001964 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 7 Aug 2010 01:06:29 +0200 Subject: [PATCH 5/9] label: Make angle part of GtkLabelPrivate --- gtk/gtklabel.c | 55 ++++++++++++-------------------------------------- 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index 07a1f4e357..d712cc6595 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -84,6 +84,8 @@ struct _GtkLabelPriv gint wrap_width; gint width_chars; gint max_width_chars; + + gdouble angle; }; /* Notes about the handling of links: @@ -345,8 +347,6 @@ static void gtk_label_get_height_for_width (GtkSizeRequest * gint *minimum_height, gint *natural_height); -static GQuark quark_angle = 0; - static GtkBuildableIface *buildable_parent_iface = NULL; G_DEFINE_TYPE_WITH_CODE (GtkLabel, gtk_label, GTK_TYPE_MISC, @@ -386,8 +386,6 @@ gtk_label_class_init (GtkLabelClass *class) GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); GtkBindingSet *binding_set; - quark_angle = g_quark_from_static_string ("angle"); - gobject_class->set_property = gtk_label_set_property; gobject_class->get_property = gtk_label_get_property; gobject_class->finalize = gtk_label_finalize; @@ -3419,7 +3417,6 @@ gtk_label_get_size (GtkSizeRequest *widget, GtkLabelPriv *priv = label->priv; PangoRectangle required_rect; PangoRectangle natural_rect; - gdouble angle; gint xpad, ypad; /* "width-chars" Hard-coded minimum width: @@ -3438,8 +3435,6 @@ gtk_label_get_size (GtkSizeRequest *widget, gtk_label_clear_layout (label); gtk_label_ensure_layout (label, TRUE); - angle = gtk_label_get_angle (label); - /* Start off with the pixel extents of the rendered layout */ pango_layout_get_extents (priv->layout, NULL, &required_rect); required_rect.x = required_rect.y = 0; @@ -3473,7 +3468,8 @@ gtk_label_get_size (GtkSizeRequest *widget, * layout to not ellipsize when we know we have been allocated our * full natural size, or it may be that pango needs a fix here). */ - if (priv->ellipsize && angle != 0 && angle != 90 && angle != 180 && angle != 270 && angle != 360) + if (priv->ellipsize && priv->angle != 0 && priv->angle != 90 && + priv->angle != 180 && priv->angle != 270 && priv->angle != 360) { /* For some reason we only need this at about 110 degrees, and only * when gaining in height @@ -3497,7 +3493,7 @@ gtk_label_get_size (GtkSizeRequest *widget, * ellipsized labels. */ if (!(priv->ellipsize && priv->have_transform) && - (angle == 90 || angle == 270)) + (priv->angle == 90 || priv->angle == 270)) { /* Doing a h4w request on a rotated label here, return the * required width for the minimum height. @@ -3524,7 +3520,7 @@ gtk_label_get_size (GtkSizeRequest *widget, * ellipsized labels. */ if (!(priv->ellipsize && priv->have_transform) && - (angle == 0 || angle == 180)) + (priv->angle == 0 || priv->angle == 180 || priv->angle == 360)) { /* Doing a w4h request on a label here, return the required * height for the minimum width. @@ -3583,9 +3579,8 @@ gtk_label_get_width_for_height (GtkSizeRequest *widget, { GtkLabel *label = GTK_LABEL (widget); GtkLabelPriv *priv = label->priv; - gdouble angle = gtk_label_get_angle (label); - if (priv->wrap && (angle == 90 || angle == 270)) + if (priv->wrap && (priv->angle == 90 || priv->angle == 270)) { gint xpad, ypad; @@ -3616,9 +3611,8 @@ gtk_label_get_height_for_width (GtkSizeRequest *widget, { GtkLabel *label = GTK_LABEL (widget); GtkLabelPriv *priv = label->priv; - gdouble angle = gtk_label_get_angle (label); - if (priv->wrap && (angle == 0 || angle == 180 || angle == 360)) + if (priv->wrap && (priv->angle == 0 || priv->angle == 180 || priv->angle == 360)) { gint xpad, ypad; @@ -3836,12 +3830,10 @@ get_layout_location (GtkLabel *label, gint xpad, ypad; gfloat xalign, yalign; PangoRectangle logical; - gdouble angle; misc = GTK_MISC (label); widget = GTK_WIDGET (label); priv = label->priv; - angle = gtk_label_get_angle (label); gtk_misc_get_alignment (misc, &xalign, &yalign); gtk_misc_get_padding (misc, &xpad, &ypad); @@ -5204,12 +5196,6 @@ gtk_label_get_selectable (GtkLabel *label) return priv->select_info && priv->select_info->selectable; } -static void -free_angle (gpointer angle) -{ - g_slice_free (gdouble, angle); -} - /** * gtk_label_set_angle: * @label: a #GtkLabel @@ -5227,20 +5213,12 @@ void gtk_label_set_angle (GtkLabel *label, gdouble angle) { - gdouble *label_angle; + GtkLabelPriv *priv; g_return_if_fail (GTK_IS_LABEL (label)); - label_angle = (gdouble *)g_object_get_qdata (G_OBJECT (label), quark_angle); + priv = label->priv; - if (!label_angle) - { - label_angle = g_slice_new (gdouble); - *label_angle = 0.0; - g_object_set_qdata_full (G_OBJECT (label), quark_angle, - label_angle, free_angle); - } - /* Canonicalize to [0,360]. We don't canonicalize 360 to 0, because * double property ranges are inclusive, and changing 360 to 0 would * make a property editor behave strangely. @@ -5248,9 +5226,9 @@ gtk_label_set_angle (GtkLabel *label, if (angle < 0 || angle > 360.0) angle = angle - 360. * floor (angle / 360.); - if (*label_angle != angle) + if (priv->angle != angle) { - *label_angle = angle; + priv->angle = angle; gtk_label_clear_layout (label); gtk_widget_queue_resize (GTK_WIDGET (label)); @@ -5273,16 +5251,9 @@ gtk_label_set_angle (GtkLabel *label, gdouble gtk_label_get_angle (GtkLabel *label) { - gdouble *angle; - g_return_val_if_fail (GTK_IS_LABEL (label), 0.0); - angle = (gdouble *)g_object_get_qdata (G_OBJECT (label), quark_angle); - - if (angle) - return *angle; - else - return 0.0; + return label->priv->angle; } static void From 59e7571aae6f61984cc0e5737e482feb33ef9f20 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Fri, 6 Aug 2010 22:44:11 -0400 Subject: [PATCH 6/9] Fixed alignment of wrapping labels allocated a greater width than needed When wrapping labels to allocation width, never set the label wrap width to a size greater than needed for the label's text (closes bug 625715) --- gtk/gtklabel.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index d712cc6595..2f4c91ee13 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -3250,7 +3250,8 @@ gtk_label_ensure_layout (GtkLabel *label, gboolean guess_wrap_width) else if (guess_wrap_width == FALSE && widget->allocation.width > 1 && widget->allocation.height > 1) { - gint xpad, ypad; + PangoRectangle rect; + gint xpad, ypad, natural_width; gtk_misc_get_padding (GTK_MISC (label), &xpad, &ypad); if (angle == 90 || angle == 270) @@ -3258,6 +3259,12 @@ gtk_label_ensure_layout (GtkLabel *label, gboolean guess_wrap_width) else width = widget->allocation.width - xpad * 2; + /* dont set a wrap width wider than the label's natural width + * incase we're allocated more space than needed */ + pango_layout_get_extents (priv->layout, NULL, &rect); + natural_width = PANGO_PIXELS (rect.width); + width = MIN (natural_width, width); + pango_layout_set_wrap (priv->layout, priv->wrap_mode); pango_layout_set_width (priv->layout, MAX (width, 1) * PANGO_SCALE); } @@ -3843,18 +3850,6 @@ get_layout_location (GtkLabel *label, pango_layout_get_extents (priv->layout, NULL, &logical); - /* Do the wrap width delimiting before the transform - */ - if (priv->wrap || priv->ellipsize || priv->width_chars > 0) - { - int width; - - width = pango_layout_get_width (priv->layout); - - if (width != -1) - logical.width = MIN (width, logical.width); - } - if (priv->have_transform) { PangoContext *context = gtk_widget_get_pango_context (widget); @@ -3879,8 +3874,6 @@ get_layout_location (GtkLabel *label, x = MIN (x, widget->allocation.x + widget->allocation.width - xpad); - - /* bgo#315462 - For single-line labels, *do* align the requisition with * respect to the allocation, even if we are under-allocated. For multi-line * labels, always show the top of the text when they are under-allocated. The From 4198dd8519c3bce56f51b071e9ee0477fe6c3a26 Mon Sep 17 00:00:00 2001 From: John Stowers Date: Wed, 14 Jul 2010 20:48:54 +1200 Subject: [PATCH 7/9] Add gdk_display_is_closed https://bugzilla.gnome.org/show_bug.cgi?id=624224 --- docs/reference/gdk/gdk3-sections.txt | 1 + gdk/gdk.symbols | 1 + gdk/gdkdisplay.c | 16 ++++++++++++++++ gdk/gdkdisplay.h | 3 ++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt index f611c016f1..49114797bd 100644 --- a/docs/reference/gdk/gdk3-sections.txt +++ b/docs/reference/gdk/gdk3-sections.txt @@ -129,6 +129,7 @@ gdk_display_beep gdk_display_sync gdk_display_flush gdk_display_close +gdk_display_is_closed gdk_display_list_devices gdk_display_get_event gdk_display_peek_event diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols index 3e02b91919..a97f0672fa 100644 --- a/gdk/gdk.symbols +++ b/gdk/gdk.symbols @@ -415,6 +415,7 @@ gdk_input_set_extension_events #if IN_HEADER(__GDK_DISPLAY_H__) #if IN_FILE(__GDK_DISPLAY_C__) gdk_display_close +gdk_display_is_closed gdk_display_get_event gdk_display_get_device_manager gdk_display_get_device_state diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 437ea9e1b3..e81c5f730a 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -338,6 +338,22 @@ gdk_display_close (GdkDisplay *display) } } +/** + * gdk_display_is_closed: + * @display: a #GdkDisplay + * + * Returns %TRUE if the display is closed. + * + * Since: 2.22 + */ +gboolean +gdk_display_is_closed (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + return display->closed; +} + /** * gdk_display_get_event: * @display: a #GdkDisplay diff --git a/gdk/gdkdisplay.h b/gdk/gdkdisplay.h index 55fcf3825d..1b11b696c7 100644 --- a/gdk/gdkdisplay.h +++ b/gdk/gdkdisplay.h @@ -211,7 +211,8 @@ void gdk_display_beep (GdkDisplay *display); void gdk_display_sync (GdkDisplay *display); void gdk_display_flush (GdkDisplay *display); -void gdk_display_close (GdkDisplay *display); +void gdk_display_close (GdkDisplay *display); +gboolean gdk_display_is_closed (GdkDisplay *display); #ifndef GDK_DISABLE_DEPRECATED GList * gdk_display_list_devices (GdkDisplay *display); From 3ccc617052cbd85a066aba2d17c6983551f6d499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jard=C3=B3n?= Date: Sat, 7 Aug 2010 17:07:17 +0200 Subject: [PATCH 8/9] Completely remove any use of GtkWindow allow-grow and allow-shrink properties These have been deprecated and removed from master. GtkWindow:resizable should be used instead. This completes commit 1a03a65e36b6288f7854da30bf89b86ad3592726 Reported by Benjamin Otte --- demos/testpixbuf.c | 1 - docs/sizing-test.txt | 3 +-- docs/tutorial/gtk-tut.sgml | 1 - gtk/gtk.symbols | 1 + gtk/gtkwindow-decorate.c | 4 ++-- gtk/gtkwindow.c | 4 ---- tests/simple.c | 3 +-- tests/testgtk.c | 36 ++++++++---------------------------- tests/testmultiscreen.c | 3 +-- tests/testrgb.c | 1 - 10 files changed, 14 insertions(+), 43 deletions(-) diff --git a/demos/testpixbuf.c b/demos/testpixbuf.c index 2c4ee01d44..296a87e307 100644 --- a/demos/testpixbuf.c +++ b/demos/testpixbuf.c @@ -390,7 +390,6 @@ new_testrgb_window (GdkPixbuf *pixbuf, gchar *title) "GtkObject::user_data", NULL, "GtkWindow::type", GTK_WINDOW_TOPLEVEL, "GtkWindow::title", title ? title : "testrgb", - "GtkWindow::allow_shrink", TRUE, NULL); g_signal_connect (window, "destroy", G_CALLBACK (quit_func), NULL); diff --git a/docs/sizing-test.txt b/docs/sizing-test.txt index 6954612d44..86183a2e83 100644 --- a/docs/sizing-test.txt +++ b/docs/sizing-test.txt @@ -106,8 +106,7 @@ GtkWindow::default_width, GtkWindow::default_height: - default_height is -1 if unset, or >= 0 if a default height is set -GtkWindow::allow_grow, GtkWindow::resizable: - - equivalent properties; changing one notifies on the other +GtkWindow::resizable: - if FALSE, we set the min size to the max size in the geometry hints. - If the app programmer has called gtk_window_set_geometry_hints() diff --git a/docs/tutorial/gtk-tut.sgml b/docs/tutorial/gtk-tut.sgml index 24861b4feb..734fe2e024 100755 --- a/docs/tutorial/gtk-tut.sgml +++ b/docs/tutorial/gtk-tut.sgml @@ -7599,7 +7599,6 @@ int main (int argc, char *argv[]) dialog = gtk_dialog_new (); gtk_window_set_title (GTK_WINDOW (dialog), "GTKToolbar Tutorial"); gtk_widget_set_size_request (GTK_WIDGET (dialog), 600, 300); - GTK_WINDOW (dialog)->allow_shrink = TRUE; /* typically we quit if someone tries to close us */ g_signal_connect (dialog, "delete-event", diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 94f9e61c7b..5378217900 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -1968,6 +1968,7 @@ gtk_false G_GNUC_CONST gtk_true G_GNUC_CONST gtk_events_pending gtk_disable_setlocale +gtk_distribute_natural_allocation gtk_set_locale gtk_check_version gtk_get_default_language diff --git a/gtk/gtkwindow-decorate.c b/gtk/gtkwindow-decorate.c index e2913605e0..010b76ee29 100644 --- a/gtk/gtkwindow-decorate.c +++ b/gtk/gtkwindow-decorate.c @@ -717,7 +717,7 @@ gtk_decorated_window_recalculate_regions (GtkWindow *window) n_regions += 2; /* close, Title */ if (deco->maximizable) n_regions += 1; - if (window->allow_shrink || window->allow_grow) + if (gtk_window_get_resizable (window)) n_regions += 2; if (deco->n_regions != n_regions) @@ -759,7 +759,7 @@ gtk_decorated_window_recalculate_regions (GtkWindow *window) region->type = GTK_WINDOW_REGION_TITLE; region++; - if (window->allow_shrink || window->allow_grow) + if (gtk_window_get_resizable (window)) { region->rect.x = width - (DECORATION_BORDER_RIGHT + 10); region->rect.y = height - DECORATION_BORDER_BOTTOM; diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 02adf0a508..f2230c9753 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -7331,10 +7331,6 @@ gtk_window_get_resizable (GtkWindow *window) { g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); - /* allow_grow is most likely to indicate the semantic concept we - * mean by "resizable" (and will be a reliable indicator if - * set_policy() hasn't been called) - */ return window->resizable; } diff --git a/tests/simple.c b/tests/simple.c index 19a19aa944..9a017d269c 100644 --- a/tests/simple.c +++ b/tests/simple.c @@ -41,8 +41,7 @@ main (int argc, char *argv[]) "user_data", NULL, "type", GTK_WINDOW_TOPLEVEL, "title", "hello world", - "allow_grow", FALSE, - "allow_shrink", FALSE, + "resizable", FALSE, "border_width", 10, NULL), "signal::destroy", gtk_main_quit, NULL, diff --git a/tests/testgtk.c b/tests/testgtk.c index 977164dde1..b727ecaea1 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -3375,8 +3375,7 @@ create_tooltips (GtkWidget *widget) "GtkWindow::type", GTK_WINDOW_TOPLEVEL, "GtkContainer::border_width", 0, "GtkWindow::title", "Tooltips", - "GtkWindow::allow_shrink", TRUE, - "GtkWindow::allow_grow", FALSE, + "GtkWindow::resizable", FALSE, NULL); gtk_window_set_screen (GTK_WINDOW (window), @@ -3495,8 +3494,8 @@ create_image (GtkWidget *widget) /* this is bogus for testing drawing when allocation < request, * don't copy into real code */ - g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL); - + gtk_window_set_resizable (GTK_WINDOW (window), TRUE); + g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window); @@ -6573,7 +6572,7 @@ create_rulers (GtkWidget *widget) gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (widget)); - g_object_set (window, "allow_shrink", TRUE, "allow_grow", TRUE, NULL); + gtk_window_set_resizable (GTK_WINDOW (window), TRUE); g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), @@ -8331,22 +8330,11 @@ set_geometry_callback (GtkWidget *entry, } static void -allow_shrink_callback (GtkWidget *widget, - gpointer data) -{ - g_object_set (g_object_get_data (data, "target"), - "allow_shrink", - GTK_TOGGLE_BUTTON (widget)->active, - NULL); -} - -static void -allow_grow_callback (GtkWidget *widget, +resizable_callback (GtkWidget *widget, gpointer data) { g_object_set (g_object_get_data (data, "target"), - "allow_grow", - GTK_TOGGLE_BUTTON (widget)->active, + "resizable", GTK_TOGGLE_BUTTON (widget)->active, NULL); } @@ -8719,20 +8707,12 @@ window_controls (GtkWidget *window) G_CALLBACK (move_to_position_callback), control_window); gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); - - button = gtk_check_button_new_with_label ("Allow shrink"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE); - g_signal_connect (button, - "toggled", - G_CALLBACK (allow_shrink_callback), - control_window); - gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); - button = gtk_check_button_new_with_label ("Allow grow"); + button = gtk_check_button_new_with_label ("Allow resize"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); g_signal_connect (button, "toggled", - G_CALLBACK (allow_grow_callback), + G_CALLBACK (resizable_callback), control_window); gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0); diff --git a/tests/testmultiscreen.c b/tests/testmultiscreen.c index ebf1438b53..e47c60fb54 100644 --- a/tests/testmultiscreen.c +++ b/tests/testmultiscreen.c @@ -116,8 +116,7 @@ main (int argc, char *argv[]) "user_data", NULL, "type", GTK_WINDOW_TOPLEVEL, "title", label, - "allow_grow", FALSE, - "allow_shrink", FALSE, + "resizable", FALSE, "border_width", 10, NULL, NULL); g_signal_connect (window[i], "destroy", diff --git a/tests/testrgb.c b/tests/testrgb.c index b05018359d..ebea6c73e0 100644 --- a/tests/testrgb.c +++ b/tests/testrgb.c @@ -286,7 +286,6 @@ new_testrgb_window (void) "GtkObject::user_data", NULL, "GtkWindow::type", GTK_WINDOW_TOPLEVEL, "GtkWindow::title", "testrgb", - "GtkWindow::allow_shrink", FALSE, NULL); g_signal_connect (window, "destroy", G_CALLBACK (quit_func), NULL); From 9ddef2365fe6785b2ed37dc20707fd86e194db25 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Sat, 7 Aug 2010 17:41:29 -0400 Subject: [PATCH 9/9] Fixed expressions in gtk_button_size_allocate() Children were getting negative allocations by misusage of MAX() macro (bad signedness of expressions). --- gtk/gtkbutton.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index 9b2f475571..e9527c189a 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -1476,31 +1476,34 @@ gtk_button_size_allocate (GtkWidget *widget, child_allocation.x = widget->allocation.x + border_width + inner_border.left + xthickness; child_allocation.y = widget->allocation.y + border_width + inner_border.top + ythickness; - child_allocation.width = MAX (1, widget->allocation.width - - xthickness * 2 - - inner_border.left - - inner_border.right - - border_width * 2); - child_allocation.height = MAX (1, widget->allocation.height - - ythickness * 2 - - inner_border.top - - inner_border.bottom - - border_width * 2); + child_allocation.width = + widget->allocation.width - + xthickness * 2 - + inner_border.left - + inner_border.right - + border_width * 2; + + child_allocation.height = + widget->allocation.height - + ythickness * 2 - + inner_border.top - + inner_border.bottom - + border_width * 2; if (gtk_widget_get_can_default (GTK_WIDGET (button))) { child_allocation.x += default_border.left; child_allocation.y += default_border.top; - child_allocation.width = MAX (1, child_allocation.width - default_border.left - default_border.right); - child_allocation.height = MAX (1, child_allocation.height - default_border.top - default_border.bottom); + child_allocation.width = child_allocation.width - default_border.left - default_border.right; + child_allocation.height = child_allocation.height - default_border.top - default_border.bottom; } if (gtk_widget_get_can_focus (GTK_WIDGET (button))) { child_allocation.x += focus_width + focus_pad; child_allocation.y += focus_width + focus_pad; - child_allocation.width = MAX (1, child_allocation.width - (focus_width + focus_pad) * 2); - child_allocation.height = MAX (1, child_allocation.height - (focus_width + focus_pad) * 2); + child_allocation.width = child_allocation.width - (focus_width + focus_pad) * 2; + child_allocation.height = child_allocation.height - (focus_width + focus_pad) * 2; } if (button->depressed) @@ -1516,6 +1519,9 @@ gtk_button_size_allocate (GtkWidget *widget, child_allocation.y += child_displacement_y; } + child_allocation.width = MAX (1, child_allocation.width); + child_allocation.height = MAX (1, child_allocation.height); + gtk_widget_size_allocate (child, &child_allocation); } }