Index: gtk/gtkvbbox.c
===================================================================
--- gtk/gtkvbbox.c	(Revision 20719)
+++ gtk/gtkvbbox.c	(Arbeitskopie)
@@ -107,33 +107,160 @@ gtk_vbutton_box_get_layout_default (void
   return default_layout_style;
 }
 
+/* The aim is to layout buttons preferrably homogeneous.
+ * If the vertical space is not enough, make buttons as high as possible.
+ * See also gtkhbbox for a similar implementation.
+ */
+static gint*
+gtk_vbutton_box_get_children_sizes (GtkWidget     *widget,
+                                    GtkAllocation *allocation,
+                                    gint          *primary_height,
+                                    gint          *secondary_height,
+                                    gint          *child_width,
+                                    gint          *nvis_children,
+                                    gint          *n_secondaries)
+{
+  gint *children_heights;
+  gint child_height;
+  gint total_height;
+  gint total_spacing;
+  gint i;
+  GList *children;
+  gint extra_space;
+  gint child_min_height, ipad_height;
+  GtkBoxChild *child;
+  GtkWidget *child_widget;
+  GtkRequisition req;
+  gint extra;
+
+  _gtk_button_box_child_requisition (widget,
+                                     nvis_children, n_secondaries,
+                                     child_width, &child_height);
+  if (*nvis_children == 0)
+    {
+      *primary_height = *secondary_height = *n_secondaries = 0;
+      return NULL;
+    }
 
+  children_heights = g_slice_alloc (sizeof (gint) * (*nvis_children));
 
+  total_height = *nvis_children * child_height;
+  total_spacing = *nvis_children * gtk_box_get_spacing (GTK_BOX (widget));
+
+  /* We don't check || !gtk_box_get_homogeneous (GTK_BOX (widget)) here
+   * because by definition this is TRUE for button boxes and actually
+   * checking breaks many, many things.
+   */
+  if (!allocation || total_height + total_spacing > allocation->height)
+    {
+      /* Homogeneous buttons would not fit into the allocation,
+       * therefore buttons should be smaller but as high as possible
+       */
+      _gtk_button_box_child_size_props (GTK_BUTTON_BOX (widget),
+                                        NULL, &child_min_height,
+                                        NULL, &ipad_height);
+
+      *primary_height = 0;
+      *secondary_height = 0;
+      children = GTK_BOX (widget)->children;
+      i = 0;
+
+      while (children)
+        {
+          child = children->data;
+          child_widget = child->widget;
+          children = children->next;
+
+          if (GTK_WIDGET_VISIBLE (child_widget))
+            {
+              gtk_widget_size_request (child_widget, &req);
+              req.height = MAX (req.height + ipad_height, child_min_height);
+
+              if (!child->is_secondary)
+                *primary_height += req.height;
+              else
+                *secondary_height += req.height;
+
+              children_heights[i++] = req.height;
+            }
+        }
+
+      total_height = *primary_height + *secondary_height;
+
+      /* Distribute the extra space between children
+       *
+       * We don't check && gtk_box_get_homogeneous (GTK_BOX (widget)) here
+       * because by definition this is TRUE for button boxes and actually
+       * checking would break many, many things
+       */
+      if (allocation)
+        extra_space = allocation->height - (total_height + total_spacing);
+      else
+        extra_space = 0;
+
+      /* If extra space is available, distribute it evenly to the buttons. */
+      if (extra_space > 0)
+        {
+          extra = extra_space / *nvis_children;
+          children = GTK_BOX (widget)->children;
+          i = 0;
+
+          while (children)
+            {
+              child = children->data;
+              child_widget = child->widget;
+              children = children->next;
+
+              if (GTK_WIDGET_VISIBLE (child_widget))
+                {
+                  children_heights[i++] += extra;
+
+                  if (!child->is_secondary)
+                    *primary_height += extra;
+                  else
+                    *secondary_height += extra;
+                }
+            }
+        }
+    }
+  else
+    {
+      /* Homogeneous allocation for all buttons */
+      *primary_height = child_height * (*nvis_children - *n_secondaries);
+      *secondary_height = child_height * *n_secondaries;
+      for (i = 0; i < *nvis_children; i++)
+        children_heights[i] = child_height;
+    }
+
+  return children_heights;
+}
 
 static void
 gtk_vbutton_box_size_request (GtkWidget      *widget,
-			      GtkRequisition *requisition)
+                              GtkRequisition *requisition)
 {
-  GtkBox *box;
-  GtkButtonBox *bbox;
-  gint nvis_children;
+  gint primary_height;
+  gint secondary_height;
   gint child_width;
-  gint child_height;
+  gint nvis_children;
+  gint n_secondaries;
+  gint *children_heights;
   gint spacing;
   GtkButtonBoxStyle layout;
-  
-  box = GTK_BOX (widget);
-  bbox = GTK_BUTTON_BOX (widget);
+  guint border_width;
 
-  spacing = box->spacing;
-  layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
-	  ? bbox->layout_style : default_layout_style;
-  
-  _gtk_button_box_child_requisition (widget,
-                                     &nvis_children,
-				     NULL,
-                                     &child_width,
-                                     &child_height);
+  spacing = gtk_box_get_spacing (GTK_BOX (widget));
+  layout = GTK_BUTTON_BOX (widget)->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
+    ? GTK_BUTTON_BOX (widget)->layout_style : default_layout_style;
+
+  children_heights = gtk_vbutton_box_get_children_sizes (widget,
+                                                         NULL,
+                                                         &primary_height,
+                                                         &secondary_height,
+                                                         &child_width,
+                                                         &nvis_children,
+                                                         &n_secondaries);
+  g_slice_free1 (sizeof (gint) * nvis_children, children_heights);
 
   if (nvis_children == 0)
     {
@@ -146,120 +273,132 @@ gtk_vbutton_box_size_request (GtkWidget 
       {
       case GTK_BUTTONBOX_SPREAD:
         requisition->height =
-		nvis_children*child_height + ((nvis_children+1)*spacing);
-	break;
+          primary_height + secondary_height + ((nvis_children + 1) * spacing);
+        break;
       case GTK_BUTTONBOX_EDGE:
       case GTK_BUTTONBOX_START:
       case GTK_BUTTONBOX_END:
       case GTK_BUTTONBOX_CENTER:
         requisition->height =
-		nvis_children*child_height + ((nvis_children-1)*spacing);
-	break;
+          primary_height + secondary_height + ((nvis_children - 1) * spacing);
+        break;
       default:
-	    g_assert_not_reached();
-	    break;
+        g_assert_not_reached ();
+        break;
       }
-	  
+
       requisition->width = child_width;
     }
-	  
-  requisition->width += GTK_CONTAINER (box)->border_width * 2;
-  requisition->height += GTK_CONTAINER (box)->border_width * 2;
-}
-
 
+  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+  requisition->width += border_width * 2;
+  requisition->height += border_width * 2;
+}
 
 static void
 gtk_vbutton_box_size_allocate (GtkWidget     *widget,
 			       GtkAllocation *allocation)
 {
-  GtkBox *base_box;
-  GtkButtonBox *box;
+  GtkButtonBoxStyle layout;
+  gint primary_height;
+  gint secondary_height;
+  gint child_width;
+  gint *children_heights;
   GtkBoxChild *child;
   GList *children;
-  GtkAllocation child_allocation;
   gint nvis_children;
+  gint n_primaries;
   gint n_secondaries;
-  gint child_width;
-  gint child_height;
   gint x = 0;
   gint y = 0;
   gint secondary_y = 0;
-  gint height;
-  gint childspace;
+  gint inner_height;
   gint childspacing = 0;
-  GtkButtonBoxStyle layout;
-  gint spacing;
-  
-  base_box = GTK_BOX (widget);
-  box = GTK_BUTTON_BOX (widget);
-  spacing = base_box->spacing;
-  layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
-	  ? box->layout_style : default_layout_style;
-  _gtk_button_box_child_requisition (widget,
-                                     &nvis_children,
-				     &n_secondaries,
-                                     &child_width,
-                                     &child_height);
+  gint primary_spacing;
+  gint secondary_spacing;
+  gint border_width;
+  GtkAllocation child_allocation;
+  gint child_height;
+  gint i;
+
   widget->allocation = *allocation;
-  height = allocation->height - GTK_CONTAINER (box)->border_width*2;
+
+  children_heights = gtk_vbutton_box_get_children_sizes (widget,
+                                                         &widget->allocation,
+                                                         &primary_height,
+                                                         &secondary_height,
+                                                         &child_width,
+                                                         &nvis_children,
+                                                         &n_secondaries);
+
+  if (nvis_children == 0)
+    return;
+
+  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+  n_primaries = nvis_children - n_secondaries;
+  inner_height = allocation->height - 2 * border_width;
+
+  layout = GTK_BUTTON_BOX (widget)->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
+    ? GTK_BUTTON_BOX (widget)->layout_style : default_layout_style;
+
   switch (layout)
-  {
-  case GTK_BUTTONBOX_SPREAD:
-    childspacing = (height - (nvis_children * child_height)) / (nvis_children + 1);
-    y = allocation->y + GTK_CONTAINER (box)->border_width + childspacing;
-    secondary_y = y + ((nvis_children - n_secondaries) * (child_height + childspacing));
-    break;
-  case GTK_BUTTONBOX_EDGE:
-    if (nvis_children >= 2)
-      {
-        childspacing = (height - (nvis_children*child_height)) / (nvis_children-1);
-	y = allocation->y + GTK_CONTAINER (box)->border_width;
-	secondary_y = y + ((nvis_children - n_secondaries) * (child_height + childspacing));
-      }
-    else
-      {
-	/* one or zero children, just center */
-	childspacing = height;
-	y = secondary_y = allocation->y + (allocation->height - child_height) / 2;
-      }
-    break;
-  case GTK_BUTTONBOX_START:
-    childspacing = spacing;
-    y = allocation->y + GTK_CONTAINER (box)->border_width;
-    secondary_y = allocation->y + allocation->height
-      - child_height * n_secondaries
-      - spacing * (n_secondaries - 1)
-      - GTK_CONTAINER (box)->border_width;
-    break;
-  case GTK_BUTTONBOX_END:
-    childspacing = spacing;
-    y = allocation->y + allocation->height 
-      - child_height * (nvis_children - n_secondaries)
-      - spacing * (nvis_children - n_secondaries - 1)
-      - GTK_CONTAINER (box)->border_width;
-    secondary_y = allocation->y + GTK_CONTAINER (box)->border_width;
-    break;
-  case GTK_BUTTONBOX_CENTER:
-    childspacing = spacing;
-    y = allocation->y + 
-      (allocation->height
-       - (child_height * (nvis_children - n_secondaries)
-	  + spacing * (nvis_children - n_secondaries - 1)))/2
-      + (n_secondaries * child_height + n_secondaries * spacing)/2;
-    secondary_y = allocation->y + GTK_CONTAINER (box)->border_width;
-    break;
-  default:
-    g_assert_not_reached();
-    break;
-  }
-		  
-  
+    {
+    case GTK_BUTTONBOX_SPREAD:
+      childspacing = (inner_height - (primary_height + secondary_height))
+                       / (nvis_children + 1);
+      primary_spacing = childspacing * (n_primaries - 1);
+      y = allocation->y + border_width + childspacing;
+      secondary_y = y + primary_height + primary_spacing + childspacing;
+      break;
+    case GTK_BUTTONBOX_EDGE:
+      if (nvis_children >= 2)
+        {
+          childspacing = (inner_height - (primary_height + secondary_height))
+                           / (nvis_children - 1);
+          primary_spacing = childspacing * (n_primaries - 1);
+          y = allocation->y + border_width;
+          secondary_y = y + primary_height + primary_spacing + childspacing;
+        }
+      else
+        {
+          /* one or zero children, just center */
+          childspacing = inner_height;
+          y = secondary_y = allocation->y + (allocation->height - primary_height) / 2;
+        }
+      break;
+    case GTK_BUTTONBOX_START:
+      childspacing = gtk_box_get_spacing (GTK_BOX (widget));
+      secondary_spacing = childspacing * (n_secondaries - 1);
+      y = allocation->y + border_width;
+      secondary_y = allocation->y + allocation->height
+        - secondary_height - secondary_spacing - border_width;
+      break;
+    case GTK_BUTTONBOX_END:
+      childspacing = gtk_box_get_spacing (GTK_BOX (widget));
+      primary_spacing = childspacing * (n_primaries - 1);
+      y = allocation->y + allocation->height
+        - primary_height - primary_spacing - border_width;
+      secondary_y = allocation->y + border_width;
+      break;
+    case GTK_BUTTONBOX_CENTER:
+      childspacing = gtk_box_get_spacing (GTK_BOX (widget));
+      primary_spacing = childspacing * (n_primaries - 1);
+      secondary_spacing = childspacing * (n_secondaries - 1);
+      y = allocation->y + (allocation->height
+        - (primary_height + primary_spacing)) / 2
+        + (secondary_height + secondary_spacing + childspacing) / 2;
+      secondary_y = allocation->y + border_width;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
   x = allocation->x + (allocation->width - child_width) / 2;
-  childspace = child_height + childspacing;
 
-  children = GTK_BOX (box)->children;
-	  
+  children = GTK_BOX (widget)->children;
+  i = 0;
   while (children)
     {
       child = children->data;
@@ -267,24 +406,27 @@ gtk_vbutton_box_size_allocate (GtkWidget
 
       if (GTK_WIDGET_VISIBLE (child->widget))
 	{
+          child_height = children_heights[i++];
+
 	  child_allocation.width = child_width;
 	  child_allocation.height = child_height;
 	  child_allocation.x = x;
-	  
+
 	  if (child->is_secondary)
 	    {
 	      child_allocation.y = secondary_y;
-	      secondary_y += childspace;
+	      secondary_y += child_height + childspacing;
 	    }
 	  else
 	    {
 	      child_allocation.y = y;
-	      y += childspace;
+	      y += child_height + childspacing;
 	    }
-	  
+
 	  gtk_widget_size_allocate (child->widget, &child_allocation);
 	}
     }
+  g_slice_free1 (sizeof (gint) * nvis_children, children_heights);
 }
   
 #define __GTK_VBBOX_C__
Index: gtk/gtkhbbox.c
===================================================================
--- gtk/gtkhbbox.c	(Revision 20719)
+++ gtk/gtkhbbox.c	(Arbeitskopie)
@@ -96,7 +96,6 @@ gtk_hbutton_box_get_spacing_default (voi
   return default_spacing;
 }
 
-
 /* get default value for layout style */
 
 GtkButtonBoxStyle
@@ -105,157 +104,307 @@ gtk_hbutton_box_get_layout_default (void
   return default_layout_style;
 }
 
+/* The aim is to layout buttons preferrably homogeneous.
+ * If the horizontal space is not enough, make buttons as wide as possible.
+ * - If a homogeneous layout is possible:
+ * + primary_width and secondary_width will be the sizes of the primary and
+ *   secondary groups (basically the homogeneous width times the number of items).
+ * + children_widths will contain the homogeneous width for all items
+ *
+ * - If a homogeneous layout is NOT possible:
+ * + primary_width and secondary_width will contain the sum of the widths
+ *   for each group
+ * + children_width will contain the heterogeneous width of each button,
+ *   i.e. its requisition plus any possible extra width
+ *
+ * All the other parameters come straight from _gtk_button_box_child_requisition
+*/
+static gint*
+gtk_hbutton_box_get_children_sizes (GtkWidget     *widget,
+                                    GtkAllocation *allocation,
+                                    gint          *primary_width,
+                                    gint          *secondary_width,
+                                    gint          *child_height,
+                                    gint          *nvis_children,
+                                    gint          *n_secondaries)
+{
+  gint *children_widths;
+  gint child_width;
+  gint total_width;
+  gint total_spacing;
+  gint i;
+  GList *children;
+  gint extra_space;
+  gint child_min_width, ipad_width;
+  GtkBoxChild *child;
+  GtkWidget *child_widget;
+  GtkRequisition req;
+  gint extra;
+
+  _gtk_button_box_child_requisition (widget,
+                                     nvis_children, n_secondaries,
+                                     &child_width, child_height);
+  if (*nvis_children == 0)
+    {
+      *primary_width = *secondary_width = *n_secondaries = 0;
+      return NULL;
+    }
+
+  children_widths = g_slice_alloc (sizeof (gint) * (*nvis_children));
+
+  total_width = *nvis_children * child_width;
+  total_spacing = *nvis_children * gtk_box_get_spacing (GTK_BOX (widget));
+
+  /* We don't check || !gtk_box_get_homogeneous (GTK_BOX (widget)) here
+   * because by definition this is TRUE for button boxes and actually
+   * checking breaks many, many things.
+   */
+  if (!allocation || total_width + total_spacing > allocation->width)
+    {
+      /* Homogeneous buttons would not fit into the allocation,
+       * therefore buttons should be smaller but as wide as possible
+       */
+      _gtk_button_box_child_size_props (GTK_BUTTON_BOX (widget),
+                                        &child_min_width, NULL,
+                                        &ipad_width, NULL);
+
+      *primary_width = 0;
+      *secondary_width = 0;
+      children = GTK_BOX (widget)->children;
+      i = 0;
+
+      while (children)
+        {
+          child = children->data;
+          child_widget = child->widget;
+          children = children->next;
+
+          if (GTK_WIDGET_VISIBLE (child_widget))
+            {
+              gtk_widget_size_request (child_widget, &req);
+              req.width = MAX (req.width + ipad_width, child_min_width);
+
+              if (!child->is_secondary)
+                *primary_width += req.width;
+              else
+                *secondary_width += req.width;
+
+              children_widths[i++] = req.width;
+            }
+        }
+
+      total_width = *primary_width + *secondary_width;
+
+      /* Distribute the extra space between children
+       *
+       * We don't check && gtk_box_get_homogeneous (GTK_BOX (widget)) here
+       * because by definition this is TRUE for button boxes and actually
+       * checking would break many, many things
+       */
+      if (allocation)
+        extra_space = allocation->width - (total_width + total_spacing);
+      else
+        extra_space = 0;
+
+      /* If extra space is available, distribute it evenly to the buttons. */
+      if (extra_space > 0)
+        {
+          extra = extra_space / *nvis_children;
+          children = GTK_BOX (widget)->children;
+          i = 0;
+
+          while (children)
+            {
+              child = children->data;
+              child_widget = child->widget;
+              children = children->next;
+
+              if (GTK_WIDGET_VISIBLE (child_widget))
+                {
+                  children_widths[i++] += extra;
+
+                  if (!child->is_secondary)
+                    *primary_width += extra;
+                  else
+                    *secondary_width += extra;
+                }
+            }
+        }
+    }
+  else
+    {
+      /* Homogeneous allocation for all buttons */
+      *primary_width = child_width * (*nvis_children - *n_secondaries);
+      *secondary_width = child_width * *n_secondaries;
+      for (i = 0; i < *nvis_children; i++)
+        children_widths[i] = child_width;
+    }
+
+  return children_widths;
+}
 
-  
 static void
 gtk_hbutton_box_size_request (GtkWidget      *widget,
 			      GtkRequisition *requisition)
 {
-  GtkBox *box;
-  GtkButtonBox *bbox;
-  gint nvis_children;
-  gint child_width;
+  gint primary_width;
+  gint secondary_width;
   gint child_height;
+  gint nvis_children;
+  gint n_secondaries;
+  gint *children_widths;
   gint spacing;
   GtkButtonBoxStyle layout;
-  
-  box = GTK_BOX (widget);
-  bbox = GTK_BUTTON_BOX (widget);
-
-  spacing = box->spacing;
-  layout = bbox->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
-	  ? bbox->layout_style : default_layout_style;
-  
-  _gtk_button_box_child_requisition (widget,
-                                     &nvis_children,
-				     NULL,
-                                     &child_width,
-                                     &child_height);
+  guint border_width;
+
+  spacing = gtk_box_get_spacing (GTK_BOX (widget));
+  layout = GTK_BUTTON_BOX (widget)->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
+    ? GTK_BUTTON_BOX (widget)->layout_style : default_layout_style;
+
+  children_widths = gtk_hbutton_box_get_children_sizes (widget,
+                                                        NULL,
+                                                        &primary_width,
+                                                        &secondary_width,
+                                                        &child_height,
+                                                        &nvis_children,
+                                                        &n_secondaries);
+  g_slice_free1 (sizeof (gint) * nvis_children, children_widths);
 
   if (nvis_children == 0)
-  {
-    requisition->width = 0; 
-    requisition->height = 0;
-  }
-  else
-  {
-    switch (layout)
     {
-    case GTK_BUTTONBOX_SPREAD:
-      requisition->width =
-	      nvis_children*child_width + ((nvis_children+1)*spacing);
-      break;
-    case GTK_BUTTONBOX_EDGE:
-    case GTK_BUTTONBOX_START:
-    case GTK_BUTTONBOX_END:
-    case GTK_BUTTONBOX_CENTER:
-      requisition->width = nvis_children*child_width + ((nvis_children-1)*spacing);
-      break;
-    default:
-      g_assert_not_reached();
-      break;
+      requisition->width = 0;
+      requisition->height = 0;
     }
-	  
-    requisition->height = child_height;
-  }
-	  
-  requisition->width += GTK_CONTAINER (box)->border_width * 2;
-  requisition->height += GTK_CONTAINER (box)->border_width * 2;
-}
+  else
+    {
+      switch (layout)
+        {
+        case GTK_BUTTONBOX_SPREAD:
+          requisition->width =
+            primary_width + secondary_width + ((nvis_children + 1) * spacing);
+          break;
+        case GTK_BUTTONBOX_EDGE:
+        case GTK_BUTTONBOX_START:
+        case GTK_BUTTONBOX_END:
+        case GTK_BUTTONBOX_CENTER:
+          requisition->width =
+            primary_width + secondary_width + ((nvis_children - 1) * spacing);
+          break;
+        default:
+          g_assert_not_reached ();
+          break;
+        }
 
+      requisition->height = child_height;
+    }
 
+  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+  requisition->width += border_width * 2;
+  requisition->height += border_width * 2;
+}
 
 static void
 gtk_hbutton_box_size_allocate (GtkWidget     *widget,
 			       GtkAllocation *allocation)
 {
-  GtkBox *base_box;
-  GtkButtonBox *box;
-  GtkBoxChild *child;
-  GList *children;
-  GtkAllocation child_allocation;
+  GtkButtonBoxStyle layout;
+  gint primary_width;
+  gint secondary_width;
+  gint child_height;
+  gint *children_widths;
+  gint x, y;
+  gint secondary_x;
   gint nvis_children;
   gint n_secondaries;
+  gint childspacing;
+  gint primary_spacing;
+  gint secondary_spacing;
+  gint n_primaries;
+  gint inner_width;
+  GList *children;
+  GtkBoxChild *child;
+  gint border_width;
+  GtkAllocation child_allocation;
   gint child_width;
-  gint child_height;
-  gint x = 0;
-  gint secondary_x = 0;
-  gint y = 0;
-  gint width;
-  gint childspace;
-  gint childspacing = 0;
-  GtkButtonBoxStyle layout;
-  gint spacing;
-  
-  base_box = GTK_BOX (widget);
-  box = GTK_BUTTON_BOX (widget);
-  spacing = base_box->spacing;
-  layout = box->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
-	  ? box->layout_style : default_layout_style;
-  _gtk_button_box_child_requisition (widget,
-                                     &nvis_children,
-				     &n_secondaries,
-                                     &child_width,
-                                     &child_height);
+  gint i;
+
   widget->allocation = *allocation;
-  width = allocation->width - GTK_CONTAINER (box)->border_width*2;
+
+  children_widths = gtk_hbutton_box_get_children_sizes (widget,
+                                                        &widget->allocation,
+                                                        &primary_width,
+                                                        &secondary_width,
+                                                        &child_height,
+                                                        &nvis_children,
+                                                        &n_secondaries);
+  if (nvis_children == 0)
+    return;
+
+  border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+  n_primaries = nvis_children - n_secondaries;
+  inner_width = allocation->width - 2 * border_width;
+
+  layout = GTK_BUTTON_BOX (widget)->layout_style != GTK_BUTTONBOX_DEFAULT_STYLE
+    ? GTK_BUTTON_BOX (widget)->layout_style : default_layout_style;
+
   switch (layout)
-  {
-  case GTK_BUTTONBOX_SPREAD:
-    childspacing = (width - (nvis_children * child_width)) / (nvis_children + 1);
-    x = allocation->x + GTK_CONTAINER (box)->border_width + childspacing;
-    secondary_x = x + ((nvis_children - n_secondaries) * (child_width + childspacing));
-    break;
-  case GTK_BUTTONBOX_EDGE:
-    if (nvis_children >= 2)
-      {
-	childspacing = (width - (nvis_children * child_width)) / (nvis_children - 1);
-	x = allocation->x + GTK_CONTAINER (box)->border_width;
-	secondary_x = x + ((nvis_children - n_secondaries) * (child_width + childspacing));
-      }
-    else
-      {
-	/* one or zero children, just center */
-        childspacing = width;
-	x = secondary_x = allocation->x + (allocation->width - child_width) / 2;
-      }
-    break;
-  case GTK_BUTTONBOX_START:
-    childspacing = spacing;
-    x = allocation->x + GTK_CONTAINER (box)->border_width;
-    secondary_x = allocation->x + allocation->width 
-      - child_width * n_secondaries
-      - spacing * (n_secondaries - 1)
-      - GTK_CONTAINER (box)->border_width;
-    break;
-  case GTK_BUTTONBOX_END:
-    childspacing = spacing;
-    x = allocation->x + allocation->width 
-      - child_width * (nvis_children - n_secondaries)
-      - spacing * (nvis_children - n_secondaries - 1)
-      - GTK_CONTAINER (box)->border_width;
-    secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
-    break;
-  case GTK_BUTTONBOX_CENTER:
-    childspacing = spacing;
-    x = allocation->x + 
-      (allocation->width
-       - (child_width * (nvis_children - n_secondaries)
-	  + spacing * (nvis_children - n_secondaries - 1)))/2
-      + (n_secondaries * child_width + n_secondaries * spacing)/2;
-    secondary_x = allocation->x + GTK_CONTAINER (box)->border_width;
-    break;
-  default:
-    g_assert_not_reached();
-    break;
-  }
+    {
+    case GTK_BUTTONBOX_SPREAD:
+      childspacing = (inner_width - (primary_width + secondary_width))
+                       / (nvis_children + 1);
+      primary_spacing = childspacing * (n_primaries - 1);
+      x = allocation->x + border_width + childspacing;
+      secondary_x = x + primary_width + primary_spacing + childspacing;
+      break;
+    case GTK_BUTTONBOX_EDGE:
+      if (nvis_children >= 2)
+        {
+          childspacing = (inner_width - (primary_width + secondary_width))
+                           / (nvis_children - 1);
+          primary_spacing = childspacing * (n_primaries - 1);
+          x = allocation->x + border_width;
+          secondary_x = x + primary_width + primary_spacing + childspacing;
+        }
+      else
+        {
+          /* one or zero children, just center */
+          childspacing = inner_width;
+          x = secondary_x = allocation->x + (allocation->width - primary_width) / 2;
+        }
+      break;
+    case GTK_BUTTONBOX_START:
+      childspacing = gtk_box_get_spacing (GTK_BOX (widget));
+      secondary_spacing = childspacing * (n_secondaries - 1);
+      x = allocation->x + border_width;
+      secondary_x = allocation->x + allocation->width
+        - secondary_width - secondary_spacing - border_width;
+      break;
+    case GTK_BUTTONBOX_END:
+      childspacing = gtk_box_get_spacing (GTK_BOX (widget));
+      primary_spacing = childspacing * (n_primaries - 1);
+      x = allocation->x + allocation->width
+        - primary_width - primary_spacing - border_width;
+      secondary_x = allocation->x + border_width;
+      break;
+    case GTK_BUTTONBOX_CENTER:
+      childspacing = gtk_box_get_spacing (GTK_BOX (widget));
+      primary_spacing = childspacing * (n_primaries - 1);
+      secondary_spacing = childspacing * (n_secondaries - 1);
+      x = allocation->x + (allocation->width
+         - (primary_width + primary_spacing)) / 2
+         + (secondary_width + secondary_spacing + childspacing) / 2;
+      secondary_x = allocation->x + border_width;
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
 
-		  
   y = allocation->y + (allocation->height - child_height) / 2;
-  childspace = child_width + childspacing;
 
-  children = GTK_BOX (box)->children;
-	  
+  children = GTK_BOX (widget)->children;
+  i = 0;
   while (children)
     {
       child = children->data;
@@ -263,28 +412,33 @@ gtk_hbutton_box_size_allocate (GtkWidget
 
       if (GTK_WIDGET_VISIBLE (child->widget))
 	{
+          child_width = children_widths[i++];
+
 	  child_allocation.width = child_width;
 	  child_allocation.height = child_height;
 	  child_allocation.y = y;
-	  
+
 	  if (child->is_secondary)
 	    {
 	      child_allocation.x = secondary_x;
-	      secondary_x += childspace;
+	      secondary_x += child_width + childspacing;
 	    }
 	  else
 	    {
 	      child_allocation.x = x;
-	      x += childspace;
+	      x += child_width + childspacing;
 	    }
 
 	  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-	    child_allocation.x = (allocation->x + allocation->width) - (child_allocation.x + child_width - allocation->x);
-	  
+	    child_allocation.x = (allocation->x + allocation->width)
+                                 - (child_allocation.x + child_width - allocation->x);
+
 	  gtk_widget_size_allocate (child->widget, &child_allocation);
 	}
     }
+
+  g_slice_free1 (sizeof (gint) * nvis_children, children_widths);
 }
-  
+
 #define __GTK_HBUTTON_BOX_C__
 #include "gtkaliasdef.c"
Index: gtk/gtkbbox.c
===================================================================
--- gtk/gtkbbox.c	(Revision 20719)
+++ gtk/gtkbbox.c	(Arbeitskopie)
@@ -384,13 +384,52 @@ gtk_button_box_set_child_secondary (GtkB
     gtk_widget_queue_resize (child);
 }
 
-/* Ask children how much space they require and round up 
+void
+_gtk_button_box_child_size_props (GtkButtonBox *bbox,
+                                  gint         *child_min_width,
+                                  gint         *child_min_height,
+                                  gint         *ipad_width,
+                                  gint         *ipad_height)
+{
+  gint width_default;
+  gint height_default;
+  gint ipad_x_default;
+  gint ipad_y_default;
+  gint ipad_x;
+  gint ipad_y;
+
+  gtk_widget_style_get (GTK_WIDGET (bbox),
+                        "child-min-width", &width_default,
+                        "child-min-height", &height_default,
+                        "child-internal-pad-x", &ipad_x_default,
+                        "child-internal-pad-y", &ipad_y_default,
+                        NULL);
+
+  if (child_min_width)
+    *child_min_width = bbox->child_min_width != GTK_BUTTONBOX_DEFAULT
+                       ? bbox->child_min_width : width_default;
+  if (child_min_height)
+    *child_min_height = bbox->child_min_height != GTK_BUTTONBOX_DEFAULT
+                        ? bbox->child_min_height : height_default;
+
+  ipad_x = bbox->child_ipad_x != GTK_BUTTONBOX_DEFAULT
+           ? bbox->child_ipad_x : ipad_x_default;
+  ipad_y = bbox->child_ipad_y != GTK_BUTTONBOX_DEFAULT
+           ? bbox->child_ipad_y : ipad_y_default;
+
+  if (ipad_width)
+    *ipad_width = 2 * ipad_x;
+  if (ipad_height)
+    *ipad_height = 2 * ipad_y;
+}
+
+/* Ask children how much space they require and round up
    to match minimum size and internal padding.
    Returns the size each single child should have. */
 void
 _gtk_button_box_child_requisition (GtkWidget *widget,
                                    int       *nvis_children,
-				   int       *nvis_secondaries,
+                                   int       *nvis_secondaries,
                                    int       *width,
                                    int       *height)
 {
@@ -404,44 +443,22 @@ _gtk_button_box_child_requisition (GtkWi
   GtkRequisition child_requisition;
   gint ipad_w;
   gint ipad_h;
-  gint width_default;
-  gint height_default;
-  gint ipad_x_default;
-  gint ipad_y_default;
-  
   gint child_min_width;
   gint child_min_height;
-  gint ipad_x;
-  gint ipad_y;
-  
+
   g_return_if_fail (GTK_IS_BUTTON_BOX (widget));
 
   bbox = GTK_BUTTON_BOX (widget);
 
-  gtk_widget_style_get (widget,
-                        "child-min-width", &width_default,
-                        "child-min-height", &height_default,
-                        "child-internal-pad-x", &ipad_x_default,
-                        "child-internal-pad-y", &ipad_y_default, 
-			NULL);
-  
-  child_min_width = bbox->child_min_width   != GTK_BUTTONBOX_DEFAULT
-	  ? bbox->child_min_width : width_default;
-  child_min_height = bbox->child_min_height !=GTK_BUTTONBOX_DEFAULT
-	  ? bbox->child_min_height : height_default;
-  ipad_x = bbox->child_ipad_x != GTK_BUTTONBOX_DEFAULT
-	  ? bbox->child_ipad_x : ipad_x_default;
-  ipad_y = bbox->child_ipad_y != GTK_BUTTONBOX_DEFAULT
-	  ? bbox->child_ipad_y : ipad_y_default;
+  _gtk_button_box_child_size_props (bbox, &child_min_width, &child_min_height,
+                                    &ipad_w, &ipad_h);
 
   nchildren = 0;
   nsecondaries = 0;
   children = GTK_BOX(bbox)->children;
   needed_width = child_min_width;
-  needed_height = child_min_height;  
-  ipad_w = ipad_x * 2;
-  ipad_h = ipad_y * 2;
-  
+  needed_height = child_min_height;
+
   while (children)
     {
       child = children->data;
Index: gtk/gtkbbox.h
===================================================================
--- gtk/gtkbbox.h	(Revision 20719)
+++ gtk/gtkbbox.h	(Arbeitskopie)
@@ -94,12 +94,13 @@ void gtk_button_box_get_child_ipadding (
 					gint         *ipad_y);
 #endif
 
-/* Internal method - do not use. */
-void _gtk_button_box_child_requisition (GtkWidget *widget,
-					int       *nvis_children,
-					int       *nvis_secondaries,
-					int       *width,
-					int       *height);
+/* Internal methods - do not use. */
+void
+_gtk_button_box_child_requisition      (GtkWidget     *widget,
+                                        int           *nvis_children,
+                                        int           *nvis_secondaries,
+                                        int           *width,
+                                        int           *height);
 G_END_DECLS
 
 #endif /* __GTK_BUTTON_BOX_H__ */
