674d3ad86802fec6369b9c791215b3d5673e4e81
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index afcd0d0..513c579 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -1673,6 +1673,8 @@ gtk_handle_box_set_snap_edge
 #if IN_FILE(__GTK_HBOX_C__)
 gtk_hbox_get_type G_GNUC_CONST
 gtk_hbox_new
+gtk_hbox_get_baseline_policy
+gtk_hbox_set_baseline_policy
 #endif
 #endif
 
diff --git a/gtk/gtkhbox.c b/gtk/gtkhbox.c
index 622caa1..357d182 100644
--- a/gtk/gtkhbox.c
+++ b/gtk/gtkhbox.c
@@ -32,6 +32,30 @@
 #include "gtkprivate.h"
 
 
+enum {
+  PROP_0,
+  PROP_BASELINE_POLICY
+};
+
+#define GTK_HBOX_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_HBOX, GtkHBoxPrivate))
+
+typedef struct _GtkHBoxPrivate GtkHBoxPrivate;
+
+struct _GtkHBoxPrivate
+{
+  GtkBaselinePolicy baseline_policy;
+  gint baseline;
+};
+
+static void gtk_hbox_set_property  (GObject        *object,
+		                    guint           prop_id,
+		                    const GValue   *value,
+		                    GParamSpec     *pspec);
+static void gtk_hbox_get_property  (GObject        *object,
+		                    guint           prop_id,
+		                    GValue         *value,
+		                    GParamSpec     *pspec);
+
 static void gtk_hbox_size_request  (GtkWidget      *widget,
 				    GtkRequisition *requisition);
 static void gtk_hbox_size_allocate (GtkWidget      *widget,
@@ -48,12 +72,24 @@ G_DEFINE_TYPE_WITH_CODE (GtkHBox, gtk_hbox, GTK_TYPE_BOX,
 static void
 gtk_hbox_class_init (GtkHBoxClass *class)
 {
-  GtkWidgetClass *widget_class;
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
 
-  widget_class = (GtkWidgetClass*) class;
+  gobject_class->set_property = gtk_hbox_set_property;
+  gobject_class->get_property = gtk_hbox_get_property;
 
   widget_class->size_request = gtk_hbox_size_request;
   widget_class->size_allocate = gtk_hbox_size_allocate;
+
+  g_type_class_add_private (gobject_class, sizeof (GtkHBoxPrivate));
+
+  g_object_class_install_property (gobject_class,
+				   PROP_BASELINE_POLICY,
+				   g_param_spec_enum ("baseline-policy",
+						      P_("Baseline policy"),
+						      P_("Indicates which baseline of children to use for vertical alignment"),
+						      GTK_TYPE_BASELINE_POLICY, GTK_BASELINE_NONE,
+						      G_PARAM_READWRITE));
 }
 
 static void
@@ -75,6 +111,43 @@ gtk_hbox_new (gboolean homogeneous,
   return GTK_WIDGET (hbox);
 }
 
+static void
+gtk_hbox_set_property (GObject      *object,
+		       guint         prop_id,
+		       const GValue *value,
+		       GParamSpec   *pspec)
+{
+  GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (object);
+
+  switch (prop_id)
+    {
+    case PROP_BASELINE_POLICY:
+      priv->baseline_policy = g_value_get_enum (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_hbox_get_property (GObject    *object,
+		       guint       prop_id,
+		       GValue     *value,
+		       GParamSpec *pspec)
+{
+  GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (object);
+
+  switch (prop_id)
+    {
+    case PROP_BASELINE_POLICY:
+      g_value_set_enum (value, priv->baseline_policy);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
 
 static void
 gtk_hbox_natural_size_request (GtkWidget      *child,
@@ -120,30 +193,82 @@ gtk_hbox_real_size_request (GtkWidget      *widget,
       children = children->next;
 
       if (GTK_WIDGET_VISIBLE (child->widget))
-	{
-	  GtkRequisition child_requisition;
-          size_request_func (child->widget, &child_requisition, widget);
+        nvis_children += 1;
+    }
+
+  if (nvis_children > 0)
+    {
+      GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (widget);
+      gint *baselines = NULL;
+      gint i;
+
+      if (priv->baseline_policy != GTK_BASELINE_NONE)
+        {
+          baselines = g_newa (gint, nvis_children);
+          priv->baseline = 0;
 
-          if (box->homogeneous)
+          i = 0;
+          children = box->children;
+          while (children)
             {
-              gint width = child_requisition.width + child->padding * 2;
-              requisition->width = MAX (requisition->width, width);
+              child = children->data;
+              children = children->next;
+
+              if (GTK_WIDGET_VISIBLE (child->widget))
+                {
+                  if (GTK_EXTENDED_LAYOUT_HAS_BASELINES (child->widget))
+                    {
+                      GtkExtendedLayout *layout = GTK_EXTENDED_LAYOUT (child->widget);
+
+                      gtk_extended_layout_set_baseline_offset (layout, 0);
+                      baselines[i] = gtk_extended_layout_get_single_baseline (layout, priv->baseline_policy);
+                      priv->baseline = MAX (priv->baseline, baselines[i]);
+                    }
+                  else
+                    baselines[i] = 0;
+
+                  ++i;
+                }
             }
-          else
+        }
+
+      i = 0;
+      children = box->children;
+      while (children)
+        {
+          child = children->data;
+          children = children->next;
+
+          if (GTK_WIDGET_VISIBLE (child->widget))
             {
-              requisition->width += child_requisition.width + child->padding * 2;
-            }
+              GtkRequisition child_requisition;
+              size_request_func (child->widget, &child_requisition, widget);
 
-	  requisition->height = MAX (requisition->height, child_requisition.height);
+              if (box->homogeneous)
+                {
+                  gint width = child_requisition.width + child->padding * 2;
+                  requisition->width = MAX (requisition->width, width);
+                }
+              else
+                {
+                  requisition->width += child_requisition.width + child->padding * 2;
+                }
 
-	  nvis_children += 1;
-	}
-    }
+              if (baselines)
+                {
+                  gint padding = MAX (priv->baseline - baselines[i], 0);
+                  child_requisition.height += padding;
+                }
+
+              requisition->height = MAX (requisition->height, child_requisition.height);
+
+              ++i;
+            }
+        }
 
-  if (nvis_children > 0)
-    {
       if (box->homogeneous)
 	requisition->width *= nvis_children;
+
       requisition->width += (nvis_children - 1) * box->spacing;
     }
 
@@ -191,6 +316,8 @@ gtk_hbox_size_allocate (GtkWidget     *widget,
 
   if (nvis_children > 0)
     {
+      GtkHBoxPrivate *priv = GTK_HBOX_GET_PRIVATE (widget);
+
       GtkTextDirection direction;
       GtkPackType packing;
       gint border_width;
@@ -365,13 +492,82 @@ gtk_hbox_size_allocate (GtkWidget     *widget,
                 } /* visible */
             } /* while children */
         } /* for packing */
+
+      if (GTK_BASELINE_NONE != priv->baseline_policy)
+        {
+          i = 0;
+          children = box->children;
+          while (children)
+            {
+              child = children->data;
+              children = children->next;
+
+              if (GTK_WIDGET_VISIBLE (child->widget))
+                {
+                  if (GTK_EXTENDED_LAYOUT_HAS_BASELINES (child->widget))
+                    {
+                      GtkExtendedLayout *layout = GTK_EXTENDED_LAYOUT (child->widget);
+                      gint baseline, dy;
+
+                      gtk_extended_layout_set_baseline_offset (layout, 0);
+                      baseline = gtk_extended_layout_get_single_baseline (layout, priv->baseline_policy);
+                      dy = priv->baseline - baseline;
+
+                      gtk_extended_layout_set_baseline_offset (layout, dy);
+                    }
+
+                  ++i;
+                }
+            }
+        } /* baseline_policy */
     } /* nvis_children */
 }
 
+/**
+ * gtk_hbox_get_baseline_policy:
+ * @hbox: a #GtkHBox
+ *
+ * Returns which baseline of children is used
+ * to vertically align them.
+ *
+ * Return value: the baseline alignment policy of the @hbox.
+ **/
+GtkBaselinePolicy
+gtk_hbox_get_baseline_policy (GtkHBox *hbox)
+{
+  g_return_val_if_fail (GTK_IS_HBOX (hbox), GTK_BASELINE_NONE);
+  return GTK_HBOX_GET_PRIVATE (hbox)->baseline_policy;
+}
+
+/**
+ * gtk_hbox_set_baseline_policy:
+ * @box: a #GtkBox
+ * @policy: the baseline alignment policy
+ *
+ * Sets the #GtkHBox:baseline-policy property of @vbox,
+ * which is the policy to vertically align children.
+ */
+void
+gtk_hbox_set_baseline_policy (GtkHBox           *hbox,
+                              GtkBaselinePolicy  policy)
+{
+  g_return_if_fail (GTK_IS_HBOX (hbox));
+  g_object_set (hbox, "baseline-policy", policy, NULL);
+}
+
 static GtkExtendedLayoutFeatures
 gtk_hbox_extended_layout_get_features (GtkExtendedLayout *layout)
 {
-  return GTK_EXTENDED_LAYOUT_NATURAL_SIZE;
+  GtkExtendedLayoutFeatures features;
+  GtkHBoxPrivate *priv;
+
+  features = GTK_EXTENDED_LAYOUT_NATURAL_SIZE;
+  priv = GTK_HBOX_GET_PRIVATE (layout);
+
+  if (GTK_BASELINE_NONE != priv->baseline_policy)
+    features |= GTK_EXTENDED_LAYOUT_BASELINES;
+
+  return features;
 }
 
 static void
@@ -381,11 +577,52 @@ gtk_hbox_extended_layout_get_natural_size (GtkExtendedLayout *layout,
   gtk_hbox_real_size_request (GTK_WIDGET (layout), requisition, gtk_hbox_natural_size_request);
 }
 
+static gint
+gtk_hbox_extended_layout_get_baselines (GtkExtendedLayout  *layout,
+                                        gint              **baselines)
+{
+  GtkHBoxPrivate *priv;
+  GtkBox *box;
+
+  gint hbox_baseline = 0;
+  gint child_baseline;
+
+  GtkBoxChild *child;
+  GList *children;
+
+  priv = GTK_HBOX_GET_PRIVATE (layout);
+
+  g_return_val_if_fail (GTK_BASELINE_NONE != priv->baseline_policy, -1);
+
+  box = GTK_BOX (layout);
+  children = box->children;
+
+  while (children)
+    {
+      child = children->data;
+      children = children->next;
+
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+          GTK_EXTENDED_LAYOUT_HAS_BASELINES (child->widget))
+        {
+          child_baseline = gtk_extended_layout_get_single_baseline (
+            GTK_EXTENDED_LAYOUT (child->widget), priv->baseline_policy);
+          hbox_baseline = MAX (hbox_baseline, child_baseline);
+        }
+    }
+
+  *baselines = g_new (gint, 1);
+  *baselines[0] = hbox_baseline;
+
+  return 1;
+}
+
 static void
 gtk_hbox_extended_layout_interface_init (GtkExtendedLayoutIface *iface)
 {
   iface->get_features = gtk_hbox_extended_layout_get_features;
   iface->get_natural_size = gtk_hbox_extended_layout_get_natural_size;
+  iface->get_baselines = gtk_hbox_extended_layout_get_baselines;
 }
 
 #define __GTK_HBOX_C__
diff --git a/gtk/gtkhbox.h b/gtk/gtkhbox.h
index 5296e21..ed546a0 100644
--- a/gtk/gtkhbox.h
+++ b/gtk/gtkhbox.h
@@ -56,10 +56,13 @@ struct _GtkHBoxClass
 };
 
 
-GType	   gtk_hbox_get_type (void) G_GNUC_CONST;
-GtkWidget* gtk_hbox_new	     (gboolean homogeneous,
-			      gint spacing);
+GType	          gtk_hbox_get_type            (void) G_GNUC_CONST;
+GtkWidget*        gtk_hbox_new	               (gboolean           homogeneous,
+                                                gint               spacing);
 
+GtkBaselinePolicy gtk_hbox_get_baseline_policy (GtkHBox           *hbox);
+void              gtk_hbox_set_baseline_policy (GtkHBox           *hbox,
+                                                GtkBaselinePolicy  policy);
 
 G_END_DECLS
 
