X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=unix%2Fgtkcols.c;h=e8223a726e3bab89fb6357419ccf4807632dddb1;hb=b73c1c1deb9e0c6080ce27d70191a7242886bea3;hp=3f5873200678cdf464c6da2bfe749ed22a284eb4;hpb=1e4273a9295f0922a84dcea3edffcbd7b5449c11;p=PuTTY.git diff --git a/unix/gtkcols.c b/unix/gtkcols.c index 3f587320..e8223a72 100644 --- a/unix/gtkcols.c +++ b/unix/gtkcols.c @@ -22,7 +22,20 @@ static void columns_forall(GtkContainer *container, gboolean include_internals, static gint columns_focus(GtkContainer *container, GtkDirectionType dir); #endif static GType columns_child_type(GtkContainer *container); +#if GTK_CHECK_VERSION(3,0,0) +static void columns_get_preferred_width(GtkWidget *widget, + gint *min, gint *nat); +static void columns_get_preferred_height(GtkWidget *widget, + gint *min, gint *nat); +static void columns_get_preferred_width_for_height(GtkWidget *widget, + gint height, + gint *min, gint *nat); +static void columns_get_preferred_height_for_width(GtkWidget *widget, + gint width, + gint *min, gint *nat); +#else static void columns_size_request(GtkWidget *widget, GtkRequisition *req); +#endif static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc); static GtkContainerClass *parent_class = NULL; @@ -104,7 +117,16 @@ static void columns_class_init(ColumnsClass *klass) widget_class->draw = columns_draw; widget_class->expose_event = columns_expose; #endif +#if GTK_CHECK_VERSION(3,0,0) + widget_class->get_preferred_width = columns_get_preferred_width; + widget_class->get_preferred_height = columns_get_preferred_height; + widget_class->get_preferred_width_for_height = + columns_get_preferred_width_for_height; + widget_class->get_preferred_height_for_width = + columns_get_preferred_height_for_width; +#else widget_class->size_request = columns_size_request; +#endif widget_class->size_allocate = columns_size_allocate; container_class->add = columns_base_add; @@ -268,6 +290,14 @@ static void columns_remove(GtkContainer *container, GtkWidget *widget) gtk_widget_unparent(widget); cols->children = g_list_remove_link(cols->children, children); g_list_free(children); + + if (child->same_height_as) { + g_return_if_fail(child->same_height_as->same_height_as == child); + child->same_height_as->same_height_as = NULL; + if (gtk_widget_get_visible(child->same_height_as->widget)) + gtk_widget_queue_resize(GTK_WIDGET(container)); + } + g_free(child); if (was_visible) gtk_widget_queue_resize(GTK_WIDGET(container)); @@ -375,6 +405,7 @@ void columns_add(Columns *cols, GtkWidget *child, childdata->colstart = colstart; childdata->colspan = colspan; childdata->force_left = FALSE; + childdata->same_height_as = NULL; cols->children = g_list_append(cols->children, childdata); cols->taborder = g_list_append(cols->taborder, child); @@ -396,26 +427,56 @@ void columns_add(Columns *cols, GtkWidget *child, } } +static ColumnsChild *columns_find_child(Columns *cols, GtkWidget *widget) +{ + GList *children; + ColumnsChild *child; + + for (children = cols->children; + children && (child = children->data); + children = children->next) { + + if (child->widget == widget) + return child; + } + + return NULL; +} + void columns_force_left_align(Columns *cols, GtkWidget *widget) { ColumnsChild *child; - GList *children; g_return_if_fail(cols != NULL); g_return_if_fail(IS_COLUMNS(cols)); g_return_if_fail(widget != NULL); - for (children = cols->children; - children && (child = children->data); - children = children->next) { - if (child->widget != widget) - continue; + child = columns_find_child(cols, widget); + g_return_if_fail(child != NULL); - child->force_left = TRUE; - if (gtk_widget_get_visible(widget)) - gtk_widget_queue_resize(GTK_WIDGET(cols)); - break; - } + child->force_left = TRUE; + if (gtk_widget_get_visible(widget)) + gtk_widget_queue_resize(GTK_WIDGET(cols)); +} + +void columns_force_same_height(Columns *cols, GtkWidget *cw1, GtkWidget *cw2) +{ + ColumnsChild *child1, *child2; + + g_return_if_fail(cols != NULL); + g_return_if_fail(IS_COLUMNS(cols)); + g_return_if_fail(cw1 != NULL); + g_return_if_fail(cw2 != NULL); + + child1 = columns_find_child(cols, cw1); + g_return_if_fail(child1 != NULL); + child2 = columns_find_child(cols, cw2); + g_return_if_fail(child2 != NULL); + + child1->same_height_as = child2; + child2->same_height_as = child1; + if (gtk_widget_get_visible(cw1) || gtk_widget_get_visible(cw2)) + gtk_widget_queue_resize(GTK_WIDGET(cols)); } void columns_taborder_last(Columns *cols, GtkWidget *widget) @@ -510,59 +571,40 @@ static gint columns_focus(GtkContainer *container, GtkDirectionType dir) #endif /* - * Now here comes the interesting bit. The actual layout part is - * done in the following two functions: - * - * columns_size_request() examines the list of widgets held in the - * Columns, and returns a requisition stating the absolute minimum - * size it can bear to be. - * - * columns_size_allocate() is given an allocation telling it what - * size the whole container is going to be, and it calls - * gtk_widget_size_allocate() on all of its (visible) children to - * set their size and position relative to the top left of the - * container. + * Underlying parts of the layout algorithm, to compute the Columns + * container's width or height given the widths or heights of its + * children. These will be called in various ways with different + * notions of width and height in use, so we abstract them out and + * pass them a 'get width' or 'get height' function pointer. */ -static void columns_size_request(GtkWidget *widget, GtkRequisition *req) +typedef gint (*widget_dim_fn_t)(ColumnsChild *child); + +static gint columns_compute_width(Columns *cols, widget_dim_fn_t get_width) { - Columns *cols; ColumnsChild *child; GList *children; - gint i, ncols, colspan, *colypos; + gint i, ncols, colspan, retwidth, childwidth; const gint *percentages; static const gint onecol[] = { 100 }; - g_return_if_fail(widget != NULL); - g_return_if_fail(IS_COLUMNS(widget)); - g_return_if_fail(req != NULL); - - cols = COLUMNS(widget); +#ifdef COLUMNS_WIDTH_DIAGNOSTICS + printf("compute_width(%p): start\n", cols); +#endif - req->width = 0; - req->height = cols->spacing; + retwidth = 0; ncols = 1; - colypos = g_new(gint, 1); - colypos[0] = 0; percentages = onecol; for (children = cols->children; children && (child = children->data); children = children->next) { - GtkRequisition creq; if (!child->widget) { /* Column reconfiguration. */ - for (i = 1; i < ncols; i++) { - if (colypos[0] < colypos[i]) - colypos[0] = colypos[i]; - } ncols = child->ncols; percentages = child->percentages; - colypos = g_renew(gint, colypos, ncols); - for (i = 1; i < ncols; i++) - colypos[i] = colypos[0]; continue; } @@ -570,17 +612,33 @@ static void columns_size_request(GtkWidget *widget, GtkRequisition *req) if (!gtk_widget_get_visible(child->widget)) continue; - gtk_widget_size_request(child->widget, &creq); + childwidth = get_width(child); colspan = child->colspan ? child->colspan : ncols-child->colstart; +#ifdef COLUMNS_WIDTH_DIAGNOSTICS + printf("compute_width(%p): ", cols); + if (GTK_IS_LABEL(child->widget)) + printf("label %p '%s' wrap=%s: ", child->widget, + gtk_label_get_text(GTK_LABEL(child->widget)), + (gtk_label_get_line_wrap(GTK_LABEL(child->widget)) + ? "TRUE" : "FALSE")); + else + printf("widget %p: ", child->widget); + { + gint min, nat; + gtk_widget_get_preferred_width(child->widget, &min, &nat); + printf("minwidth=%d natwidth=%d ", min, nat); + } + printf("thiswidth=%d span=%d\n", childwidth, colspan); +#endif + /* - * To compute width: we know that creq.width plus - * cols->spacing needs to equal a certain percentage of the - * full width of the container. So we work this value out, - * figure out how wide the container will need to be to - * make that percentage of it equal to that width, and - * ensure our returned width is at least that much. Very - * simple really. + * To compute width: we know that childwidth + cols->spacing + * needs to equal a certain percentage of the full width of + * the container. So we work this value out, figure out how + * wide the container will need to be to make that percentage + * of it equal to that width, and ensure our returned width is + * at least that much. Very simple really. */ { int percent, thiswid, fullwid; @@ -589,15 +647,19 @@ static void columns_size_request(GtkWidget *widget, GtkRequisition *req) for (i = 0; i < colspan; i++) percent += percentages[child->colstart+i]; - thiswid = creq.width + cols->spacing; + thiswid = childwidth + cols->spacing; /* - * Since creq is the _minimum_ size the child needs, we - * must ensure that it gets _at least_ that size. - * Hence, when scaling thiswid up to fullwid, we must - * round up, which means adding percent-1 before - * dividing by percent. + * Since childwidth is (at least sometimes) the _minimum_ + * size the child needs, we must ensure that it gets _at + * least_ that size. Hence, when scaling thiswid up to + * fullwid, we must round up, which means adding percent-1 + * before dividing by percent. */ fullwid = (thiswid * 100 + percent - 1) / percent; +#ifdef COLUMNS_WIDTH_DIAGNOSTICS + printf("compute_width(%p): after %p, thiswid=%d fullwid=%d\n", + cols, child->widget, thiswid, fullwid); +#endif /* * The above calculation assumes every widget gets @@ -605,58 +667,29 @@ static void columns_size_request(GtkWidget *widget, GtkRequisition *req) * cols->spacing here to account for the extra load of * spacing on the right. */ - if (req->width < fullwid - cols->spacing) - req->width = fullwid - cols->spacing; - } - - /* - * To compute height: the widget's top will be positioned - * at the largest y value so far reached in any of the - * columns it crosses. Then it will go down by creq.height - * plus padding; and the point it reaches at the bottom is - * the new y value in all those columns, and minus the - * padding it is also a lower bound on our own size - * request. - */ - { - int topy, boty; - - topy = 0; - for (i = 0; i < colspan; i++) { - if (topy < colypos[child->colstart+i]) - topy = colypos[child->colstart+i]; - } - boty = topy + creq.height + cols->spacing; - for (i = 0; i < colspan; i++) { - colypos[child->colstart+i] = boty; - } - - if (req->height < boty - cols->spacing) - req->height = boty - cols->spacing; + if (retwidth < fullwid - cols->spacing) + retwidth = fullwid - cols->spacing; } } - req->width += 2*gtk_container_get_border_width(GTK_CONTAINER(cols)); - req->height += 2*gtk_container_get_border_width(GTK_CONTAINER(cols)); + retwidth += 2*gtk_container_get_border_width(GTK_CONTAINER(cols)); - g_free(colypos); +#ifdef COLUMNS_WIDTH_DIAGNOSTICS + printf("compute_width(%p): done, returning %d\n", cols, retwidth); +#endif + + return retwidth; } -static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc) +static void columns_alloc_horiz(Columns *cols, gint ourwidth, + widget_dim_fn_t get_width) { - Columns *cols; ColumnsChild *child; GList *children; - gint i, ncols, colspan, border, *colxpos, *colypos; + gint i, ncols, colspan, border, *colxpos, childwidth; const gint *percentages; static const gint onecol[] = { 100 }; - g_return_if_fail(widget != NULL); - g_return_if_fail(IS_COLUMNS(widget)); - g_return_if_fail(alloc != NULL); - - cols = COLUMNS(widget); - gtk_widget_set_allocation(widget, alloc); border = gtk_container_get_border_width(GTK_CONTAINER(cols)); ncols = 1; @@ -667,36 +700,24 @@ static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc) * subtracting the spacing. */ colxpos = g_new(gint, 2); colxpos[0] = 0; - colxpos[1] = alloc->width - 2*border + cols->spacing; - /* As in size_request, colypos is the lowest y reached in each column. */ - colypos = g_new(gint, 1); - colypos[0] = 0; + colxpos[1] = ourwidth - 2*border + cols->spacing; for (children = cols->children; children && (child = children->data); children = children->next) { - GtkRequisition creq; - GtkAllocation call; if (!child->widget) { gint percent; /* Column reconfiguration. */ - for (i = 1; i < ncols; i++) { - if (colypos[0] < colypos[i]) - colypos[0] = colypos[i]; - } ncols = child->ncols; percentages = child->percentages; - colypos = g_renew(gint, colypos, ncols); - for (i = 1; i < ncols; i++) - colypos[i] = colypos[0]; colxpos = g_renew(gint, colxpos, ncols + 1); colxpos[0] = 0; percent = 0; for (i = 0; i < ncols; i++) { percent += percentages[i]; - colxpos[i+1] = (((alloc->width - 2*border) + cols->spacing) + colxpos[i+1] = (((ourwidth - 2*border) + cols->spacing) * percent / 100); } continue; @@ -706,7 +727,7 @@ static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc) if (!gtk_widget_get_visible(child->widget)) continue; - gtk_widget_get_child_requisition(child->widget, &creq); + childwidth = get_width(child); colspan = child->colspan ? child->colspan : ncols-child->colstart; /* @@ -716,12 +737,130 @@ static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc) * Unless we're forcing left, in which case the width is * exactly the requisition width. */ - call.x = alloc->x + border + colxpos[child->colstart]; + child->x = colxpos[child->colstart]; if (child->force_left) - call.width = creq.width; + child->w = childwidth; else - call.width = (colxpos[child->colstart+colspan] - - colxpos[child->colstart] - cols->spacing); + child->w = (colxpos[child->colstart+colspan] - + colxpos[child->colstart] - cols->spacing); + } + + g_free(colxpos); +} + +static gint columns_compute_height(Columns *cols, widget_dim_fn_t get_height) +{ + ColumnsChild *child; + GList *children; + gint i, ncols, colspan, *colypos, retheight, childheight; + + retheight = cols->spacing; + + ncols = 1; + colypos = g_new(gint, 1); + colypos[0] = 0; + + for (children = cols->children; + children && (child = children->data); + children = children->next) { + + if (!child->widget) { + /* Column reconfiguration. */ + for (i = 1; i < ncols; i++) { + if (colypos[0] < colypos[i]) + colypos[0] = colypos[i]; + } + ncols = child->ncols; + colypos = g_renew(gint, colypos, ncols); + for (i = 1; i < ncols; i++) + colypos[i] = colypos[0]; + continue; + } + + /* Only take visible widgets into account. */ + if (!gtk_widget_get_visible(child->widget)) + continue; + + childheight = get_height(child); + if (child->same_height_as) { + gint childheight2 = get_height(child->same_height_as); + if (childheight < childheight2) + childheight = childheight2; + } + colspan = child->colspan ? child->colspan : ncols-child->colstart; + + /* + * To compute height: the widget's top will be positioned at + * the largest y value so far reached in any of the columns it + * crosses. Then it will go down by childheight plus padding; + * and the point it reaches at the bottom is the new y value + * in all those columns, and minus the padding it is also a + * lower bound on our own height. + */ + { + int topy, boty; + + topy = 0; + for (i = 0; i < colspan; i++) { + if (topy < colypos[child->colstart+i]) + topy = colypos[child->colstart+i]; + } + boty = topy + childheight + cols->spacing; + for (i = 0; i < colspan; i++) { + colypos[child->colstart+i] = boty; + } + + if (retheight < boty - cols->spacing) + retheight = boty - cols->spacing; + } + } + + retheight += 2*gtk_container_get_border_width(GTK_CONTAINER(cols)); + + g_free(colypos); + + return retheight; +} + +static void columns_alloc_vert(Columns *cols, gint ourheight, + widget_dim_fn_t get_height) +{ + ColumnsChild *child; + GList *children; + gint i, ncols, colspan, *colypos, realheight, fakeheight; + + ncols = 1; + /* As in size_request, colypos is the lowest y reached in each column. */ + colypos = g_new(gint, 1); + colypos[0] = 0; + + for (children = cols->children; + children && (child = children->data); + children = children->next) { + if (!child->widget) { + /* Column reconfiguration. */ + for (i = 1; i < ncols; i++) { + if (colypos[0] < colypos[i]) + colypos[0] = colypos[i]; + } + ncols = child->ncols; + colypos = g_renew(gint, colypos, ncols); + for (i = 1; i < ncols; i++) + colypos[i] = colypos[0]; + continue; + } + + /* Only take visible widgets into account. */ + if (!gtk_widget_get_visible(child->widget)) + continue; + + realheight = fakeheight = get_height(child); + if (child->same_height_as) { + gint childheight2 = get_height(child->same_height_as); + if (fakeheight < childheight2) + fakeheight = childheight2; + } + colspan = child->colspan ? child->colspan : ncols-child->colstart; /* * To compute height: the widget's top will be positioned @@ -738,17 +877,279 @@ static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc) if (topy < colypos[child->colstart+i]) topy = colypos[child->colstart+i]; } - call.y = alloc->y + border + topy; - call.height = creq.height; - boty = topy + creq.height + cols->spacing; + child->y = topy + fakeheight/2 - realheight/2; + child->h = realheight; + boty = topy + fakeheight + cols->spacing; for (i = 0; i < colspan; i++) { colypos[child->colstart+i] = boty; } } - - gtk_widget_size_allocate(child->widget, &call); } - g_free(colxpos); g_free(colypos); } + +/* + * Now here comes the interesting bit. The actual layout part is + * done in the following two functions: + * + * columns_size_request() examines the list of widgets held in the + * Columns, and returns a requisition stating the absolute minimum + * size it can bear to be. + * + * columns_size_allocate() is given an allocation telling it what + * size the whole container is going to be, and it calls + * gtk_widget_size_allocate() on all of its (visible) children to + * set their size and position relative to the top left of the + * container. + */ + +#if !GTK_CHECK_VERSION(3,0,0) + +static gint columns_gtk2_get_width(ColumnsChild *child) +{ + GtkRequisition creq; + gtk_widget_size_request(child->widget, &creq); + return creq.width; +} + +static gint columns_gtk2_get_height(ColumnsChild *child) +{ + GtkRequisition creq; + gtk_widget_size_request(child->widget, &creq); + return creq.height; +} + +static void columns_size_request(GtkWidget *widget, GtkRequisition *req) +{ + Columns *cols; + + g_return_if_fail(widget != NULL); + g_return_if_fail(IS_COLUMNS(widget)); + g_return_if_fail(req != NULL); + + cols = COLUMNS(widget); + + req->width = columns_compute_width(cols, columns_gtk2_get_width); + req->height = columns_compute_height(cols, columns_gtk2_get_height); +} + +static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc) +{ + Columns *cols; + ColumnsChild *child; + GList *children; + gint border; + + g_return_if_fail(widget != NULL); + g_return_if_fail(IS_COLUMNS(widget)); + g_return_if_fail(alloc != NULL); + + cols = COLUMNS(widget); + gtk_widget_set_allocation(widget, alloc); + + border = gtk_container_get_border_width(GTK_CONTAINER(cols)); + + columns_alloc_horiz(cols, alloc->width, columns_gtk2_get_width); + columns_alloc_vert(cols, alloc->height, columns_gtk2_get_height); + + for (children = cols->children; + children && (child = children->data); + children = children->next) { + if (child->widget && gtk_widget_get_visible(child->widget)) { + GtkAllocation call; + call.x = alloc->x + border + child->x; + call.y = alloc->y + border + child->y; + call.width = child->w; + call.height = child->h; + gtk_widget_size_allocate(child->widget, &call); + } + } +} + +#else /* GTK_CHECK_VERSION(3,0,0) */ + +static gint columns_gtk3_get_min_width(ColumnsChild *child) +{ + gint ret; + gtk_widget_get_preferred_width(child->widget, &ret, NULL); + return ret; +} + +static gint columns_gtk3_get_nat_width(ColumnsChild *child) +{ + gint ret; + + if ((GTK_IS_LABEL(child->widget) && + gtk_label_get_line_wrap(GTK_LABEL(child->widget))) || + GTK_IS_ENTRY(child->widget)) { + /* + * We treat wrapping GtkLabels as a special case in this + * layout class, because the whole point of those is that I + * _don't_ want them to take up extra horizontal space for + * long text, but instead to wrap it to whatever size is used + * by the rest of the layout. + * + * GtkEntry gets similar treatment, because in OS X GTK I've + * found that it requests a natural width regardless of the + * output of gtk_entry_set_width_chars. + */ + gtk_widget_get_preferred_width(child->widget, &ret, NULL); + } else { + gtk_widget_get_preferred_width(child->widget, NULL, &ret); + } + return ret; +} + +static gint columns_gtk3_get_minfh_width(ColumnsChild *child) +{ + gint ret; + gtk_widget_get_preferred_width_for_height(child->widget, child->h, + &ret, NULL); + return ret; +} + +static gint columns_gtk3_get_natfh_width(ColumnsChild *child) +{ + gint ret; + gtk_widget_get_preferred_width_for_height(child->widget, child->h, + NULL, &ret); + return ret; +} + +static gint columns_gtk3_get_min_height(ColumnsChild *child) +{ + gint ret; + gtk_widget_get_preferred_height(child->widget, &ret, NULL); + return ret; +} + +static gint columns_gtk3_get_nat_height(ColumnsChild *child) +{ + gint ret; + gtk_widget_get_preferred_height(child->widget, NULL, &ret); + return ret; +} + +static gint columns_gtk3_get_minfw_height(ColumnsChild *child) +{ + gint ret; + gtk_widget_get_preferred_height_for_width(child->widget, child->w, + &ret, NULL); + return ret; +} + +static gint columns_gtk3_get_natfw_height(ColumnsChild *child) +{ + gint ret; + gtk_widget_get_preferred_height_for_width(child->widget, child->w, + NULL, &ret); + return ret; +} + +static void columns_get_preferred_width(GtkWidget *widget, + gint *min, gint *nat) +{ + Columns *cols; + + g_return_if_fail(widget != NULL); + g_return_if_fail(IS_COLUMNS(widget)); + + cols = COLUMNS(widget); + + if (min) + *min = columns_compute_width(cols, columns_gtk3_get_min_width); + if (nat) + *nat = columns_compute_width(cols, columns_gtk3_get_nat_width); +} + +static void columns_get_preferred_height(GtkWidget *widget, + gint *min, gint *nat) +{ + Columns *cols; + + g_return_if_fail(widget != NULL); + g_return_if_fail(IS_COLUMNS(widget)); + + cols = COLUMNS(widget); + + if (min) + *min = columns_compute_height(cols, columns_gtk3_get_min_height); + if (nat) + *nat = columns_compute_height(cols, columns_gtk3_get_nat_height); +} + +static void columns_get_preferred_width_for_height(GtkWidget *widget, + gint height, + gint *min, gint *nat) +{ + Columns *cols; + + g_return_if_fail(widget != NULL); + g_return_if_fail(IS_COLUMNS(widget)); + + cols = COLUMNS(widget); + + /* FIXME: which one should the get-height function here be? */ + columns_alloc_vert(cols, height, columns_gtk3_get_nat_height); + + if (min) + *min = columns_compute_width(cols, columns_gtk3_get_minfh_width); + if (nat) + *nat = columns_compute_width(cols, columns_gtk3_get_natfh_width); +} + +static void columns_get_preferred_height_for_width(GtkWidget *widget, + gint width, + gint *min, gint *nat) +{ + Columns *cols; + + g_return_if_fail(widget != NULL); + g_return_if_fail(IS_COLUMNS(widget)); + + cols = COLUMNS(widget); + + /* FIXME: which one should the get-height function here be? */ + columns_alloc_horiz(cols, width, columns_gtk3_get_nat_width); + + if (min) + *min = columns_compute_height(cols, columns_gtk3_get_minfw_height); + if (nat) + *nat = columns_compute_height(cols, columns_gtk3_get_natfw_height); +} + +static void columns_size_allocate(GtkWidget *widget, GtkAllocation *alloc) +{ + Columns *cols; + ColumnsChild *child; + GList *children; + gint border; + + g_return_if_fail(widget != NULL); + g_return_if_fail(IS_COLUMNS(widget)); + g_return_if_fail(alloc != NULL); + + cols = COLUMNS(widget); + gtk_widget_set_allocation(widget, alloc); + + border = gtk_container_get_border_width(GTK_CONTAINER(cols)); + + columns_alloc_horiz(cols, alloc->width, columns_gtk3_get_min_width); + columns_alloc_vert(cols, alloc->height, columns_gtk3_get_minfw_height); + + for (children = cols->children; + children && (child = children->data); + children = children->next) { + if (child->widget && gtk_widget_get_visible(child->widget)) { + GtkAllocation call; + call.x = alloc->x + border + child->x; + call.y = alloc->y + border + child->y; + call.width = child->w; + call.height = child->h; + gtk_widget_size_allocate(child->widget, &call); + } + } +} + +#endif