[gtk+] widget: Use ::measure vfunc to measure size



commit 9992a616efa47205ac16ed8be255eda5e7aadf6c
Author: Timm Bäder <mail baedert org>
Date:   Sat Oct 22 16:06:14 2016 +0200

    widget: Use ::measure vfunc to measure size
    
    Add a new ::measure vfunc similar to GtkCssGadget's that widget
    implementations have to override instead of the old get_preferred_width,
    get_preferred_height, get_preferred_width_for_height,
    get_preferred_height_for_width and
    get_preferred_height_and_baseline_for_width.

 demos/gtk-demo/offscreen_window.c  |   43 ++---
 demos/gtk-demo/offscreen_window2.c |   43 ++---
 gtk/gtkaccellabel.c                |   46 ++++--
 gtk/gtkactionbar.c                 |   44 ++---
 gtk/gtkapplicationwindow.c         |  136 ++++++---------
 gtk/gtkbbox.c                      |  136 ++-------------
 gtk/gtkbin.c                       |  122 +++-----------
 gtk/gtkbox.c                       |  101 ++---------
 gtk/gtkboxgadget.c                 |   10 +-
 gtk/gtkbutton.c                    |  111 +++----------
 gtk/gtkcalendar.c                  |   43 ++---
 gtk/gtkcellview.c                  |   80 ++-------
 gtk/gtkcheckbutton.c               |  155 +++--------------
 gtk/gtkcolorswatch.c               |   31 ++--
 gtk/gtkcombobox.c                  |   88 ++--------
 gtk/gtkentry.c                     |   65 ++-----
 gtk/gtkeventbox.c                  |   71 --------
 gtk/gtkexpander.c                  |   82 ++-------
 gtk/gtkfixed.c                     |   72 +++-----
 gtk/gtkflowbox.c                   |  118 +++----------
 gtk/gtkframe.c                     |   83 ++-------
 gtk/gtkgrid.c                      |   73 +-------
 gtk/gtkheaderbar.c                 |   65 ++------
 gtk/gtkicon.c                      |   46 +----
 gtk/gtkiconview.c                  |  152 ++++-------------
 gtk/gtkimage.c                     |   65 ++-----
 gtk/gtklabel.c                     |  102 ++---------
 gtk/gtklayout.c                    |   33 ++--
 gtk/gtklevelbar.c                  |   31 ++--
 gtk/gtklistbox.c                   |  141 +++------------
 gtk/gtkmagnifier.c                 |   55 ++----
 gtk/gtkmenu.c                      |  320 +++++++++++++++++-----------------
 gtk/gtkmenubar.c                   |   86 +++-------
 gtk/gtkmenuitem.c                  |   45 ++----
 gtk/gtkmodelbutton.c               |  111 ++----------
 gtk/gtknotebook.c                  |  102 ++++--------
 gtk/gtkoffscreenwindow.c           |   65 ++-----
 gtk/gtkpaned.c                     |  114 ++++---------
 gtk/gtkpathbar.c                   |  145 ++++++++--------
 gtk/gtkpopover.c                   |  179 ++++++--------------
 gtk/gtkprogressbar.c               |   43 ++---
 gtk/gtkrange.c                     |   48 ++----
 gtk/gtkrevealer.c                  |  100 +++--------
 gtk/gtkscale.c                     |   82 +++------
 gtk/gtkscrolledwindow.c            |   75 ++------
 gtk/gtkseparator.c                 |   32 ++---
 gtk/gtkseparatortoolitem.c         |   45 ++---
 gtk/gtksizerequest.c               |   96 +++-------
 gtk/gtkspinbutton.c                |   60 ++-----
 gtk/gtkspinner.c                   |   31 ++--
 gtk/gtkstack.c                     |   93 ++--------
 gtk/gtkswitch.c                    |   31 ++--
 gtk/gtktextview.c                  |   44 ++---
 gtk/gtktoolbar.c                   |   47 ++---
 gtk/gtktoolitem.c                  |   38 ----
 gtk/gtktoolitemgroup.c             |   31 ++--
 gtk/gtktoolpalette.c               |   30 ++--
 gtk/gtktreemenu.c                  |  102 +++---------
 gtk/gtktreeview.c                  |   90 ++++++-----
 gtk/gtkviewport.c                  |   97 +++--------
 gtk/gtkwidget.c                    |   73 ++------
 gtk/gtkwidget.h                    |   52 ++++--
 gtk/gtkwidgetprivate.h             |    8 -
 gtk/gtkwindow.c                    |  337 +++++++++---------------------------
 tests/gtkoffscreenbox.c            |   42 ++---
 65 files changed, 1533 insertions(+), 3804 deletions(-)
---
diff --git a/demos/gtk-demo/offscreen_window.c b/demos/gtk-demo/offscreen_window.c
index 9480025..1affe04 100644
--- a/demos/gtk-demo/offscreen_window.c
+++ b/demos/gtk-demo/offscreen_window.c
@@ -39,12 +39,13 @@ void       gtk_rotated_bin_set_angle (GtkRotatedBin *bin,
 
 static void     gtk_rotated_bin_realize       (GtkWidget       *widget);
 static void     gtk_rotated_bin_unrealize     (GtkWidget       *widget);
-static void     gtk_rotated_bin_get_preferred_width  (GtkWidget *widget,
-                                                      gint      *minimum,
-                                                      gint      *natural);
-static void     gtk_rotated_bin_get_preferred_height (GtkWidget *widget,
-                                                      gint      *minimum,
-                                                      gint      *natural);
+static void     gtk_rotated_bin_measure       (GtkWidget       *widget,
+                                               GtkOrientation   orientation,
+                                               int              for_size,
+                                               int             *minimum,
+                                               int             *natural,
+                                               int             *minimum_baseline,
+                                               int             *natural_baseline);
 static void     gtk_rotated_bin_size_allocate (GtkWidget       *widget,
                                                GtkAllocation   *allocation);
 static gboolean gtk_rotated_bin_damage        (GtkWidget       *widget,
@@ -152,8 +153,7 @@ gtk_rotated_bin_class_init (GtkRotatedBinClass *klass)
 
   widget_class->realize = gtk_rotated_bin_realize;
   widget_class->unrealize = gtk_rotated_bin_unrealize;
-  widget_class->get_preferred_width = gtk_rotated_bin_get_preferred_width;
-  widget_class->get_preferred_height = gtk_rotated_bin_get_preferred_height;
+  widget_class->measure = gtk_rotated_bin_measure;
   widget_class->size_allocate = gtk_rotated_bin_size_allocate;
   widget_class->draw = gtk_rotated_bin_draw;
 
@@ -396,27 +396,22 @@ gtk_rotated_bin_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_rotated_bin_get_preferred_width (GtkWidget *widget,
-                                     gint      *minimum,
-                                     gint      *natural)
+gtk_rotated_bin_measure (GtkWidget       *widget,
+                         GtkOrientation   orientation,
+                         int              for_size,
+                         int             *minimum,
+                         int             *natural,
+                         int             *minimum_baseline,
+                         int             *natural_baseline)
 {
   GtkRequisition requisition;
 
   gtk_rotated_bin_size_request (widget, &requisition);
 
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_rotated_bin_get_preferred_height (GtkWidget *widget,
-                                      gint      *minimum,
-                                      gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_rotated_bin_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    *minimum = *natural = requisition.width;
+  else
+    *minimum = *natural = requisition.height;
 }
 
 static void
diff --git a/demos/gtk-demo/offscreen_window2.c b/demos/gtk-demo/offscreen_window2.c
index 06c4a0a..22bbe52 100644
--- a/demos/gtk-demo/offscreen_window2.c
+++ b/demos/gtk-demo/offscreen_window2.c
@@ -36,12 +36,13 @@ GtkWidget* gtk_mirror_bin_new       (void);
 
 static void     gtk_mirror_bin_realize       (GtkWidget       *widget);
 static void     gtk_mirror_bin_unrealize     (GtkWidget       *widget);
-static void     gtk_mirror_bin_get_preferred_width  (GtkWidget *widget,
-                                                     gint      *minimum,
-                                                     gint      *natural);
-static void     gtk_mirror_bin_get_preferred_height (GtkWidget *widget,
-                                                     gint      *minimum,
-                                                     gint      *natural);
+static void     gtk_mirror_bin_measure       (GtkWidget       *widget,
+                                              GtkOrientation   orientation,
+                                              int              for_size,
+                                              int             *minimum,
+                                              int             *natural,
+                                              int             *minimum_baseline,
+                                              int             *natural_baseline);
 static void     gtk_mirror_bin_size_allocate (GtkWidget       *widget,
                                                GtkAllocation   *allocation);
 static gboolean gtk_mirror_bin_damage        (GtkWidget       *widget,
@@ -91,8 +92,7 @@ gtk_mirror_bin_class_init (GtkMirrorBinClass *klass)
 
   widget_class->realize = gtk_mirror_bin_realize;
   widget_class->unrealize = gtk_mirror_bin_unrealize;
-  widget_class->get_preferred_width = gtk_mirror_bin_get_preferred_width;
-  widget_class->get_preferred_height = gtk_mirror_bin_get_preferred_height;
+  widget_class->measure = gtk_mirror_bin_measure;
   widget_class->size_allocate = gtk_mirror_bin_size_allocate;
   widget_class->draw = gtk_mirror_bin_draw;
 
@@ -320,27 +320,22 @@ gtk_mirror_bin_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_mirror_bin_get_preferred_width (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
+gtk_mirror_bin_measure (GtkWidget       *widget,
+                        GtkOrientation   orientation,
+                        int              for_size,
+                        int             *minimum,
+                        int             *natural,
+                        int             *minimum_baseline,
+                        int             *natural_baseline)
 {
   GtkRequisition requisition;
 
   gtk_mirror_bin_size_request (widget, &requisition);
 
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_mirror_bin_get_preferred_height (GtkWidget *widget,
-                                     gint      *minimum,
-                                     gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_mirror_bin_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    *minimum = *natural = requisition.width;
+  else
+    *minimum = *natural = requisition.height;
 }
 
 static void
diff --git a/gtk/gtkaccellabel.c b/gtk/gtkaccellabel.c
index a6c3e13..3be1e68 100644
--- a/gtk/gtkaccellabel.c
+++ b/gtk/gtkaccellabel.c
@@ -142,11 +142,13 @@ static void         gtk_accel_label_finalize     (GObject            *object);
 static GskRenderNode *gtk_accel_label_get_render_node (GtkWidget   *widget,
                                                        GskRenderer *renderer);
 static const gchar *gtk_accel_label_get_string   (GtkAccelLabel      *accel_label);
-
-
-static void         gtk_accel_label_get_preferred_width (GtkWidget           *widget,
-                                                         gint                *min_width,
-                                                         gint                *nat_width);
+static void gtk_accel_label_measure (GtkWidget      *widget,
+                                     GtkOrientation  orientation,
+                                     int             for_size,
+                                     int            *minimum,
+                                     int            *natural,
+                                     int            *minimum_baseline,
+                                     int            *natural_baseline);
 
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkAccelLabel, gtk_accel_label, GTK_TYPE_LABEL)
@@ -162,7 +164,7 @@ gtk_accel_label_class_init (GtkAccelLabelClass *class)
   gobject_class->get_property = gtk_accel_label_get_property;
 
   widget_class->get_render_node = gtk_accel_label_get_render_node;
-  widget_class->get_preferred_width = gtk_accel_label_get_preferred_width;
+  widget_class->measure = gtk_accel_label_measure;
   widget_class->destroy = gtk_accel_label_destroy;
 
   gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_ACCEL_LABEL);
@@ -413,21 +415,33 @@ gtk_accel_label_get_accel_layout (GtkAccelLabel *accel_label)
 }
 
 static void
-gtk_accel_label_get_preferred_width (GtkWidget *widget,
-                                     gint      *min_width,
-                                     gint      *nat_width)
+gtk_accel_label_measure (GtkWidget      *widget,
+                         GtkOrientation  orientation,
+                         int             for_size,
+                         int            *minimum,
+                         int            *natural,
+                         int            *minimum_baseline,
+                         int            *natural_baseline)
 {
   GtkAccelLabel *accel_label = GTK_ACCEL_LABEL (widget);
-  PangoLayout   *layout;
-  gint           width;
 
-  GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->get_preferred_width (widget, min_width, nat_width);
+  GTK_WIDGET_CLASS (gtk_accel_label_parent_class)->measure (widget,
+                                                            orientation,
+                                                            for_size,
+                                                            minimum, natural,
+                                                            minimum_baseline, natural_baseline);
 
-  layout = gtk_accel_label_get_accel_layout (accel_label);
-  pango_layout_get_pixel_size (layout, &width, NULL);
-  accel_label->priv->accel_string_width = width;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      PangoLayout *layout;
+      int width;
 
-  g_object_unref (layout);
+      layout = gtk_accel_label_get_accel_layout (accel_label);
+      pango_layout_get_pixel_size (layout, &width, NULL);
+      accel_label->priv->accel_string_width = width;
+
+      g_object_unref (layout);
+    }
 }
 
 static gint
diff --git a/gtk/gtkactionbar.c b/gtk/gtkactionbar.c
index 870cb3b..9de2de0 100644
--- a/gtk/gtkactionbar.c
+++ b/gtk/gtkactionbar.c
@@ -256,40 +256,27 @@ gtk_action_bar_measure (GtkCssGadget   *gadget,
   GtkWidget *widget = gtk_css_gadget_get_owner (gadget);
   GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
 
-  if (orientation == GTK_ORIENTATION_HORIZONTAL)
-    gtk_widget_get_preferred_width_for_height (priv->revealer, for_size, minimum, natural);
-  else
-    gtk_widget_get_preferred_height_and_baseline_for_width (priv->revealer, for_size, minimum, natural, 
minimum_baseline, natural_baseline);
-}
-
-static void
-gtk_action_bar_get_preferred_width_for_height (GtkWidget *widget,
-                                               gint       height,
-                                               gint      *minimum,
-                                               gint      *natural)
-{
-  GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
+  gtk_widget_measure (priv->revealer,
+                      orientation,
+                      for_size,
+                      minimum, natural,
+                      minimum_baseline, natural_baseline);
 }
 
 static void
-gtk_action_bar_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                            gint       width,
-                                                            gint      *minimum,
-                                                            gint      *natural,
-                                                            gint      *minimum_baseline,
-                                                            gint      *natural_baseline)
+gtk_action_bar_measure_ (GtkWidget *widget,
+                        GtkOrientation orientation,
+                        int        for_size,
+                        int       *minimum,
+                        int       *natural,
+                        int       *minimum_baseline,
+                        int       *natural_baseline)
 {
   GtkActionBarPrivate *priv = gtk_action_bar_get_instance_private (GTK_ACTION_BAR (widget));
 
   gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
@@ -312,8 +299,7 @@ gtk_action_bar_class_init (GtkActionBarClass *klass)
   widget_class->destroy = gtk_action_bar_destroy;
   widget_class->get_render_node = gtk_action_bar_get_render_node;
   widget_class->size_allocate = gtk_action_bar_size_allocate;
-  widget_class->get_preferred_width_for_height = gtk_action_bar_get_preferred_width_for_height;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_action_bar_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_action_bar_measure_;
 
   container_class->add = gtk_action_bar_add;
   container_class->remove = gtk_action_bar_remove;
diff --git a/gtk/gtkapplicationwindow.c b/gtk/gtkapplicationwindow.c
index 7929812..5742d91 100644
--- a/gtk/gtkapplicationwindow.c
+++ b/gtk/gtkapplicationwindow.c
@@ -526,104 +526,71 @@ enum {
 static GParamSpec *gtk_application_window_properties[N_PROPS];
 
 static void
-gtk_application_window_real_get_preferred_height (GtkWidget *widget,
-                                                  gint      *minimum_height,
-                                                  gint      *natural_height)
+gtk_application_window_measure (GtkWidget *widget,
+                                GtkOrientation  orientation,
+                                int             for_size,
+                                int            *minimum,
+                                int            *natural,
+                                int            *minimum_baseline,
+                                int            *natural_baseline)
 {
   GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
+  GtkApplicationWindowPrivate *priv = gtk_application_window_get_instance_private (window);
 
-  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
-    ->get_preferred_height (widget, minimum_height, natural_height);
+  GTK_WIDGET_CLASS (gtk_application_window_parent_class)->measure (widget,
+                                                                   orientation,
+                                                                   for_size,
+                                                                   minimum, natural,
+                                                                   minimum_baseline, natural_baseline);
 
-  if (window->priv->menubar != NULL)
+  if (priv->menubar != NULL)
     {
-      gint menubar_min_height, menubar_nat_height;
-
-      gtk_widget_get_preferred_height (window->priv->menubar, &menubar_min_height, &menubar_nat_height);
-      *minimum_height += menubar_min_height;
-      *natural_height += menubar_nat_height;
-    }
-}
-
-static void
-gtk_application_window_real_get_preferred_height_for_width (GtkWidget *widget,
-                                                            gint       width,
-                                                            gint      *minimum_height,
-                                                            gint      *natural_height)
-{
-  GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
+      int menubar_min, menubar_nat;
 
-  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
-    ->get_preferred_height_for_width (widget, width, minimum_height, natural_height);
-
-  if (window->priv->menubar != NULL)
-    {
-      gint menubar_min_height, menubar_nat_height;
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          GtkBorder border = {0};
+          int menubar_height = 0;
 
-      gtk_widget_get_preferred_height_for_width (window->priv->menubar, width, &menubar_min_height, 
&menubar_nat_height);
-      *minimum_height += menubar_min_height;
-      *natural_height += menubar_nat_height;
-    }
-}
+          gtk_widget_get_preferred_height_for_width (priv->menubar, for_size, &menubar_height, NULL);
 
-static void
-gtk_application_window_real_get_preferred_width (GtkWidget *widget,
-                                                 gint      *minimum_width,
-                                                 gint      *natural_width)
-{
-  GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
+          GTK_WIDGET_CLASS (gtk_application_window_parent_class)->measure (widget,
+                                                                           orientation,
+                                                                           for_size - menubar_height,
+                                                                           minimum, natural,
+                                                                           minimum_baseline, 
natural_baseline);
 
-  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
-    ->get_preferred_width (widget, minimum_width, natural_width);
 
-  if (window->priv->menubar != NULL)
-    {
-      gint menubar_min_width, menubar_nat_width;
-      GtkBorder border = { 0 };
+          gtk_widget_get_preferred_width_for_height (window->priv->menubar, menubar_height, &menubar_min, 
&menubar_nat);
 
-      gtk_widget_get_preferred_width (window->priv->menubar, &menubar_min_width, &menubar_nat_width);
+          _gtk_window_get_shadow_width (GTK_WINDOW (widget), &border);
+          menubar_min += border.left + border.right;
+          menubar_nat += border.left + border.right;
 
-      _gtk_window_get_shadow_width (GTK_WINDOW (widget), &border);
+          *minimum = MAX (*minimum, menubar_min);
+          *natural = MAX (*natural, menubar_nat);
 
-      menubar_min_width += border.left + border.right;
-      menubar_nat_width += border.left + border.right;
-
-      *minimum_width = MAX (*minimum_width, menubar_min_width);
-      *natural_width = MAX (*natural_width, menubar_nat_width);
+        }
+      else /* VERTICAL */
+        {
+          GTK_WIDGET_CLASS (gtk_application_window_parent_class)->measure (widget,
+                                                                           orientation,
+                                                                           for_size,
+                                                                           minimum, natural,
+                                                                           minimum_baseline, 
natural_baseline);
+
+          gtk_widget_get_preferred_height_for_width (priv->menubar, for_size, &menubar_min, &menubar_nat);
+          *minimum += menubar_min;
+          *natural += menubar_nat;
+        }
     }
-}
-
-static void
-gtk_application_window_real_get_preferred_width_for_height (GtkWidget *widget,
-                                                            gint       height,
-                                                            gint      *minimum_width,
-                                                            gint      *natural_width)
-{
-  GtkApplicationWindow *window = GTK_APPLICATION_WINDOW (widget);
-  gint menubar_height;
-
-  if (window->priv->menubar != NULL)
-    gtk_widget_get_preferred_height (window->priv->menubar, &menubar_height, NULL);
   else
-    menubar_height = 0;
-
-  GTK_WIDGET_CLASS (gtk_application_window_parent_class)
-    ->get_preferred_width_for_height (widget, height - menubar_height, minimum_width, natural_width);
-
-  if (window->priv->menubar != NULL)
     {
-      gint menubar_min_width, menubar_nat_width;
-      GtkBorder border = { 0 };
-
-      gtk_widget_get_preferred_width_for_height (window->priv->menubar, menubar_height, &menubar_min_width, 
&menubar_nat_width);
-
-      _gtk_window_get_shadow_width (GTK_WINDOW (widget), &border);
-
-      menubar_min_width += border.left + border.right;
-      menubar_nat_width += border.left + border.right;
-
-      *minimum_width = MAX (*minimum_width, menubar_min_width);
-      *natural_width = MAX (*natural_width, menubar_nat_width);
+      GTK_WIDGET_CLASS (gtk_application_window_parent_class)->measure (widget,
+                                                                       orientation,
+                                                                       for_size,
+                                                                       minimum, natural,
+                                                                       minimum_baseline, natural_baseline);
     }
 }
 
@@ -841,10 +808,7 @@ gtk_application_window_class_init (GtkApplicationWindowClass *class)
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
   container_class->forall = gtk_application_window_real_forall_internal;
-  widget_class->get_preferred_height = gtk_application_window_real_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_application_window_real_get_preferred_height_for_width;
-  widget_class->get_preferred_width = gtk_application_window_real_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_application_window_real_get_preferred_width_for_height;
+  widget_class->measure = gtk_application_window_measure;
   widget_class->size_allocate = gtk_application_window_real_size_allocate;
   widget_class->realize = gtk_application_window_real_realize;
   widget_class->unrealize = gtk_application_window_real_unrealize;
diff --git a/gtk/gtkbbox.c b/gtk/gtkbbox.c
index 3d2a8ef..111a638 100644
--- a/gtk/gtkbbox.c
+++ b/gtk/gtkbbox.c
@@ -94,28 +94,13 @@ static void gtk_button_box_get_property       (GObject           *object,
                                                GParamSpec        *pspec);
 static GskRenderNode *gtk_button_box_get_render_node (GtkWidget   *widget,
                                                       GskRenderer *renderer);
-
-static void gtk_button_box_get_preferred_width            (GtkWidget *widget,
-                                                           gint      *minimum,
-                                                           gint      *natural);
-static void gtk_button_box_get_preferred_height           (GtkWidget *widget,
-                                                           gint      *minimum,
-                                                           gint      *natural);
-static void gtk_button_box_get_preferred_width_for_height (GtkWidget *widget,
-                                                           gint       height,
-                                                           gint      *minimum,
-                                                           gint      *natural);
-static void gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
-                                                           gint       width,
-                                                           gint      *minimum,
-                                                           gint      *natural);
-static void gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                                       gint       width,
-                                                                       gint      *minimum,
-                                                                       gint      *natural,
-                                                                       gint      *minimum_baseline,
-                                                                       gint      *natural_baseline);
-
+static void gtk_button_box_measure_           (GtkWidget         *widget,
+                                               GtkOrientation     orientation,
+                                               int                for_size,
+                                               int               *minimum,
+                                               int               *natural,
+                                               int               *minimum_baseline,
+                                               int               *natural_baseline);
 static void gtk_button_box_size_allocate      (GtkWidget         *widget,
                                                GtkAllocation     *allocation);
 static void gtk_button_box_remove             (GtkContainer      *container,
@@ -181,11 +166,7 @@ gtk_button_box_class_init (GtkButtonBoxClass *class)
   gobject_class->get_property = gtk_button_box_get_property;
   gobject_class->finalize = gtk_button_box_finalize;
 
-  widget_class->get_preferred_width = gtk_button_box_get_preferred_width;
-  widget_class->get_preferred_height = gtk_button_box_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_button_box_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_button_box_get_preferred_height_for_width;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_button_box_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_button_box_measure_;
   widget_class->size_allocate = gtk_button_box_size_allocate;
   widget_class->get_render_node = gtk_button_box_get_render_node;
 
@@ -808,96 +789,15 @@ gtk_button_box_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_button_box_get_preferred_width (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  GtkButtonBoxPrivate *priv = GTK_BUTTON_BOX (widget)->priv;
-  GtkCssGadget *gadget;
-
-  if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
-    gadget = gtk_box_get_gadget (GTK_BOX (widget));
-  else
-    gadget = priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_box_get_preferred_height (GtkWidget *widget,
-                                     gint      *minimum,
-                                     gint      *natural)
-{
-  GtkButtonBoxPrivate *priv = GTK_BUTTON_BOX (widget)->priv;
-  GtkCssGadget *gadget;
-
-  if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
-    gadget = gtk_box_get_gadget (GTK_BOX (widget));
-  else
-    gadget = priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_box_get_preferred_width_for_height (GtkWidget *widget,
-                                               gint       height,
-                                               gint      *minimum,
-                                               gint      *natural)
-{
-  GtkButtonBoxPrivate *priv = GTK_BUTTON_BOX (widget)->priv;
-  GtkCssGadget *gadget;
-
-  if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
-    gadget = gtk_box_get_gadget (GTK_BOX (widget));
-  else
-    gadget = priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_box_get_preferred_height_for_width (GtkWidget *widget,
-                                               gint       width,
-                                               gint      *minimum,
-                                               gint      *natural)
-{
-  GtkButtonBoxPrivate *priv = GTK_BUTTON_BOX (widget)->priv;
-  GtkCssGadget *gadget;
-
-  if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
-    gadget = gtk_box_get_gadget (GTK_BOX (widget));
-  else
-    gadget = priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                           gint       width,
-                                                           gint      *minimum,
-                                                           gint      *natural,
-                                                           gint      *minimum_baseline,
-                                                           gint      *natural_baseline)
+gtk_button_box_measure_ (GtkWidget      *widget,
+                        GtkOrientation  orientation,
+                        int             for_size,
+                        int            *minimum,
+                        int            *natural,
+                        int            *minimum_baseline,
+                        int            *natural_baseline)
 {
-  GtkButtonBoxPrivate *priv = GTK_BUTTON_BOX (widget)->priv;
+  GtkButtonBoxPrivate *priv = gtk_button_box_get_instance_private (GTK_BUTTON_BOX (widget));
   GtkCssGadget *gadget;
 
   if (priv->layout_style == GTK_BUTTONBOX_EXPAND)
@@ -906,8 +806,8 @@ gtk_button_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
     gadget = priv->gadget;
 
   gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c
index 2fba246..c5e1bc5 100644
--- a/gtk/gtkbin.c
+++ b/gtk/gtkbin.c
@@ -56,20 +56,13 @@ static void gtk_bin_forall      (GtkContainer   *container,
                                 gpointer        callback_data);
 static GType gtk_bin_child_type (GtkContainer   *container);
 
-static void               gtk_bin_get_preferred_width             (GtkWidget           *widget,
-                                                                   gint                *minimum_width,
-                                                                   gint                *natural_width);
-static void               gtk_bin_get_preferred_height            (GtkWidget           *widget,
-                                                                   gint                *minimum_height,
-                                                                   gint                *natural_height);
-static void               gtk_bin_get_preferred_width_for_height  (GtkWidget           *widget,
-                                                                   gint                 height,
-                                                                   gint                *minimum_width,
-                                                                   gint                *natural_width);
-static void               gtk_bin_get_preferred_height_for_width  (GtkWidget           *widget,
-                                                                   gint                 width,
-                                                                   gint                *minimum_height,
-                                                                   gint                *natural_height);
+static void               gtk_bin_measure                         (GtkWidget      *widget,
+                                                                   GtkOrientation  orientation,
+                                                                   int             for_size,
+                                                                   int            *minimum,
+                                                                   int            *natural,
+                                                                   int            *minimum_baseline,
+                                                                   int            *natural_baseline);
 static void               gtk_bin_size_allocate                   (GtkWidget           *widget,
                                                                    GtkAllocation       *allocation);
 
@@ -81,10 +74,7 @@ gtk_bin_class_init (GtkBinClass *class)
   GtkWidgetClass *widget_class = (GtkWidgetClass*) class;
   GtkContainerClass *container_class = (GtkContainerClass*) class;
 
-  widget_class->get_preferred_width = gtk_bin_get_preferred_width;
-  widget_class->get_preferred_height = gtk_bin_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_bin_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_bin_get_preferred_height_for_width;
+  widget_class->measure = gtk_bin_measure;
   widget_class->size_allocate = gtk_bin_size_allocate;
 
   container_class->add = gtk_bin_add;
@@ -172,90 +162,28 @@ gtk_bin_forall (GtkContainer *container,
 }
 
 static void
-gtk_bin_get_preferred_width (GtkWidget *widget,
-                             gint      *minimum_width,
-                             gint      *natural_width)
+gtk_bin_measure (GtkWidget *widget,
+                 GtkOrientation  orientation,
+                 int             for_size,
+                 int            *minimum,
+                 int            *natural,
+                 int            *minimum_baseline,
+                 int            *natural_baseline)
 {
-  GtkBin *bin = GTK_BIN (widget);
-  GtkBinPrivate *priv = bin->priv;
-
-  *minimum_width = 0;
-  *natural_width = 0;
+  GtkBinPrivate *priv = gtk_bin_get_instance_private (GTK_BIN (widget));
 
-  if (priv->child && gtk_widget_get_visible (priv->child))
+  if (priv->child != NULL && gtk_widget_get_visible (priv->child))
     {
-      gint child_min, child_nat;
-      gtk_widget_get_preferred_width (priv->child,
-                                      &child_min, &child_nat);
-      *minimum_width = child_min;
-      *natural_width = child_nat;
+      gtk_widget_measure (priv->child,
+                          orientation,
+                          for_size,
+                          minimum, natural,
+                          minimum_baseline, natural_baseline);
     }
-}
-
-static void
-gtk_bin_get_preferred_height (GtkWidget *widget,
-                              gint      *minimum_height,
-                              gint      *natural_height)
-{
-  GtkBin *bin = GTK_BIN (widget);
-  GtkBinPrivate *priv = bin->priv;
-
-  *minimum_height = 0;
-  *natural_height = 0;
-
-  if (priv->child && gtk_widget_get_visible (priv->child))
-    {
-      gint child_min, child_nat;
-      gtk_widget_get_preferred_height (priv->child,
-                                       &child_min, &child_nat);
-      *minimum_height = child_min;
-      *natural_height = child_nat;
-    }
-}
-
-static void 
-gtk_bin_get_preferred_width_for_height (GtkWidget *widget,
-                                        gint       height,
-                                        gint      *minimum_width,
-                                        gint      *natural_width)
-{
-  GtkBin *bin = GTK_BIN (widget);
-  GtkBinPrivate *priv = bin->priv;
-
-  *minimum_width = 0;
-  *natural_width = 0;
-
-  if (priv->child && gtk_widget_get_visible (priv->child))
-    {
-      gint child_min, child_nat;
-      gtk_widget_get_preferred_width_for_height (priv->child, height,
-                                                 &child_min, &child_nat);
-
-      *minimum_width = child_min;
-      *natural_width = child_nat;
-    }
-}
-
-static void
-gtk_bin_get_preferred_height_for_width  (GtkWidget *widget,
-                                         gint       width,
-                                         gint      *minimum_height,
-                                         gint      *natural_height)
-{
-  GtkBin *bin = GTK_BIN (widget);
-  GtkBinPrivate *priv = bin->priv;
-
-  *minimum_height = 0;
-  *natural_height = 0;
-
-  if (priv->child && gtk_widget_get_visible (priv->child))
+  else
     {
-      gint child_min, child_nat;
-      gtk_widget_get_preferred_height_for_width (priv->child, width,
-                                                 &child_min, &child_nat);
-
-      *minimum_height = child_min;
-      *natural_height = child_nat;
+      *minimum = 0;
+      *natural = 0;
     }
 }
 
diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c
index a3f0c42..91a27e5 100644
--- a/gtk/gtkbox.c
+++ b/gtk/gtkbox.c
@@ -195,29 +195,13 @@ static GType gtk_box_child_type        (GtkContainer   *container);
 static GtkWidgetPath * gtk_box_get_path_for_child
                                        (GtkContainer   *container,
                                         GtkWidget      *child);
-
-
-static void               gtk_box_get_preferred_width            (GtkWidget           *widget,
-                                                                  gint                *minimum_size,
-                                                                  gint                *natural_size);
-static void               gtk_box_get_preferred_height           (GtkWidget           *widget,
-                                                                  gint                *minimum_size,
-                                                                  gint                *natural_size);
-static void               gtk_box_get_preferred_width_for_height (GtkWidget           *widget,
-                                                                  gint                 height,
-                                                                  gint                *minimum_width,
-                                                                  gint                *natural_width);
-static void               gtk_box_get_preferred_height_for_width (GtkWidget           *widget,
-                                                                  gint                 width,
-                                                                  gint                *minimum_height,
-                                                                  gint                *natural_height);
-static void  gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget           *widget,
-                                                                 gint                 width,
-                                                                 gint                *minimum_height,
-                                                                 gint                *natural_height,
-                                                                 gint                *minimum_baseline,
-                                                                 gint                *natural_baseline);
-
+static void gtk_box_measure (GtkWidget      *widget,
+                             GtkOrientation  orientation,
+                             int             for_size,
+                             int            *minimum,
+                             int            *natural,
+                             int            *minimum_baseline,
+                             int            *natural_baseline);
 static GskRenderNode *  gtk_box_get_render_node                 (GtkWidget            *widget,
                                                                  GskRenderer          *renderer);
 
@@ -252,11 +236,7 @@ gtk_box_class_init (GtkBoxClass *class)
 
   widget_class->get_render_node                = gtk_box_get_render_node;
   widget_class->size_allocate                  = gtk_box_size_allocate;
-  widget_class->get_preferred_width            = gtk_box_get_preferred_width;
-  widget_class->get_preferred_height           = gtk_box_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_box_get_preferred_height_for_width;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_box_get_preferred_height_and_baseline_for_width;
-  widget_class->get_preferred_width_for_height = gtk_box_get_preferred_width_for_height;
+  widget_class->measure                        = gtk_box_measure;
   widget_class->direction_changed              = gtk_box_direction_changed;
 
   container_class->add = gtk_box_add;
@@ -1660,27 +1640,19 @@ gtk_box_get_size (GtkWidget      *widget,
 }
 
 static void
-gtk_box_get_preferred_width (GtkWidget *widget,
-                             gint      *minimum,
-                             gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_box_get_preferred_height (GtkWidget *widget,
-                              gint      *minimum,
-                              gint      *natural)
+gtk_box_measure (GtkWidget      *widget,
+                 GtkOrientation  orientation,
+                 int             for_size,
+                 int            *minimum,
+                 int            *natural,
+                 int            *minimum_baseline,
+                 int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -1963,34 +1935,6 @@ gtk_box_compute_size_for_orientation (GtkBox *box,
 }
 
 static void
-gtk_box_get_preferred_width_for_height (GtkWidget *widget,
-                                        gint       height,
-                                        gint      *minimum,
-                                        gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                    gint       width,
-                                                    gint      *minimum,
-                                                    gint      *natural,
-                                                    gint      *minimum_baseline,
-                                                    gint      *natural_baseline)
-{
-  gtk_css_gadget_get_preferred_size (GTK_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     minimum_baseline, natural_baseline);
-}
-
-static void
 gtk_box_get_content_size (GtkCssGadget   *gadget,
                           GtkOrientation  orientation,
                           gint            for_size,
@@ -2022,15 +1966,6 @@ gtk_box_get_content_size (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_box_get_preferred_height_for_width (GtkWidget *widget,
-                                        gint       width,
-                                        gint      *minimum_height,
-                                        gint      *natural_height)
-{
-  gtk_box_get_preferred_height_and_baseline_for_width (widget, width, minimum_height, natural_height, NULL, 
NULL);
-}
-
-static void
 gtk_box_init (GtkBox *box)
 {
   GtkBoxPrivate *private;
diff --git a/gtk/gtkboxgadget.c b/gtk/gtkboxgadget.c
index 10bc0df..fb230c0 100644
--- a/gtk/gtkboxgadget.c
+++ b/gtk/gtkboxgadget.c
@@ -126,11 +126,11 @@ gtk_box_gadget_measure_child (GObject        *child,
 {
   if (GTK_IS_WIDGET (child))
     {
-      _gtk_widget_get_preferred_size_for_size (GTK_WIDGET (child),
-                                               orientation,
-                                               for_size,
-                                               minimum, natural,
-                                               minimum_baseline, natural_baseline);
+      gtk_widget_measure (GTK_WIDGET (child),
+                          orientation,
+                          for_size,
+                          minimum, natural,
+                          minimum_baseline, natural_baseline);
     }
   else
     {
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 45c638b..543ed4e 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -149,27 +149,13 @@ static void gtk_button_do_release      (GtkButton             *button,
 
 static void gtk_button_actionable_iface_init     (GtkActionableInterface *iface);
 
-static void gtk_button_get_preferred_width             (GtkWidget           *widget,
-                                                        gint                *minimum_size,
-                                                        gint                *natural_size);
-static void gtk_button_get_preferred_height            (GtkWidget           *widget,
-                                                        gint                *minimum_size,
-                                                        gint                *natural_size);
-static void gtk_button_get_preferred_width_for_height  (GtkWidget           *widget,
-                                                        gint                 for_size,
-                                                        gint                *minimum_size,
-                                                        gint                *natural_size);
-static void gtk_button_get_preferred_height_for_width  (GtkWidget           *widget,
-                                                        gint                 for_size,
-                                                        gint                *minimum_size,
-                                                        gint                *natural_size);
-static void gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                                   gint       width,
-                                                                   gint      *minimum_size,
-                                                                   gint      *natural_size,
-                                                                   gint      *minimum_baseline,
-                                                                   gint      *natural_baseline);
-
+static void gtk_button_measure_ (GtkWidget      *widget,
+                                 GtkOrientation  orientation,
+                                 int             for_size,
+                                 int            *minimum,
+                                 int            *natural,
+                                 int            *minimum_baseline,
+                                 int            *natural_baseline);
 static void     gtk_button_measure  (GtkCssGadget        *gadget,
                                      GtkOrientation       orientation,
                                      int                  for_size,
@@ -231,11 +217,7 @@ gtk_button_class_init (GtkButtonClass *klass)
   gobject_class->set_property = gtk_button_set_property;
   gobject_class->get_property = gtk_button_get_property;
 
-  widget_class->get_preferred_width = gtk_button_get_preferred_width;
-  widget_class->get_preferred_height = gtk_button_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_button_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_button_get_preferred_height_for_width;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_button_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_button_measure_;
   widget_class->screen_changed = gtk_button_screen_changed;
   widget_class->realize = gtk_button_realize;
   widget_class->unrealize = gtk_button_unrealize;
@@ -1109,11 +1091,11 @@ gtk_button_measure (GtkCssGadget   *gadget,
 
   if (child && gtk_widget_get_visible (child))
     {
-       _gtk_widget_get_preferred_size_for_size (child,
-                                                orientation,
-                                                for_size,
-                                                minimum, natural,
-                                                minimum_baseline, natural_baseline);
+       gtk_widget_measure (child,
+                           orientation,
+                           for_size,
+                           minimum, natural,
+                           minimum_baseline, natural_baseline);
     }
   else
     {
@@ -1127,67 +1109,18 @@ gtk_button_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_button_get_preferred_width (GtkWidget *widget,
-                                gint      *minimum_size,
-                                gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_get_preferred_height (GtkWidget *widget,
-                                 gint      *minimum_size,
-                                 gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_get_preferred_width_for_height (GtkWidget *widget,
-                                           gint       for_size,
-                                           gint      *minimum_size,
-                                           gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     for_size,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_get_preferred_height_for_width (GtkWidget *widget,
-                                           gint       for_size,
-                                           gint      *minimum_size,
-                                           gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     for_size,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                       gint       for_size,
-                                                       gint      *minimum_size,
-                                                       gint      *natural_size,
-                                                       gint      *minimum_baseline,
-                                                       gint      *natural_baseline)
+gtk_button_measure_ (GtkWidget      *widget,
+                     GtkOrientation  orientation,
+                     int             for_size,
+                     int            *minimum,
+                     int            *natural,
+                     int            *minimum_baseline,
+                     int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
+                                     orientation,
                                      for_size,
-                                     minimum_size, natural_size,
+                                     minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
 
diff --git a/gtk/gtkcalendar.c b/gtk/gtkcalendar.c
index 7488903..24f34a3 100644
--- a/gtk/gtkcalendar.c
+++ b/gtk/gtkcalendar.c
@@ -261,12 +261,13 @@ static void     gtk_calendar_realize        (GtkWidget        *widget);
 static void     gtk_calendar_unrealize      (GtkWidget        *widget);
 static void     gtk_calendar_map            (GtkWidget        *widget);
 static void     gtk_calendar_unmap          (GtkWidget        *widget);
-static void     gtk_calendar_get_preferred_width  (GtkWidget   *widget,
-                                                   gint        *minimum,
-                                                   gint        *natural);
-static void     gtk_calendar_get_preferred_height (GtkWidget   *widget,
-                                                   gint        *minimum,
-                                                   gint        *natural);
+static void     gtk_calendar_measure        (GtkWidget        *widget,
+                                             GtkOrientation  orientation,
+                                             int             for_size,
+                                             int            *minimum,
+                                             int            *natural,
+                                             int            *minimum_baseline,
+                                             int            *natural_baseline);
 static void     gtk_calendar_size_allocate  (GtkWidget        *widget,
                                              GtkAllocation    *allocation);
 static gboolean gtk_calendar_draw           (GtkWidget        *widget,
@@ -365,8 +366,7 @@ gtk_calendar_class_init (GtkCalendarClass *class)
   widget_class->map = gtk_calendar_map;
   widget_class->unmap = gtk_calendar_unmap;
   widget_class->draw = gtk_calendar_draw;
-  widget_class->get_preferred_width = gtk_calendar_get_preferred_width;
-  widget_class->get_preferred_height = gtk_calendar_get_preferred_height;
+  widget_class->measure = gtk_calendar_measure;
   widget_class->size_allocate = gtk_calendar_size_allocate;
   widget_class->button_press_event = gtk_calendar_button_press;
   widget_class->button_release_event = gtk_calendar_button_release;
@@ -2035,27 +2035,22 @@ gtk_calendar_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_calendar_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
+gtk_calendar_measure (GtkWidget        *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
 {
   GtkRequisition requisition;
 
   gtk_calendar_size_request (widget, &requisition);
 
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_calendar_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_calendar_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    *minimum = *natural = requisition.width;
+  else /* VERTICAL */
+    *minimum = *natural = requisition.height;
 }
 
 static void
diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c
index 80c7f56..2ae9e93 100644
--- a/gtk/gtkcellview.c
+++ b/gtk/gtkcellview.c
@@ -97,21 +97,13 @@ static void       gtk_cell_view_buildable_custom_tag_end       (GtkBuildable
                                                                gpointer              *data);
 
 static GtkSizeRequestMode gtk_cell_view_get_request_mode       (GtkWidget             *widget);
-static void       gtk_cell_view_get_preferred_width            (GtkWidget             *widget,
-                                                               gint                  *minimum_size,
-                                                               gint                  *natural_size);
-static void       gtk_cell_view_get_preferred_height           (GtkWidget             *widget,
-                                                               gint                  *minimum_size,
-                                                               gint                  *natural_size);
-static void       gtk_cell_view_get_preferred_width_for_height (GtkWidget             *widget,
-                                                               gint                   avail_size,
-                                                               gint                  *minimum_size,
-                                                               gint                  *natural_size);
-static void       gtk_cell_view_get_preferred_height_for_width (GtkWidget             *widget,
-                                                               gint                   avail_size,
-                                                               gint                  *minimum_size,
-                                                               gint                  *natural_size);
-
+static void gtk_cell_view_measure_ (GtkWidget      *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 static void       context_size_changed_cb                      (GtkCellAreaContext   *context,
                                                                GParamSpec           *pspec,
                                                                GtkWidget            *view);
@@ -202,10 +194,7 @@ gtk_cell_view_class_init (GtkCellViewClass *klass)
   widget_class->draw                           = gtk_cell_view_draw;
   widget_class->size_allocate                  = gtk_cell_view_size_allocate;
   widget_class->get_request_mode               = gtk_cell_view_get_request_mode;
-  widget_class->get_preferred_width            = gtk_cell_view_get_preferred_width;
-  widget_class->get_preferred_height           = gtk_cell_view_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_cell_view_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_cell_view_get_preferred_height_for_width;
+  widget_class->measure                        = gtk_cell_view_measure_;
 
   /* properties */
   g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation");
@@ -681,54 +670,21 @@ gtk_cell_view_get_request_mode (GtkWidget *widget)
   return gtk_cell_area_get_request_mode (priv->area);
 }
 
-static void
-gtk_cell_view_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_CELL_VIEW (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_cell_view_get_preferred_width_for_height (GtkWidget *widget,
-                                              gint       height,
-                                              gint      *minimum,
-                                              gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_CELL_VIEW (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
 
 static void
-gtk_cell_view_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_CELL_VIEW (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_cell_view_get_preferred_height_for_width (GtkWidget *widget,
-                                              gint       width,
-                                              gint      *minimum,
-                                              gint      *natural)
+gtk_cell_view_measure_ (GtkWidget      *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_CELL_VIEW (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
diff --git a/gtk/gtkcheckbutton.c b/gtk/gtkcheckbutton.c
index f6f8d37..646ea6a 100644
--- a/gtk/gtkcheckbutton.c
+++ b/gtk/gtkcheckbutton.c
@@ -78,26 +78,6 @@
  */
 
 
-static void gtk_check_button_get_preferred_width                         (GtkWidget          *widget,
-                                                                          gint               *minimum,
-                                                                          gint               *natural);
-static void gtk_check_button_get_preferred_width_for_height              (GtkWidget          *widget,
-                                                                          gint                height,
-                                                                          gint               *minimum,
-                                                                          gint               *natural);
-static void gtk_check_button_get_preferred_height                        (GtkWidget          *widget,
-                                                                          gint               *minimum,
-                                                                          gint               *natural);
-static void gtk_check_button_get_preferred_height_for_width              (GtkWidget          *widget,
-                                                                          gint                width,
-                                                                          gint               *minimum,
-                                                                          gint               *natural);
-static void gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget          *widget,
-                                                                         gint                width,
-                                                                         gint               *minimum,
-                                                                         gint               *natural,
-                                                                         gint               
*minimum_baseline,
-                                                                         gint               
*natural_baseline);
 static void gtk_check_button_size_allocate       (GtkWidget           *widget,
                                                  GtkAllocation       *allocation);
 static GskRenderNode *gtk_check_button_get_render_node (GtkWidget   *widget,
@@ -196,6 +176,30 @@ gtk_check_button_remove (GtkContainer *container,
 }
 
 static void
+gtk_check_button_measure (GtkWidget      *widget,
+                          GtkOrientation  orientation,
+                          int             for_size,
+                          int            *minimum,
+                          int            *natural,
+                          int            *minimum_baseline,
+                          int            *natural_baseline)
+{
+  GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
+  GtkCssGadget *gadget;
+
+  if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
+    gadget = priv->gadget;
+  else
+    gadget = GTK_BUTTON (widget)->priv->gadget;
+
+  gtk_css_gadget_get_preferred_size (gadget,
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
+}
+
+static void
 gtk_check_button_class_init (GtkCheckButtonClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
@@ -204,11 +208,7 @@ gtk_check_button_class_init (GtkCheckButtonClass *class)
 
   object_class->finalize = gtk_check_button_finalize;
 
-  widget_class->get_preferred_width = gtk_check_button_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_check_button_get_preferred_width_for_height;
-  widget_class->get_preferred_height = gtk_check_button_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_check_button_get_preferred_height_for_width;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_check_button_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_check_button_measure;
   widget_class->size_allocate = gtk_check_button_size_allocate;
   widget_class->get_render_node = gtk_check_button_get_render_node;
   widget_class->state_flags_changed = gtk_check_button_state_flags_changed;
@@ -338,111 +338,6 @@ gtk_check_button_new_with_mnemonic (const gchar *label)
 }
 
 static void
-gtk_check_button_get_preferred_width_for_height (GtkWidget *widget,
-                                                 gint       height,
-                                                 gint      *minimum,
-                                                 gint      *natural)
-{
-  GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
-  GtkCssGadget *gadget;
-
-  if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
-    gadget = priv->gadget;
-  else
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_check_button_get_preferred_width (GtkWidget *widget,
-                                      gint      *minimum,
-                                      gint      *natural)
-{
-  GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
-  GtkCssGadget *gadget;
-
-  if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
-    gadget = priv->gadget;
-  else
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_check_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                             gint       width,
-                                                             gint      *minimum,
-                                                             gint      *natural,
-                                                             gint      *minimum_baseline,
-                                                             gint      *natural_baseline)
-{
-  GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
-  GtkCssGadget *gadget;
-
-  if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
-    gadget = priv->gadget;
-  else
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     minimum_baseline, natural_baseline);
-}
-
-static void
-gtk_check_button_get_preferred_height_for_width (GtkWidget *widget,
-                                                 gint       width,
-                                                 gint      *minimum,
-                                                 gint      *natural)
-{
-  GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
-  GtkCssGadget *gadget;
-
-  if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
-    gadget = priv->gadget;
-  else
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_check_button_get_preferred_height (GtkWidget *widget,
-                                       gint      *minimum,
-                                       gint      *natural)
-{
-  GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
-  GtkCssGadget *gadget;
-
-  if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
-    gadget = priv->gadget;
-  else
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
 gtk_check_button_size_allocate (GtkWidget     *widget,
                                GtkAllocation *allocation)
 {
diff --git a/gtk/gtkcolorswatch.c b/gtk/gtkcolorswatch.c
index ec5dbec..971503a 100644
--- a/gtk/gtkcolorswatch.c
+++ b/gtk/gtkcolorswatch.c
@@ -523,28 +523,22 @@ swatch_size_allocate (GtkWidget     *widget,
 }
 
 static void
-swatch_get_preferred_width (GtkWidget *widget,
-                            gint      *minimum,
-                            gint      *natural)
+gtk_color_swatch_measure_ (GtkWidget *widget,
+                          GtkOrientation  orientation,
+                          int             for_size,
+                          int            *minimum,
+                          int            *natural,
+                          int            *minimum_baseline,
+                          int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_COLOR_SWATCH (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
-static void
-swatch_get_preferred_height (GtkWidget *widget,
-                             gint      *minimum,
-                             gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_COLOR_SWATCH (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
+
 
 static gboolean
 swatch_popup_menu (GtkWidget *widget)
@@ -674,8 +668,7 @@ gtk_color_swatch_class_init (GtkColorSwatchClass *class)
   object_class->finalize = swatch_finalize;
   object_class->dispose = swatch_dispose;
 
-  widget_class->get_preferred_width = swatch_get_preferred_width;
-  widget_class->get_preferred_height = swatch_get_preferred_height;
+  widget_class->measure = gtk_color_swatch_measure_;
   widget_class->draw = swatch_draw;
   widget_class->drag_begin = swatch_drag_begin;
   widget_class->drag_data_get = swatch_drag_data_get;
diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c
index 864819f..2a007a3 100644
--- a/gtk/gtkcombobox.c
+++ b/gtk/gtkcombobox.c
@@ -468,11 +468,11 @@ gtk_combo_box_measure (GtkCssGadget   *gadget,
   GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
   GtkComboBoxPrivate *priv = combo_box->priv;
 
-  _gtk_widget_get_preferred_size_for_size (priv->box,
-                                           orientation,
-                                           size,
-                                           minimum, natural,
-                                           minimum_baseline, natural_baseline);
+  gtk_widget_measure (priv->box,
+                      orientation,
+                      size,
+                      minimum, natural,
+                      minimum_baseline, natural_baseline);
 }
 
 static void
@@ -525,72 +525,25 @@ gtk_combo_box_allocate (GtkCssGadget        *gadget,
 }
 
 static void
-gtk_combo_box_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum_size,
-                                   gint      *natural_size)
+gtk_combo_box_measure_ (GtkWidget      *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   gint dummy;
 
   /* https://bugzilla.gnome.org/show_bug.cgi?id=729496 */
-  if (natural_size == NULL)
-    natural_size = &dummy;
-
-  gtk_css_gadget_get_preferred_size (GTK_COMBO_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_combo_box_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum_size,
-                                    gint      *natural_size)
-{
-  gint min_width;
+  if (natural == NULL)
+    natural = &dummy;
 
-  /* Combo box is height-for-width only
-   * (so we always just reserve enough height for the minimum width)
-   */
-  gtk_css_gadget_get_preferred_size (GTK_COMBO_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     &min_width, NULL,
-                                     NULL, NULL);
-  gtk_css_gadget_get_preferred_size (GTK_COMBO_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     min_width,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_combo_box_get_preferred_width_for_height (GtkWidget *widget,
-                                              gint       avail_size,
-                                              gint      *minimum_size,
-                                              gint      *natural_size)
-{
-  /* Combo box is height-for-width only
-   * (so we assume we always reserved enough height for the minimum width)
-   */
-  gtk_css_gadget_get_preferred_size (GTK_COMBO_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     avail_size,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_combo_box_get_preferred_height_for_width (GtkWidget *widget,
-                                              gint       avail_size,
-                                              gint      *minimum_size,
-                                              gint      *natural_size)
-{
   gtk_css_gadget_get_preferred_size (GTK_COMBO_BOX (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     avail_size,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -667,10 +620,7 @@ gtk_combo_box_class_init (GtkComboBoxClass *klass)
   widget_class->mnemonic_activate = gtk_combo_box_mnemonic_activate;
   widget_class->grab_focus = gtk_combo_box_grab_focus;
   widget_class->style_updated = gtk_combo_box_style_updated;
-  widget_class->get_preferred_width = gtk_combo_box_get_preferred_width;
-  widget_class->get_preferred_height = gtk_combo_box_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_combo_box_get_preferred_height_for_width;
-  widget_class->get_preferred_width_for_height = gtk_combo_box_get_preferred_width_for_height;
+  widget_class->measure = gtk_combo_box_measure_;
   widget_class->destroy = gtk_combo_box_destroy;
   widget_class->compute_expand = gtk_combo_box_compute_expand;
 
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index d0b485d..2f91597 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -412,18 +412,6 @@ static void   gtk_entry_realize              (GtkWidget        *widget);
 static void   gtk_entry_unrealize            (GtkWidget        *widget);
 static void   gtk_entry_map                  (GtkWidget        *widget);
 static void   gtk_entry_unmap                (GtkWidget        *widget);
-static void   gtk_entry_get_preferred_width  (GtkWidget        *widget,
-                                              gint             *minimum,
-                                              gint             *natural);
-static void   gtk_entry_get_preferred_height (GtkWidget        *widget,
-                                              gint             *minimum,
-                                              gint             *natural);
-static void  gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                                    gint       width,
-                                                                    gint      *minimum_height,
-                                                                    gint      *natural_height,
-                                                                    gint      *minimum_baseline,
-                                                                    gint      *natural_baseline);
 static void   gtk_entry_size_allocate        (GtkWidget        *widget,
                                              GtkAllocation    *allocation);
 static gint   gtk_entry_draw                 (GtkWidget        *widget,
@@ -693,6 +681,14 @@ static void         buffer_connect_signals             (GtkEntry       *entry);
 static void         buffer_disconnect_signals          (GtkEntry       *entry);
 static GtkEntryBuffer *get_buffer                      (GtkEntry       *entry);
 
+static void     gtk_entry_measure_  (GtkWidget          *gadget,
+                                    GtkOrientation       orientation,
+                                    int                  for_size,
+                                    int                 *minimum,
+                                    int                 *natural,
+                                    int                 *minimum_baseline,
+                                    int                 *natural_baseline);
+
 static void     gtk_entry_measure  (GtkCssGadget        *gadget,
                                     GtkOrientation       orientation,
                                     int                  for_size,
@@ -763,9 +759,7 @@ gtk_entry_class_init (GtkEntryClass *class)
   widget_class->unmap = gtk_entry_unmap;
   widget_class->realize = gtk_entry_realize;
   widget_class->unrealize = gtk_entry_unrealize;
-  widget_class->get_preferred_width = gtk_entry_get_preferred_width;
-  widget_class->get_preferred_height = gtk_entry_get_preferred_height;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_entry_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_entry_measure_;
   widget_class->size_allocate = gtk_entry_size_allocate;
   widget_class->draw = gtk_entry_draw;
   widget_class->enter_notify_event = gtk_entry_enter_notify;
@@ -3180,40 +3174,17 @@ gtk_entry_unrealize (GtkWidget *widget)
 }
 
 static void
-gtk_entry_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_entry_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_entry_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                      gint       width,
-                                                      gint      *minimum,
-                                                      gint      *natural,
-                                                      gint      *minimum_baseline,
-                                                      gint      *natural_baseline)
+gtk_entry_measure_ (GtkWidget      *widget,
+                    GtkOrientation  orientation,
+                    int             for_size,
+                    int             *minimum,
+                    int             *natural,
+                    int             *minimum_baseline,
+                    int             *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_ENTRY (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
diff --git a/gtk/gtkeventbox.c b/gtk/gtkeventbox.c
index 24e11cd..99f5b5f 100644
--- a/gtk/gtkeventbox.c
+++ b/gtk/gtkeventbox.c
@@ -59,18 +59,6 @@ static void     gtk_event_box_realize       (GtkWidget        *widget);
 static void     gtk_event_box_unrealize     (GtkWidget        *widget);
 static void     gtk_event_box_map           (GtkWidget        *widget);
 static void     gtk_event_box_unmap         (GtkWidget        *widget);
-static void     gtk_event_box_get_preferred_width  (GtkWidget *widget,
-                                                    gint      *minimum,
-                                                    gint      *natural);
-static void     gtk_event_box_get_preferred_height (GtkWidget *widget,
-                                                    gint      *minimum,
-                                                    gint      *natural);
-static void     gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                                          gint       width,
-                                                                          gint      *minimum,
-                                                                          gint      *natural,
-                                                                          gint      *minimum_baseline,
-                                                                          gint      *natural_baseline);
 static void     gtk_event_box_size_allocate (GtkWidget        *widget,
                                              GtkAllocation    *allocation);
 static gboolean gtk_event_box_draw          (GtkWidget        *widget,
@@ -99,9 +87,6 @@ gtk_event_box_class_init (GtkEventBoxClass *class)
   widget_class->unrealize = gtk_event_box_unrealize;
   widget_class->map = gtk_event_box_map;
   widget_class->unmap = gtk_event_box_unmap;
-  widget_class->get_preferred_width = gtk_event_box_get_preferred_width;
-  widget_class->get_preferred_height = gtk_event_box_get_preferred_height;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_event_box_get_preferred_height_and_baseline_for_width;
   widget_class->size_allocate = gtk_event_box_size_allocate;
   widget_class->draw = gtk_event_box_draw;
 
@@ -481,62 +466,6 @@ gtk_event_box_unmap (GtkWidget *widget)
 }
 
 static void
-gtk_event_box_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkBin *bin = GTK_BIN (widget);
-  GtkWidget *child;
-
-  *minimum = 0;
-  *natural = 0;
-
-  child = gtk_bin_get_child (bin);
-  if (child && gtk_widget_get_visible (child))
-    gtk_widget_get_preferred_width (child, minimum, natural);
-}
-
-static void
-gtk_event_box_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                          gint       width,
-                                                          gint      *minimum,
-                                                          gint      *natural,
-                                                          gint      *minimum_baseline,
-                                                          gint      *natural_baseline)
-{
-  GtkBin *bin = GTK_BIN (widget);
-  GtkWidget *child;
-
-  *minimum = 0;
-  *natural = 0;
-
-  if (minimum_baseline)
-    *minimum_baseline = -1;
-
-  if (natural_baseline)
-    *natural_baseline = -1;
-
-  child = gtk_bin_get_child (bin);
-  if (child && gtk_widget_get_visible (child))
-    gtk_widget_get_preferred_height_and_baseline_for_width (child,
-                                                           width,
-                                                           minimum,
-                                                           natural,
-                                                           minimum_baseline,
-                                                           natural_baseline);
-}
-
-static void
-gtk_event_box_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  gtk_event_box_get_preferred_height_and_baseline_for_width (widget, -1,
-                                                            minimum, natural,
-                                                            NULL, NULL);
-}
-
-static void
 gtk_event_box_size_allocate (GtkWidget     *widget,
                              GtkAllocation *allocation)
 {
diff --git a/gtk/gtkexpander.c b/gtk/gtkexpander.c
index 8d44c01..dcbbb10 100644
--- a/gtk/gtkexpander.c
+++ b/gtk/gtkexpander.c
@@ -220,20 +220,13 @@ static void gtk_expander_buildable_add_child      (GtkBuildable *buildable,
 
 
 /* GtkWidget      */
-static void  gtk_expander_get_preferred_width             (GtkWidget           *widget,
-                                                           gint                *minimum_size,
-                                                           gint                *natural_size);
-static void  gtk_expander_get_preferred_height            (GtkWidget           *widget,
-                                                           gint                *minimum_size,
-                                                           gint                *natural_size);
-static void  gtk_expander_get_preferred_height_for_width  (GtkWidget           *layout,
-                                                           gint                 width,
-                                                           gint                *minimum_height,
-                                                           gint                *natural_height);
-static void  gtk_expander_get_preferred_width_for_height  (GtkWidget           *layout,
-                                                           gint                 width,
-                                                           gint                *minimum_height,
-                                                           gint                *natural_height);
+static void gtk_expander_measure (GtkWidget      *widget,
+                                  GtkOrientation  orientation,
+                                  int             for_size,
+                                  int            *minimum,
+                                  int            *natural,
+                                  int            *minimum_baseline,
+                                  int            *natural_baseline);
 static void gtk_expander_state_flags_changed (GtkWidget        *widget,
                                               GtkStateFlags     previous_state);
 static void gtk_expander_direction_changed   (GtkWidget        *widget,
@@ -277,10 +270,7 @@ gtk_expander_class_init (GtkExpanderClass *klass)
   widget_class->focus                = gtk_expander_focus;
   widget_class->drag_motion          = gtk_expander_drag_motion;
   widget_class->drag_leave           = gtk_expander_drag_leave;
-  widget_class->get_preferred_width            = gtk_expander_get_preferred_width;
-  widget_class->get_preferred_height           = gtk_expander_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_expander_get_preferred_height_for_width;
-  widget_class->get_preferred_width_for_height = gtk_expander_get_preferred_width_for_height;
+  widget_class->measure              = gtk_expander_measure;
   widget_class->state_flags_changed  = gtk_expander_state_flags_changed;
   widget_class->direction_changed  = gtk_expander_direction_changed;
 
@@ -1119,53 +1109,19 @@ gtk_expander_activate (GtkExpander *expander)
 }
 
 static void
-gtk_expander_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum_size,
-                                  gint      *natural_size)
+gtk_expander_measure (GtkWidget      *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_EXPANDER (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_expander_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum_size,
-                                   gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_EXPANDER (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_expander_get_preferred_width_for_height (GtkWidget *widget,
-                                             gint       height,
-                                             gint      *minimum_size,
-                                             gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_EXPANDER (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_expander_get_preferred_height_for_width (GtkWidget *widget,
-                                             gint       width,
-                                             gint      *minimum_size,
-                                             gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_EXPANDER (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
 }
 
 /**
diff --git a/gtk/gtkfixed.c b/gtk/gtkfixed.c
index 9e6b681..2e57c66 100644
--- a/gtk/gtkfixed.c
+++ b/gtk/gtkfixed.c
@@ -86,12 +86,15 @@ enum {
 };
 
 static void gtk_fixed_realize       (GtkWidget        *widget);
-static void gtk_fixed_get_preferred_width  (GtkWidget *widget,
-                                            gint      *minimum,
-                                            gint      *natural);
-static void gtk_fixed_get_preferred_height (GtkWidget *widget,
-                                            gint      *minimum,
-                                            gint      *natural);
+static void gtk_fixed_measure (GtkWidget      *widget,
+                               GtkOrientation  orientation,
+                               int             for_size,
+                               int            *minimum,
+                               int            *natural,
+                               int            *minimum_baseline,
+                               int            *natural_baseline);
+
+
 static void gtk_fixed_size_allocate (GtkWidget        *widget,
                                      GtkAllocation    *allocation);
 static gboolean gtk_fixed_draw      (GtkWidget        *widget,
@@ -129,8 +132,7 @@ gtk_fixed_class_init (GtkFixedClass *class)
   container_class = (GtkContainerClass*) class;
 
   widget_class->realize = gtk_fixed_realize;
-  widget_class->get_preferred_width = gtk_fixed_get_preferred_width;
-  widget_class->get_preferred_height = gtk_fixed_get_preferred_height;
+  widget_class->measure = gtk_fixed_measure;
   widget_class->size_allocate = gtk_fixed_size_allocate;
   widget_class->draw = gtk_fixed_draw;
 
@@ -368,9 +370,13 @@ gtk_fixed_realize (GtkWidget *widget)
 }
 
 static void
-gtk_fixed_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
+gtk_fixed_measure (GtkWidget      *widget,
+                   GtkOrientation  orientation,
+                   int             for_size,
+                   int            *minimum,
+                   int            *natural,
+                   int            *minimum_baseline,
+                   int            *natural_baseline)
 {
   GtkFixed *fixed = GTK_FIXED (widget);
   GtkFixedPrivate *priv = fixed->priv;
@@ -388,38 +394,18 @@ gtk_fixed_get_preferred_width (GtkWidget *widget,
       if (!gtk_widget_get_visible (child->widget))
         continue;
 
-      gtk_widget_get_preferred_width (child->widget, &child_min, &child_nat);
-
-      *minimum = MAX (*minimum, child->x + child_min);
-      *natural = MAX (*natural, child->x + child_nat);
-    }
-}
-
-static void
-gtk_fixed_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
-{
-  GtkFixed *fixed = GTK_FIXED (widget);
-  GtkFixedPrivate *priv = fixed->priv;
-  GtkFixedChild *child;
-  GList *children;
-  gint child_min, child_nat;
+      gtk_widget_measure (child->widget, orientation, -1, &child_min, &child_nat, NULL, NULL);
 
-  *minimum = 0;
-  *natural = 0;
-
-  for (children = priv->children; children; children = children->next)
-    {
-      child = children->data;
-
-      if (!gtk_widget_get_visible (child->widget))
-        continue;
-
-      gtk_widget_get_preferred_height (child->widget, &child_min, &child_nat);
-
-      *minimum = MAX (*minimum, child->y + child_min);
-      *natural = MAX (*natural, child->y + child_nat);
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        {
+          *minimum = MAX (*minimum, child->x + child_min);
+          *natural = MAX (*natural, child->x + child_nat);
+        }
+      else /* VERTICAL */
+        { 
+          *minimum = MAX (*minimum, child->y + child_min);
+          *natural = MAX (*natural, child->y + child_nat);
+        }
     }
 }
 
diff --git a/gtk/gtkflowbox.c b/gtk/gtkflowbox.c
index 3c21e63..22c56d3 100644
--- a/gtk/gtkflowbox.c
+++ b/gtk/gtkflowbox.c
@@ -414,53 +414,19 @@ gtk_flow_box_child_get_request_mode (GtkWidget *widget)
 }
 
 static void
-gtk_flow_box_child_get_preferred_height (GtkWidget *widget,
-                                         gint      *minimum,
-                                         gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_flow_box_child_get_preferred_height_for_width (GtkWidget *widget,
-                                                   gint       width,
-                                                   gint      *minimum,
-                                                   gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_flow_box_child_get_preferred_width (GtkWidget *widget,
-                                        gint      *minimum,
-                                        gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_flow_box_child_get_preferred_width_for_height (GtkWidget *widget,
-                                                   gint       height,
-                                                   gint      *minimum,
-                                                   gint      *natural)
+gtk_flow_box_child_measure_ (GtkWidget     *widget,
+                            GtkOrientation  orientation,
+                            int             for_size,
+                            int            *minimum,
+                            int            *natural,
+                            int            *minimum_baseline,
+                            int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (CHILD_PRIV (GTK_FLOW_BOX_CHILD (widget))->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -587,10 +553,7 @@ gtk_flow_box_child_class_init (GtkFlowBoxChildClass *class)
 
   widget_class->get_render_node = gtk_flow_box_child_get_render_node;
   widget_class->get_request_mode = gtk_flow_box_child_get_request_mode;
-  widget_class->get_preferred_height = gtk_flow_box_child_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_flow_box_child_get_preferred_height_for_width;
-  widget_class->get_preferred_width = gtk_flow_box_child_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_flow_box_child_get_preferred_width_for_height;
+  widget_class->measure = gtk_flow_box_child_measure_;
   widget_class->size_allocate = gtk_flow_box_child_size_allocate;
   widget_class->focus = gtk_flow_box_child_focus;
 
@@ -2062,53 +2025,19 @@ get_largest_aligned_line_length (GtkFlowBox     *box,
 }
 
 static void
-gtk_flow_box_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_flow_box_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_flow_box_get_preferred_height_for_width (GtkWidget *widget,
-                                             gint       width,
-                                             gint      *minimum,
-                                             gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_flow_box_get_preferred_width_for_height (GtkWidget *widget,
-                                             gint       height,
-                                             gint      *minimum,
-                                             gint      *natural)
+gtk_flow_box_measure_ (GtkWidget     *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -3771,10 +3700,7 @@ gtk_flow_box_class_init (GtkFlowBoxClass *class)
   widget_class->get_render_node = gtk_flow_box_get_render_node;
   widget_class->key_press_event = gtk_flow_box_key_press_event;
   widget_class->get_request_mode = gtk_flow_box_get_request_mode;
-  widget_class->get_preferred_width = gtk_flow_box_get_preferred_width;
-  widget_class->get_preferred_height = gtk_flow_box_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_flow_box_get_preferred_height_for_width;
-  widget_class->get_preferred_width_for_height = gtk_flow_box_get_preferred_width_for_height;
+  widget_class->measure = gtk_flow_box_measure_;
 
   container_class->add = gtk_flow_box_add;
   container_class->remove = gtk_flow_box_remove;
diff --git a/gtk/gtkframe.c b/gtk/gtkframe.c
index 6a5ed09..270ab1e 100644
--- a/gtk/gtkframe.c
+++ b/gtk/gtkframe.c
@@ -144,21 +144,13 @@ static void gtk_frame_buildable_add_child           (GtkBuildable *buildable,
                                                     GtkBuilder   *builder,
                                                     GObject      *child,
                                                     const gchar  *type);
-
-static void gtk_frame_get_preferred_width           (GtkWidget           *widget,
-                                                     gint                *minimum_size,
-                                                    gint                *natural_size);
-static void gtk_frame_get_preferred_height          (GtkWidget           *widget,
-                                                    gint                *minimum_size,
-                                                    gint                *natural_size);
-static void gtk_frame_get_preferred_height_for_width(GtkWidget           *layout,
-                                                    gint                 width,
-                                                    gint                *minimum_height,
-                                                    gint                *natural_height);
-static void gtk_frame_get_preferred_width_for_height(GtkWidget           *layout,
-                                                    gint                 width,
-                                                    gint                *minimum_height,
-                                                    gint                *natural_height);
+static void     gtk_frame_measure_ (GtkWidget           *widget,
+                                    GtkOrientation       orientation,
+                                    gint                 for_size,
+                                    gint                *minimum_size,
+                                    gint                *natural_size,
+                                    gint                *minimum_baseline,
+                                    gint                *natural_baseline);
 static void gtk_frame_state_flags_changed (GtkWidget     *widget,
                                            GtkStateFlags  previous_state);
 
@@ -252,10 +244,7 @@ gtk_frame_class_init (GtkFrameClass *class)
 
   widget_class->get_render_node                = gtk_frame_get_render_node;
   widget_class->size_allocate                  = gtk_frame_size_allocate;
-  widget_class->get_preferred_width            = gtk_frame_get_preferred_width;
-  widget_class->get_preferred_height           = gtk_frame_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_frame_get_preferred_height_for_width;
-  widget_class->get_preferred_width_for_height = gtk_frame_get_preferred_width_for_height;
+  widget_class->measure = gtk_frame_measure_;
   widget_class->state_flags_changed            = gtk_frame_state_flags_changed;
 
   container_class->remove = gtk_frame_remove;
@@ -982,56 +971,20 @@ gtk_frame_measure_border (GtkCssGadget   *gadget,
     }
 }
 
-
-static void
-gtk_frame_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
 static void
-gtk_frame_get_preferred_width_for_height (GtkWidget *widget,
-                                          gint       height,
-                                          gint      *minimum,
-                                          gint      *natural)
+gtk_frame_measure_ (GtkWidget           *widget,
+                    GtkOrientation       orientation,
+                    gint                 for_size,
+                    gint                *minimum,
+                    gint                *natural,
+                    gint                *minimum_baseline,
+                    gint                *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_frame_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-
-static void
-gtk_frame_get_preferred_height_for_width (GtkWidget *widget,
-                                          gint       width,
-                                          gint      *minimum,
-                                          gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_FRAME (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
diff --git a/gtk/gtkgrid.c b/gtk/gtkgrid.c
index 1c5855d..729904c 100644
--- a/gtk/gtkgrid.c
+++ b/gtk/gtkgrid.c
@@ -1488,66 +1488,17 @@ gtk_grid_get_size_for_size (GtkGrid        *grid,
 }
 
 static void
-gtk_grid_get_preferred_width (GtkWidget *widget,
-                              gint      *minimum,
-                              gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_GRID (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_grid_get_preferred_height (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_GRID (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_grid_get_preferred_width_for_height (GtkWidget *widget,
-                                         gint       height,
-                                         gint      *minimum,
-                                         gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_GRID (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_grid_get_preferred_height_for_width (GtkWidget *widget,
-                                         gint       width,
-                                         gint      *minimum,
-                                         gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_GRID (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_grid_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                     gint       width,
-                                                     gint      *minimum,
-                                                     gint      *natural,
-                                                     gint      *minimum_baseline,
-                                                     gint      *natural_baseline)
+gtk_grid_measure_ (GtkWidget     *widget,
+                  GtkOrientation  orientation,
+                  int             for_size,
+                  int            *minimum,
+                  int            *natural,
+                  int            *minimum_baseline,
+                  int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_GRID (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
@@ -1732,11 +1683,7 @@ gtk_grid_class_init (GtkGridClass *class)
   object_class->finalize = gtk_grid_finalize;
 
   widget_class->size_allocate = gtk_grid_size_allocate;
-  widget_class->get_preferred_width = gtk_grid_get_preferred_width;
-  widget_class->get_preferred_height = gtk_grid_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_grid_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_grid_get_preferred_height_for_width;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_grid_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_grid_measure_;
   widget_class->get_render_node = gtk_grid_get_render_node;
 
   container_class->add = gtk_grid_add;
diff --git a/gtk/gtkheaderbar.c b/gtk/gtkheaderbar.c
index 23a5674..592abe3 100644
--- a/gtk/gtkheaderbar.c
+++ b/gtk/gtkheaderbar.c
@@ -904,61 +904,21 @@ gtk_header_bar_get_content_size (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_header_bar_get_preferred_width (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
+gtk_header_bar_measure (GtkWidget      *widget,
+                        GtkOrientation  orientation,
+                        int             for_size,
+                        int            *minimum,
+                        int            *natural,
+                        int            *minimum_baseline,
+                        int            *natural_baseline)
 {
   GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (GTK_HEADER_BAR (widget));
 
   gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_header_bar_get_preferred_height (GtkWidget *widget,
-                                     gint      *minimum,
-                                     gint      *natural)
-{
-  GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (GTK_HEADER_BAR (widget));
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_header_bar_get_preferred_width_for_height (GtkWidget *widget,
-                                               gint       height,
-                                               gint      *minimum,
-                                               gint      *natural)
-{
-  GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (GTK_HEADER_BAR (widget));
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_header_bar_get_preferred_height_for_width (GtkWidget *widget,
-                                               gint       width,
-                                               gint      *minimum,
-                                               gint      *natural)
-{
-  GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (GTK_HEADER_BAR (widget));
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -1949,10 +1909,7 @@ gtk_header_bar_class_init (GtkHeaderBarClass *class)
 
   widget_class->destroy = gtk_header_bar_destroy;
   widget_class->size_allocate = gtk_header_bar_size_allocate;
-  widget_class->get_preferred_width = gtk_header_bar_get_preferred_width;
-  widget_class->get_preferred_height = gtk_header_bar_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_header_bar_get_preferred_height_for_width;
-  widget_class->get_preferred_width_for_height = gtk_header_bar_get_preferred_width_for_height;
+  widget_class->measure = gtk_header_bar_measure;
   widget_class->realize = gtk_header_bar_realize;
   widget_class->unrealize = gtk_header_bar_unrealize;
   widget_class->hierarchy_changed = gtk_header_bar_hierarchy_changed;
diff --git a/gtk/gtkicon.c b/gtk/gtkicon.c
index 3e5e80f..65068b5 100644
--- a/gtk/gtkicon.c
+++ b/gtk/gtkicon.c
@@ -94,49 +94,25 @@ gtk_icon_set_property (GObject      *object,
 }
 
 static void
-gtk_icon_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                      gint       for_width,
-                                                      gint      *minimum,
-                                                      gint      *natural,
-                                                      gint      *minimum_baseline,
-                                                      gint      *natural_baseline)
+gtk_icon_measure (GtkWidget *widget,
+                  GtkOrientation  orientation,
+                  int             for_size,
+                  int            *minimum,
+                  int            *natural,
+                  int            *minimum_baseline,
+                  int            *natural_baseline)
 {
   GtkIcon *self = GTK_ICON (widget);
   GtkIconPrivate *priv = gtk_icon_get_instance_private (self);
 
   gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     for_width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
 
 static void
-gtk_icon_get_preferred_height (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  gtk_icon_get_preferred_height_and_baseline_for_width (widget, -1,
-                                                        minimum, natural,
-                                                        NULL, NULL);
-}
-
-static void
-gtk_icon_get_preferred_width (GtkWidget *widget,
-                              gint      *minimum,
-                              gint      *natural)
-{
-  GtkIcon *self = GTK_ICON (widget);
-  GtkIconPrivate *priv = gtk_icon_get_instance_private (self);
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
 gtk_icon_size_allocate (GtkWidget     *widget,
                         GtkAllocation *allocation)
 {
@@ -175,9 +151,7 @@ gtk_icon_class_init (GtkIconClass *klass)
   oclass->finalize = gtk_icon_finalize;
 
   wclass->size_allocate = gtk_icon_size_allocate;
-  wclass->get_preferred_width = gtk_icon_get_preferred_width;
-  wclass->get_preferred_height = gtk_icon_get_preferred_height;
-  wclass->get_preferred_height_and_baseline_for_width = gtk_icon_get_preferred_height_and_baseline_for_width;
+  wclass->measure = gtk_icon_measure;
   wclass->draw = gtk_icon_draw;
 
   icon_props[PROP_CSS_NAME] =
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index 4e828b2..638f9e0 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -144,22 +144,13 @@ static void             gtk_icon_view_destroy                   (GtkWidget
 static void             gtk_icon_view_realize                   (GtkWidget          *widget);
 static void             gtk_icon_view_unrealize                 (GtkWidget          *widget);
 static GtkSizeRequestMode gtk_icon_view_get_request_mode        (GtkWidget          *widget);
-static void             gtk_icon_view_get_preferred_width       (GtkWidget          *widget,
-                                                                gint               *minimum,
-                                                                gint               *natural);
-static void             gtk_icon_view_get_preferred_width_for_height
-                                                                (GtkWidget          *widget,
-                                                                 gint                height,
-                                                                gint               *minimum,
-                                                                gint               *natural);
-static void             gtk_icon_view_get_preferred_height      (GtkWidget          *widget,
-                                                                gint               *minimum,
-                                                                gint               *natural);
-static void             gtk_icon_view_get_preferred_height_for_width
-                                                                (GtkWidget          *widget,
-                                                                 gint                width,
-                                                                gint               *minimum,
-                                                                gint               *natural);
+static void gtk_icon_view_measure (GtkWidget *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 static void             gtk_icon_view_size_allocate             (GtkWidget          *widget,
                                                                 GtkAllocation      *allocation);
 static gboolean         gtk_icon_view_draw                      (GtkWidget          *widget,
@@ -361,10 +352,7 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
   widget_class->realize = gtk_icon_view_realize;
   widget_class->unrealize = gtk_icon_view_unrealize;
   widget_class->get_request_mode = gtk_icon_view_get_request_mode;
-  widget_class->get_preferred_width = gtk_icon_view_get_preferred_width;
-  widget_class->get_preferred_height = gtk_icon_view_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_icon_view_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_icon_view_get_preferred_height_for_width;
+  widget_class->measure = gtk_icon_view_measure;
   widget_class->size_allocate = gtk_icon_view_size_allocate;
   widget_class->draw = gtk_icon_view_draw;
   widget_class->motion_notify_event = gtk_icon_view_motion;
@@ -1607,13 +1595,19 @@ gtk_icon_view_get_request_mode (GtkWidget *widget)
 }
 
 static void
-gtk_icon_view_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
+gtk_icon_view_measure (GtkWidget *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   GtkIconView *icon_view = GTK_ICON_VIEW (widget);
   GtkIconViewPrivate *priv = icon_view->priv;
-  int item_min, item_nat;
+  GtkOrientation other_orientation = orientation == GTK_ORIENTATION_HORIZONTAL ?
+                                     GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL;
+  int item_min, item_nat, items, item_size, n_items;
 
   if (gtk_icon_view_is_empty (icon_view))
     {
@@ -1621,113 +1615,37 @@ gtk_icon_view_get_preferred_width (GtkWidget *widget,
       return;
     }
 
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_HORIZONTAL, -1, &item_min, &item_nat);
-
-  if (priv->columns > 0)
-    {
-      *minimum = item_min * priv->columns + priv->column_spacing * (priv->columns - 1);
-      *natural = item_nat * priv->columns + priv->column_spacing * (priv->columns - 1);
-    }
-  else
-    {
-      int n_items = gtk_icon_view_get_n_items (icon_view);
-
-      *minimum = item_min;
-      *natural = item_nat * n_items + priv->column_spacing * (n_items - 1);
-    }
-
-  *minimum += 2 * priv->margin;
-  *natural += 2 * priv->margin;
-}
-
-static void
-gtk_icon_view_get_preferred_width_for_height (GtkWidget *widget,
-                                              gint       height,
-                                              gint      *minimum,
-                                              gint      *natural)
-{
-  GtkIconView *icon_view = GTK_ICON_VIEW (widget);
-  GtkIconViewPrivate *priv = icon_view->priv;
-  int item_min, item_nat, rows, row_height, n_items;
-
-  if (gtk_icon_view_is_empty (icon_view))
-    {
-      *minimum = *natural = 2 * priv->margin;
-      return;
-    }
-
-  gtk_icon_view_compute_n_items_for_size (icon_view, GTK_ORIENTATION_VERTICAL, height, &rows, &row_height, 
NULL, NULL);
   n_items = gtk_icon_view_get_n_items (icon_view);
 
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_HORIZONTAL, row_height, &item_min, 
&item_nat);
-  *minimum = (item_min + priv->column_spacing) * ((n_items + rows - 1) / rows) - priv->column_spacing;
-  *natural = (item_nat + priv->column_spacing) * ((n_items + rows - 1) / rows) - priv->column_spacing;
-
-  *minimum += 2 * priv->margin;
-  *natural += 2 * priv->margin;
-}
-
-static void
-gtk_icon_view_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkIconView *icon_view = GTK_ICON_VIEW (widget);
-  GtkIconViewPrivate *priv = icon_view->priv;
-  int item_min, item_nat, n_items;
-
-  if (gtk_icon_view_is_empty (icon_view))
+  if (for_size < 0)
     {
-      *minimum = *natural = 2 * priv->margin;
-      return;
-    }
-
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_VERTICAL, -1, &item_min, &item_nat);
-  n_items = gtk_icon_view_get_n_items (icon_view);
+      gtk_icon_view_get_preferred_item_size (icon_view, orientation, -1, &item_min, &item_nat);
 
-  if (priv->columns > 0)
-    {
-      int n_rows = (n_items + priv->columns - 1) / priv->columns;
+      if (priv->columns > 0)
+        {
+          int n_rows = (n_items + priv->columns - 1) / priv->columns;
 
-      *minimum = item_min * n_rows + priv->row_spacing * (n_rows - 1);
-      *natural = item_nat * n_rows + priv->row_spacing * (n_rows - 1);
+          *minimum = item_min * n_rows + priv->row_spacing * (n_rows - 1);
+          *natural = item_nat * n_rows + priv->row_spacing * (n_rows - 1);
+        }
+      else
+        {
+          *minimum = item_min;
+          *natural = item_nat * n_items + priv->row_spacing * (n_items - 1);
+        }
     }
   else
     {
-      *minimum = item_min;
-      *natural = item_nat * n_items + priv->row_spacing * (n_items - 1);
+      gtk_icon_view_compute_n_items_for_size (icon_view, orientation, for_size, NULL, NULL, &items, 
&item_size);
+      gtk_icon_view_get_preferred_item_size (icon_view, other_orientation, item_size, &item_min, &item_nat);
+      *minimum = (item_min + priv->row_spacing) * ((n_items + items - 1) / items) - priv->row_spacing;
+      *natural = (item_nat + priv->row_spacing) * ((n_items + items - 1) / items) - priv->row_spacing;
     }
 
   *minimum += 2 * priv->margin;
   *natural += 2 * priv->margin;
 }
 
-static void
-gtk_icon_view_get_preferred_height_for_width (GtkWidget *widget,
-                                              gint       width,
-                                              gint      *minimum,
-                                              gint      *natural)
-{
-  GtkIconView *icon_view = GTK_ICON_VIEW (widget);
-  GtkIconViewPrivate *priv = icon_view->priv;
-  int item_min, item_nat, columns, column_width, n_items;
-
-  if (gtk_icon_view_is_empty (icon_view))
-    {
-      *minimum = *natural = 2 * priv->margin;
-      return;
-    }
-
-  gtk_icon_view_compute_n_items_for_size (icon_view, GTK_ORIENTATION_HORIZONTAL, width, NULL, NULL, 
&columns, &column_width);
-  n_items = gtk_icon_view_get_n_items (icon_view);
-
-  gtk_icon_view_get_preferred_item_size (icon_view, GTK_ORIENTATION_VERTICAL, column_width, &item_min, 
&item_nat);
-  *minimum = (item_min + priv->row_spacing) * ((n_items + columns - 1) / columns) - priv->row_spacing;
-  *natural = (item_nat + priv->row_spacing) * ((n_items + columns - 1) / columns) - priv->row_spacing;
-
-  *minimum += 2 * priv->margin;
-  *natural += 2 * priv->margin;
-}
 
 static void
 gtk_icon_view_allocate_children (GtkIconView *icon_view)
diff --git a/gtk/gtkimage.c b/gtk/gtkimage.c
index 3d196f3..cb8b543 100644
--- a/gtk/gtkimage.c
+++ b/gtk/gtkimage.c
@@ -148,19 +148,13 @@ static void gtk_image_size_allocate        (GtkWidget    *widget,
                                             GtkAllocation*allocation);
 static void gtk_image_unmap                (GtkWidget    *widget);
 static void gtk_image_unrealize            (GtkWidget    *widget);
-static void gtk_image_get_preferred_width  (GtkWidget    *widget,
-                                            gint         *minimum,
-                                            gint         *natural);
-static void gtk_image_get_preferred_height (GtkWidget    *widget,
-                                            gint         *minimum,
-                                            gint         *natural);
-static void gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                                  gint       width,
-                                                                  gint      *minimum,
-                                                                  gint      *natural,
-                                                                  gint      *minimum_baseline,
-                                                                  gint      *natural_baseline);
-
+static void gtk_image_measure (GtkWidget      *widget,
+                               GtkOrientation  orientation,
+                               int            for_size,
+                               int           *minimum,
+                               int           *natural,
+                               int           *minimum_baseline,
+                               int           *natural_baseline);
 static void gtk_image_get_content_size (GtkCssGadget   *gadget,
                                         GtkOrientation  orientation,
                                         gint            for_size,
@@ -218,9 +212,7 @@ gtk_image_class_init (GtkImageClass *class)
 
   widget_class = GTK_WIDGET_CLASS (class);
   widget_class->get_render_node = gtk_image_get_render_node;
-  widget_class->get_preferred_width = gtk_image_get_preferred_width;
-  widget_class->get_preferred_height = gtk_image_get_preferred_height;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_image_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_image_measure;
   widget_class->size_allocate = gtk_image_size_allocate;
   widget_class->unmap = gtk_image_unmap;
   widget_class->unrealize = gtk_image_unrealize;
@@ -1578,40 +1570,17 @@ gtk_image_clear (GtkImage *image)
 }
 
 static void
-gtk_image_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_IMAGE (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_image_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_IMAGE (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_image_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                      gint       width,
-                                                      gint      *minimum,
-                                                      gint      *natural,
-                                                      gint      *minimum_baseline,
-                                                      gint      *natural_baseline)
+gtk_image_measure (GtkWidget      *widget,
+                   GtkOrientation  orientation,
+                   int            for_size,
+                   int           *minimum,
+                   int           *natural,
+                   int           *minimum_baseline,
+                   int           *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_IMAGE (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c
index 5ea67e0..1f74a8b 100644
--- a/gtk/gtklabel.c
+++ b/gtk/gtklabel.c
@@ -549,26 +549,13 @@ static void   gtk_label_drag_gesture_update         (GtkGestureDrag *gesture,
                                                      GtkLabel       *label);
 
 static GtkSizeRequestMode gtk_label_get_request_mode                (GtkWidget           *widget);
-static void               gtk_label_get_preferred_width             (GtkWidget           *widget,
-                                                                     gint                *minimum_size,
-                                                                     gint                *natural_size);
-static void               gtk_label_get_preferred_height            (GtkWidget           *widget,
-                                                                     gint                *minimum_size,
-                                                                     gint                *natural_size);
-static void               gtk_label_get_preferred_width_for_height  (GtkWidget           *widget,
-                                                                     gint                 height,
-                                                                     gint                *minimum_width,
-                                                                     gint                *natural_width);
-static void               gtk_label_get_preferred_height_for_width  (GtkWidget           *widget,
-                                                                     gint                 width,
-                                                                     gint                *minimum_height,
-                                                                     gint                *natural_height);
-static void    gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget          *widget,
-                                                                     gint                width,
-                                                                     gint               *minimum_height,
-                                                                     gint               *natural_height,
-                                                                     gint               *minimum_baseline,
-                                                                     gint               *natural_baseline);
+static void     gtk_label_measure_ (GtkWidget     *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 
 static void     gtk_label_measure (GtkCssGadget   *gadget,
                                    GtkOrientation  orientation,
@@ -640,11 +627,7 @@ gtk_label_class_init (GtkLabelClass *class)
   widget_class->popup_menu = gtk_label_popup_menu;
   widget_class->focus = gtk_label_focus;
   widget_class->get_request_mode = gtk_label_get_request_mode;
-  widget_class->get_preferred_width = gtk_label_get_preferred_width;
-  widget_class->get_preferred_height = gtk_label_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_label_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_label_get_preferred_height_for_width;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_label_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_label_measure_;
 
   class->move_cursor = gtk_label_move_cursor;
   class->copy_clipboard = gtk_label_copy_clipboard;
@@ -3869,67 +3852,18 @@ gtk_label_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_label_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum_size,
-                               gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_LABEL (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_label_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum_size,
-                                gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_LABEL (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_label_get_preferred_width_for_height (GtkWidget *widget,
-                                          gint       height,
-                                          gint      *minimum_width,
-                                          gint      *natural_width)
-{
-  gtk_css_gadget_get_preferred_size (GTK_LABEL (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum_width, natural_width,
-                                     NULL, NULL);
-}
-
-static void
-gtk_label_get_preferred_height_for_width (GtkWidget *widget,
-                                          gint       width,
-                                          gint      *minimum_height,
-                                          gint      *natural_height)
-{
-  gtk_css_gadget_get_preferred_size (GTK_LABEL (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum_height, natural_height,
-                                     NULL, NULL);
-}
-
-static void
-gtk_label_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                      gint       width,
-                                                      gint      *minimum_height,
-                                                      gint      *natural_height,
-                                                      gint      *minimum_baseline,
-                                                      gint      *natural_baseline)
+gtk_label_measure_ (GtkWidget     *widget,
+                    GtkOrientation  orientation,
+                    int             for_size,
+                    int            *minimum,
+                    int            *natural,
+                    int            *minimum_baseline,
+                    int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_LABEL (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum_height, natural_height,
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
 
diff --git a/gtk/gtklayout.c b/gtk/gtklayout.c
index 81e716a..56347b2 100644
--- a/gtk/gtklayout.c
+++ b/gtk/gtklayout.c
@@ -123,12 +123,13 @@ static void gtk_layout_finalize           (GObject        *object);
 static void gtk_layout_realize            (GtkWidget      *widget);
 static void gtk_layout_unrealize          (GtkWidget      *widget);
 static void gtk_layout_map                (GtkWidget      *widget);
-static void gtk_layout_get_preferred_width  (GtkWidget     *widget,
-                                             gint          *minimum,
-                                             gint          *natural);
-static void gtk_layout_get_preferred_height (GtkWidget     *widget,
-                                             gint          *minimum,
-                                             gint          *natural);
+static void gtk_layout_measure (GtkWidget *widget,
+                                GtkOrientation  orientation,
+                                int             for_size,
+                                int            *minimum,
+                                int            *natural,
+                                int            *minimum_baseline,
+                                int            *natural_baseline);
 static void gtk_layout_size_allocate      (GtkWidget      *widget,
                                            GtkAllocation  *allocation);
 static gint gtk_layout_draw               (GtkWidget      *widget,
@@ -687,8 +688,7 @@ gtk_layout_class_init (GtkLayoutClass *class)
   widget_class->realize = gtk_layout_realize;
   widget_class->unrealize = gtk_layout_unrealize;
   widget_class->map = gtk_layout_map;
-  widget_class->get_preferred_width = gtk_layout_get_preferred_width;
-  widget_class->get_preferred_height = gtk_layout_get_preferred_height;
+  widget_class->measure = gtk_layout_measure;
   widget_class->size_allocate = gtk_layout_size_allocate;
   widget_class->draw = gtk_layout_draw;
 
@@ -937,20 +937,17 @@ gtk_layout_unrealize (GtkWidget *widget)
 }
 
 static void
-gtk_layout_get_preferred_width (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
+gtk_layout_measure (GtkWidget *widget,
+                    GtkOrientation  orientation,
+                    int             for_size,
+                    int            *minimum,
+                    int            *natural,
+                    int            *minimum_baseline,
+                    int            *natural_baseline)
 {
   *minimum = *natural = 0;
 }
 
-static void
-gtk_layout_get_preferred_height (GtkWidget *widget,
-                                 gint      *minimum,
-                                 gint      *natural)
-{
-  *minimum = *natural = 0;
-}
 
 static void
 gtk_layout_size_allocate (GtkWidget     *widget,
diff --git a/gtk/gtklevelbar.c b/gtk/gtklevelbar.c
index 709b7d4..f7229f5 100644
--- a/gtk/gtklevelbar.c
+++ b/gtk/gtklevelbar.c
@@ -426,27 +426,19 @@ gtk_level_bar_measure_trough (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_level_bar_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
+gtk_level_bar_measure (GtkWidget      *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_LEVEL_BAR (widget)->priv->trough_gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_level_bar_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_LEVEL_BAR (widget)->priv->trough_gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -976,8 +968,7 @@ gtk_level_bar_class_init (GtkLevelBarClass *klass)
 
   wclass->draw = gtk_level_bar_draw;
   wclass->size_allocate = gtk_level_bar_size_allocate;
-  wclass->get_preferred_width = gtk_level_bar_get_preferred_width;
-  wclass->get_preferred_height = gtk_level_bar_get_preferred_height;
+  wclass->measure = gtk_level_bar_measure;
   wclass->state_flags_changed = gtk_level_bar_state_flags_changed;
   wclass->direction_changed = gtk_level_bar_direction_changed;
 
diff --git a/gtk/gtklistbox.c b/gtk/gtklistbox.c
index 98440d2..90ebaca 100644
--- a/gtk/gtklistbox.c
+++ b/gtk/gtklistbox.c
@@ -239,22 +239,6 @@ static void                 gtk_list_box_move_cursor                  (GtkListBo
 static void                 gtk_list_box_finalize                     (GObject             *obj);
 static void                 gtk_list_box_parent_set                   (GtkWidget           *widget,
                                                                        GtkWidget           *prev_parent);
-
-static void                 gtk_list_box_get_preferred_height           (GtkWidget           *widget,
-                                                                         gint                *minimum_height,
-                                                                         gint                
*natural_height);
-static void                 gtk_list_box_get_preferred_height_for_width (GtkWidget           *widget,
-                                                                         gint                 width,
-                                                                         gint                *minimum_height,
-                                                                         gint                
*natural_height);
-static void                 gtk_list_box_get_preferred_width            (GtkWidget           *widget,
-                                                                         gint                *minimum_width,
-                                                                         gint                *natural_width);
-static void                 gtk_list_box_get_preferred_width_for_height (GtkWidget           *widget,
-                                                                         gint                 height,
-                                                                         gint                *minimum_width,
-                                                                         gint                *natural_width);
-
 static void                 gtk_list_box_select_row_internal            (GtkListBox          *box,
                                                                          GtkListBoxRow       *row);
 static void                 gtk_list_box_unselect_row_internal          (GtkListBox          *box,
@@ -302,6 +286,13 @@ static void     gtk_list_box_allocate    (GtkCssGadget        *gadget,
                                           int                  baseline,
                                           GtkAllocation       *out_clip,
                                           gpointer             data);
+static void gtk_list_box_measure_ (GtkWidget     *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 
 
 
@@ -424,10 +415,7 @@ gtk_list_box_class_init (GtkListBoxClass *klass)
   widget_class->realize = gtk_list_box_realize;
   widget_class->compute_expand = gtk_list_box_compute_expand;
   widget_class->get_request_mode = gtk_list_box_get_request_mode;
-  widget_class->get_preferred_height = gtk_list_box_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_list_box_get_preferred_height_for_width;
-  widget_class->get_preferred_width = gtk_list_box_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_list_box_get_preferred_width_for_height;
+  widget_class->measure = gtk_list_box_measure_;
   widget_class->size_allocate = gtk_list_box_size_allocate;
   widget_class->drag_leave = gtk_list_box_drag_leave;
   widget_class->parent_set = gtk_list_box_parent_set;
@@ -2558,53 +2546,19 @@ gtk_list_box_get_request_mode (GtkWidget *widget)
 }
 
 static void
-gtk_list_box_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_list_box_get_preferred_height_for_width (GtkWidget *widget,
-                                             gint       width,
-                                             gint      *minimum,
-                                             gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_list_box_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
+gtk_list_box_measure_ (GtkWidget     *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_list_box_get_preferred_width_for_height (GtkWidget *widget,
-                                             gint       height,
-                                             gint      *minimum,
-                                             gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (BOX_PRIV (widget)->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -3299,53 +3253,19 @@ gtk_list_box_row_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_list_box_row_get_preferred_height (GtkWidget *widget,
-                                       gint      *minimum,
-                                       gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (ROW_PRIV (GTK_LIST_BOX_ROW (widget))->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_list_box_row_get_preferred_height_for_width (GtkWidget *widget,
-                                                 gint       width,
-                                                 gint      *minimum,
-                                                 gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (ROW_PRIV (GTK_LIST_BOX_ROW (widget))->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_list_box_row_get_preferred_width (GtkWidget *widget,
-                                      gint      *minimum,
-                                      gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (ROW_PRIV (GTK_LIST_BOX_ROW (widget))->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_list_box_row_get_preferred_width_for_height (GtkWidget *widget,
-                                                 gint       height,
-                                                 gint      *minimum,
-                                                 gint      *natural)
+gtk_list_box_row_measure_ (GtkWidget     *widget,
+                          GtkOrientation  orientation,
+                          int             for_size,
+                          int            *minimum,
+                          int            *natural,
+                          int            *minimum_baseline,
+                          int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (ROW_PRIV (GTK_LIST_BOX_ROW (widget))->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -3723,10 +3643,7 @@ gtk_list_box_row_class_init (GtkListBoxRowClass *klass)
   widget_class->show = gtk_list_box_row_show;
   widget_class->hide = gtk_list_box_row_hide;
   widget_class->get_render_node = gtk_list_box_row_get_render_node;
-  widget_class->get_preferred_height = gtk_list_box_row_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_list_box_row_get_preferred_height_for_width;
-  widget_class->get_preferred_width = gtk_list_box_row_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_list_box_row_get_preferred_width_for_height;
+  widget_class->measure = gtk_list_box_row_measure_;
   widget_class->size_allocate = gtk_list_box_row_size_allocate;
   widget_class->focus = gtk_list_box_row_focus;
   widget_class->grab_focus = gtk_list_box_row_grab_focus;
diff --git a/gtk/gtkmagnifier.c b/gtk/gtkmagnifier.c
index 5d93767..f34f1bb 100644
--- a/gtk/gtkmagnifier.c
+++ b/gtk/gtkmagnifier.c
@@ -134,46 +134,32 @@ _gtk_magnifier_draw (GtkWidget *widget,
 }
 
 static void
-gtk_magnifier_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum_width,
-                                   gint      *natural_width)
+gtk_magnifier_measure (GtkWidget      *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
-  GtkMagnifier *magnifier;
-  GtkMagnifierPrivate *priv;
-  gint width;
-
-  magnifier = GTK_MAGNIFIER (widget);
-  priv = _gtk_magnifier_get_instance_private (magnifier);
+  GtkMagnifier *magnifier = GTK_MAGNIFIER (widget);
+  GtkMagnifierPrivate *priv = _gtk_magnifier_get_instance_private (magnifier);
+  gint size;
 
   if (priv->resize && priv->inspected)
-    width = priv->magnification * gtk_widget_get_allocated_width (priv->inspected);
+    {
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        size = priv->magnification * gtk_widget_get_allocated_width (priv->inspected);
+      else
+        size = priv->magnification * gtk_widget_get_allocated_height (priv->inspected);
+    }
   else
-    width = 0;
+    size = 0;
 
-  *minimum_width = width;
-  *natural_width = width;
+  *minimum = size;
+  *natural = size;
 }
 
-static void
-gtk_magnifier_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum_height,
-                                    gint      *natural_height)
-{
-  GtkMagnifier *magnifier;
-  GtkMagnifierPrivate *priv;
-  gint height;
-
-  magnifier = GTK_MAGNIFIER (widget);
-  priv = _gtk_magnifier_get_instance_private (magnifier);
-
-  if (priv->resize && priv->inspected)
-    height = priv->magnification * gtk_widget_get_allocated_height (priv->inspected);
-  else
-    height = 0;
-
-  *minimum_height = height;
-  *natural_height = height;
-}
 
 static void
 resize_handler (GtkWidget     *widget,
@@ -284,8 +270,7 @@ _gtk_magnifier_class_init (GtkMagnifierClass *klass)
 
   widget_class->destroy = _gtk_magnifier_destroy;
   widget_class->draw = _gtk_magnifier_draw;
-  widget_class->get_preferred_width = gtk_magnifier_get_preferred_width;
-  widget_class->get_preferred_height = gtk_magnifier_get_preferred_height;
+  widget_class->measure = gtk_magnifier_measure;
   widget_class->map = gtk_magnifier_map;
   widget_class->unmap = gtk_magnifier_unmap;
 
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index e98dcda..6e306ba 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -305,17 +305,13 @@ static gboolean gtk_menu_real_can_activate_accel (GtkWidget *widget,
                                                   guint      signal_id);
 static void _gtk_menu_refresh_accel_paths (GtkMenu *menu,
                                            gboolean group_changed);
-
-static void gtk_menu_get_preferred_width            (GtkWidget           *widget,
-                                                     gint                *minimum_size,
-                                                     gint                *natural_size);
-static void gtk_menu_get_preferred_height           (GtkWidget           *widget,
-                                                     gint                *minimum_size,
-                                                     gint                *natural_size);
-static void gtk_menu_get_preferred_height_for_width (GtkWidget           *widget,
-                                                     gint                 for_size,
-                                                     gint                *minimum_size,
-                                                     gint                *natural_size);
+static void gtk_menu_measure (GtkWidget      *widget,
+                              GtkOrientation  orientation,
+                              int             for_size,
+                              int            *minimum,
+                              int            *natural,
+                              int            *minimum_baseline,
+                              int            *natural_baseline);
 
 
 static const gchar attach_data_key[] = "gtk-menu-attach-data";
@@ -525,9 +521,7 @@ gtk_menu_class_init (GtkMenuClass *class)
   widget_class->focus = gtk_menu_focus;
   widget_class->can_activate_accel = gtk_menu_real_can_activate_accel;
   widget_class->grab_notify = gtk_menu_grab_notify;
-  widget_class->get_preferred_width = gtk_menu_get_preferred_width;
-  widget_class->get_preferred_height = gtk_menu_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_menu_get_preferred_height_for_width;
+  widget_class->measure = gtk_menu_measure;
 
   container_class->remove = gtk_menu_remove;
   container_class->get_child_property = gtk_menu_get_child_property;
@@ -3016,189 +3010,189 @@ gtk_menu_show (GtkWidget *widget)
   GTK_WIDGET_CLASS (gtk_menu_parent_class)->show (widget);
 }
 
-
-static void 
-gtk_menu_get_preferred_width (GtkWidget *widget,
-                              gint      *minimum_size,
-                              gint      *natural_size)
+static void gtk_menu_measure (GtkWidget      *widget,
+                              GtkOrientation  orientation,
+                              int             for_size,
+                              int            *minimum,
+                              int            *natural,
+                              int            *minimum_baseline,
+                              int            *natural_baseline)
 {
-  GtkMenu        *menu;
-  GtkMenuShell   *menu_shell;
-  GtkMenuPrivate *priv;
-  GtkWidget      *child;
-  GList          *children;
-  guint           max_toggle_size;
-  guint           max_accel_width;
-  gint            child_min, child_nat;
-  gint            min_width, nat_width;
-  GtkBorder       padding;
+  GtkMenu *menu = GTK_MENU (widget);
+  GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget);
+  GtkMenuPrivate *priv = gtk_menu_get_instance_private (menu);
+  GtkWidget *child;
 
-  menu       = GTK_MENU (widget);
-  menu_shell = GTK_MENU_SHELL (widget);
-  priv       = menu->priv;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      GList          *children;
+      guint           max_toggle_size;
+      guint           max_accel_width;
+      gint            child_min, child_nat;
+      gint            min_width, nat_width;
+      GtkBorder       padding;
 
-  min_width = nat_width = 0;
+      min_width = nat_width = 0;
 
-  max_toggle_size = 0;
-  max_accel_width = 0;
+      max_toggle_size = 0;
+      max_accel_width = 0;
 
-  children = menu_shell->priv->children;
-  while (children)
-    {
-      gint part;
-      gint toggle_size;
-      gint l, r, t, b;
+      children = menu_shell->priv->children;
+      while (children)
+        {
+          gint part;
+          gint toggle_size;
+          gint l, r, t, b;
 
-      child = children->data;
-      children = children->next;
+          child = children->data;
+          children = children->next;
 
-      if (! gtk_widget_get_visible (child))
-        continue;
+          if (! gtk_widget_get_visible (child))
+            continue;
 
-      get_effective_child_attach (child, &l, &r, &t, &b);
+          get_effective_child_attach (child, &l, &r, &t, &b);
 
-      /* It's important to size_request the child
-       * before doing the toggle size request, in
-       * case the toggle size request depends on the size
-       * request of a child of the child (e.g. for ImageMenuItem)
-       */
-       gtk_widget_get_preferred_width (child, &child_min, &child_nat);
+          /* It's important to size_request the child
+           * before doing the toggle size request, in
+           * case the toggle size request depends on the size
+           * request of a child of the child (e.g. for ImageMenuItem)
+           */
+           gtk_widget_get_preferred_width (child, &child_min, &child_nat);
 
-       gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (child), &toggle_size);
-       max_toggle_size = MAX (max_toggle_size, toggle_size);
-       max_accel_width = MAX (max_accel_width,
-                              GTK_MENU_ITEM (child)->priv->accelerator_width);
+           gtk_menu_item_toggle_size_request (GTK_MENU_ITEM (child), &toggle_size);
+           max_toggle_size = MAX (max_toggle_size, toggle_size);
+           max_accel_width = MAX (max_accel_width,
+                                  GTK_MENU_ITEM (child)->priv->accelerator_width);
 
-       part = child_min / (r - l);
-       min_width = MAX (min_width, part);
+           part = child_min / (r - l);
+           min_width = MAX (min_width, part);
 
-       part = child_nat / (r - l);
-       nat_width = MAX (nat_width, part);
-    }
+           part = child_nat / (r - l);
+           nat_width = MAX (nat_width, part);
+        }
 
-  /* If the menu doesn't include any images or check items
-   * reserve the space so that all menus are consistent.
-   * We only do this for 'ordinary' menus, not for combobox
-   * menus or multi-column menus
-   */
-  if (max_toggle_size == 0 &&
-      gtk_menu_get_n_columns (menu) == 1 &&
-      !priv->no_toggle_size)
-    {
-      GtkWidget *menu_item;
-      GtkCssGadget *indicator_gadget;
-      gint indicator_width;
-
-      /* Create a GtkCheckMenuItem, to query indicator size */
-      menu_item = gtk_check_menu_item_new ();
-      indicator_gadget = _gtk_check_menu_item_get_indicator_gadget
-        (GTK_CHECK_MENU_ITEM (menu_item));
-
-      gtk_css_gadget_get_preferred_size (indicator_gadget,
-                                         GTK_ORIENTATION_HORIZONTAL,
-                                         -1,
-                                         &indicator_width, NULL,
-                                         NULL, NULL);
-      max_toggle_size = indicator_width;
-
-      gtk_widget_destroy (menu_item);
-    }
+      /* If the menu doesn't include any images or check items
+       * reserve the space so that all menus are consistent.
+       * We only do this for 'ordinary' menus, not for combobox
+       * menus or multi-column menus
+       */
+      if (max_toggle_size == 0 &&
+          gtk_menu_get_n_columns (menu) == 1 &&
+          !priv->no_toggle_size)
+        {
+          GtkWidget *menu_item;
+          GtkCssGadget *indicator_gadget;
+          gint indicator_width;
+
+          /* Create a GtkCheckMenuItem, to query indicator size */
+          menu_item = gtk_check_menu_item_new ();
+          indicator_gadget = _gtk_check_menu_item_get_indicator_gadget
+            (GTK_CHECK_MENU_ITEM (menu_item));
+
+          gtk_css_gadget_get_preferred_size (indicator_gadget,
+                                             GTK_ORIENTATION_HORIZONTAL,
+                                             -1,
+                                             &indicator_width, NULL,
+                                             NULL, NULL);
+          max_toggle_size = indicator_width;
+
+          gtk_widget_destroy (menu_item);
+        }
 
-  min_width += 2 * max_toggle_size + max_accel_width;
-  min_width *= gtk_menu_get_n_columns (menu);
+      min_width += 2 * max_toggle_size + max_accel_width;
+      min_width *= gtk_menu_get_n_columns (menu);
 
-  nat_width += 2 * max_toggle_size + max_accel_width;
-  nat_width *= gtk_menu_get_n_columns (menu);
+      nat_width += 2 * max_toggle_size + max_accel_width;
+      nat_width *= gtk_menu_get_n_columns (menu);
 
-  get_menu_padding (widget, &padding);
-  min_width   += padding.left + padding.right;
-  nat_width   += padding.left + padding.right;
+      get_menu_padding (widget, &padding);
+      min_width   += padding.left + padding.right;
+      nat_width   += padding.left + padding.right;
 
-  priv->toggle_size = max_toggle_size;
-  priv->accel_size  = max_accel_width;
+      priv->toggle_size = max_toggle_size;
+      priv->accel_size  = max_accel_width;
 
-  *minimum_size = min_width;
-  *natural_size = nat_width;
-}
+      *minimum = min_width;
+      *natural = nat_width;
 
-static void
-gtk_menu_get_preferred_height (GtkWidget *widget,
-                               gint      *minimum_size,
-                               gint      *natural_size)
-{
-  gint min_width, nat_width;
+    }
+  else /* VERTICAL */
+    {
+      if (for_size < 0)
+        {
+          gint min_width, nat_width;
 
-  /* Menus are height-for-width only, just return the height
-   * for the minimum width
-   */
-  GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, &min_width, &nat_width);
-  GTK_WIDGET_GET_CLASS (widget)->get_preferred_height_for_width (widget, min_width, minimum_size, 
natural_size);
-}
+          /* Menus are height-for-width only, just return the height
+           * for the minimum width
+           */
+          GTK_WIDGET_GET_CLASS (widget)->measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
+                                                  &min_width, &nat_width, NULL, NULL);
+          GTK_WIDGET_GET_CLASS (widget)->measure (widget, GTK_ORIENTATION_VERTICAL, min_width,
+                                                  minimum, natural,
+                                                  minimum_baseline, natural_baseline);
+        }
+      else
+        {
+          GtkBorder       padding, arrow_border;
+          guint          *min_heights, *nat_heights;
+          gint            n_heights, i;
+          gint            min_height, single_height, nat_height;
 
-static void
-gtk_menu_get_preferred_height_for_width (GtkWidget *widget,
-                                         gint       for_size,
-                                         gint      *minimum_size,
-                                         gint      *natural_size)
-{
-  GtkBorder       padding, arrow_border;
-  GtkMenu        *menu = GTK_MENU (widget);
-  GtkMenuPrivate *priv = menu->priv;
-  guint          *min_heights, *nat_heights;
-  gint            n_heights, i;
-  gint            min_height, single_height, nat_height;
+          get_menu_padding (widget, &padding);
 
-  get_menu_padding (widget, &padding);
+          min_height = nat_height = padding.top + padding.bottom;
+          single_height = 0;
 
-  min_height = nat_height = padding.top + padding.bottom;
-  single_height = 0;
+          n_heights =
+            calculate_line_heights (menu, for_size, &min_heights, &nat_heights);
 
-  n_heights =
-    calculate_line_heights (menu, for_size, &min_heights, &nat_heights);
+          for (i = 0; i < n_heights; i++)
+            {
+              min_height += min_heights[i];
+              single_height = MAX (single_height, min_heights[i]);
+              nat_height += nat_heights[i];
+            }
 
-  for (i = 0; i < n_heights; i++)
-    {
-      min_height += min_heights[i];
-      single_height = MAX (single_height, min_heights[i]);
-      nat_height += nat_heights[i];
-    }
+          get_arrows_border (menu, &arrow_border);
+          single_height += padding.top + padding.bottom
+                           + arrow_border.top + arrow_border.bottom;
+          min_height = MIN (min_height, single_height);
 
-  get_arrows_border (menu, &arrow_border);
-  single_height += padding.top + padding.bottom
-                   + arrow_border.top + arrow_border.bottom;
-  min_height = MIN (min_height, single_height);
+          if (priv->have_position)
+            {
+              GdkDisplay *display;
+              GdkMonitor *monitor;
+              GdkRectangle workarea;
+              GtkBorder border;
 
-  if (priv->have_position)
-    {
-      GdkDisplay *display;
-      GdkMonitor *monitor;
-      GdkRectangle workarea;
-      GtkBorder border;
+              display = gtk_widget_get_display (priv->toplevel);
+              monitor = gdk_display_get_monitor (display, priv->monitor_num);
+              gdk_monitor_get_workarea (monitor, &workarea);
 
-      display = gtk_widget_get_display (priv->toplevel);
-      monitor = gdk_display_get_monitor (display, priv->monitor_num);
-      gdk_monitor_get_workarea (monitor, &workarea);
+              if (priv->position_y + min_height > workarea.y + workarea.height)
+                min_height = workarea.y + workarea.height - priv->position_y;
 
-      if (priv->position_y + min_height > workarea.y + workarea.height)
-        min_height = workarea.y + workarea.height - priv->position_y;
+              if (priv->position_y + nat_height > workarea.y + workarea.height)
+                nat_height = workarea.y + workarea.height - priv->position_y;
 
-      if (priv->position_y + nat_height > workarea.y + workarea.height)
-        nat_height = workarea.y + workarea.height - priv->position_y;
+              _gtk_window_get_shadow_width (GTK_WINDOW (priv->toplevel), &border);
 
-      _gtk_window_get_shadow_width (GTK_WINDOW (priv->toplevel), &border);
+              if (priv->position_y + border.top < workarea.y)
+                {
+                  min_height -= workarea.y - (priv->position_y + border.top);
+                  nat_height -= workarea.y - (priv->position_y + border.top);
+                }
+            }
 
-      if (priv->position_y + border.top < workarea.y)
-        {
-          min_height -= workarea.y - (priv->position_y + border.top);
-          nat_height -= workarea.y - (priv->position_y + border.top);
-        }
-    }
+          *minimum = min_height;
+          *natural = nat_height;
+
+          g_free (min_heights);
+          g_free (nat_heights);
 
-  *minimum_size = min_height;
-  *natural_size = nat_height;
 
-  g_free (min_heights);
-  g_free (nat_heights);
+        }
+    }
 }
 
 static gboolean
diff --git a/gtk/gtkmenubar.c b/gtk/gtkmenubar.c
index bdf2ce0..c1feaff 100644
--- a/gtk/gtkmenubar.c
+++ b/gtk/gtkmenubar.c
@@ -85,20 +85,13 @@ static void gtk_menu_bar_get_property      (GObject             *object,
                                            GValue              *value,
                                            GParamSpec          *pspec);
 static void gtk_menu_bar_finalize          (GObject             *object);
-static void gtk_menu_bar_get_preferred_width (GtkWidget     *widget,
-                                             gint          *minimum,
-                                             gint          *natural);
-static void gtk_menu_bar_get_preferred_height (GtkWidget    *widget,
-                                              gint         *minimum,
-                                              gint         *natural);
-static void gtk_menu_bar_get_preferred_width_for_height (GtkWidget    *widget,
-                                                         gint          height,
-                                                         gint         *minimum,
-                                                         gint         *natural);
-static void gtk_menu_bar_get_preferred_height_for_width (GtkWidget    *widget,
-                                                         gint          width,
-                                                         gint         *minimum,
-                                                         gint         *natural);
+static void gtk_menu_bar_measure_ (GtkWidget     *widget,
+                                  GtkOrientation  orientation,
+                                  int             for_size,
+                                  int            *minimum,
+                                  int            *natural,
+                                  int            *minimum_baseline,
+                                  int            *natural_baseline);
 static void gtk_menu_bar_size_allocate     (GtkWidget       *widget,
                                            GtkAllocation   *allocation);
 static gint gtk_menu_bar_draw              (GtkWidget       *widget,
@@ -149,10 +142,7 @@ gtk_menu_bar_class_init (GtkMenuBarClass *class)
   gobject_class->set_property = gtk_menu_bar_set_property;
   gobject_class->finalize = gtk_menu_bar_finalize;
 
-  widget_class->get_preferred_width = gtk_menu_bar_get_preferred_width;
-  widget_class->get_preferred_height = gtk_menu_bar_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_menu_bar_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_menu_bar_get_preferred_height_for_width;
+  widget_class->measure = gtk_menu_bar_measure_;
   widget_class->size_allocate = gtk_menu_bar_size_allocate;
   widget_class->draw = gtk_menu_bar_draw;
   widget_class->hierarchy_changed = gtk_menu_bar_hierarchy_changed;
@@ -374,7 +364,11 @@ gtk_menu_bar_measure (GtkCssGadget   *gadget,
 
       if (gtk_widget_get_visible (child))
         {
-          _gtk_widget_get_preferred_size_for_size (child, orientation, size, &child_minimum, &child_natural, 
NULL, NULL);
+          gtk_widget_measure (child,
+                              orientation,
+                              size,
+                              &child_minimum, &child_natural,
+                              NULL, NULL);
 
           if (use_toggle_size)
             {
@@ -402,53 +396,19 @@ gtk_menu_bar_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_menu_bar_get_preferred_width (GtkWidget *widget,
-                                 gint      *minimum,
-                                 gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_menu_bar_get_preferred_height (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_menu_bar_get_preferred_width_for_height (GtkWidget *widget,
-                                             gint       height,
-                                             gint      *minimum,
-                                             gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_menu_bar_get_preferred_height_for_width (GtkWidget *widget,
-                                             gint       width,
-                                             gint      *minimum,
-                                             gint      *natural)
+gtk_menu_bar_measure_ (GtkWidget      *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_MENU_BAR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
diff --git a/gtk/gtkmenuitem.c b/gtk/gtkmenuitem.c
index b989d32..9330a44 100644
--- a/gtk/gtkmenuitem.c
+++ b/gtk/gtkmenuitem.c
@@ -560,41 +560,22 @@ gtk_menu_item_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_menu_item_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum_size,
-                                   gint      *natural_size)
+gtk_menu_item_measure_ (GtkWidget      *widget,
+                        GtkOrientation  orientation,
+                        int             for_size,
+                        int            *minimum,
+                        int            *natural,
+                        int            *minimum_baseline,
+                        int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_MENU_ITEM (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
 }
 
-static void
-gtk_menu_item_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum_size,
-                                    gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_MENU_ITEM (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
 
-static void
-gtk_menu_item_get_preferred_height_for_width (GtkWidget *widget,
-                                              gint       for_size,
-                                              gint      *minimum_size,
-                                              gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_MENU_ITEM (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     for_size,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
 
 static void
 gtk_menu_item_class_init (GtkMenuItemClass *klass)
@@ -620,9 +601,7 @@ gtk_menu_item_class_init (GtkMenuItemClass *klass)
   widget_class->mnemonic_activate = gtk_menu_item_mnemonic_activate;
   widget_class->parent_set = gtk_menu_item_parent_set;
   widget_class->can_activate_accel = gtk_menu_item_can_activate_accel;
-  widget_class->get_preferred_width = gtk_menu_item_get_preferred_width;
-  widget_class->get_preferred_height = gtk_menu_item_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_menu_item_get_preferred_height_for_width;
+  widget_class->measure = gtk_menu_item_measure_;
   widget_class->direction_changed = gtk_menu_item_direction_changed;
 
   container_class->forall = gtk_menu_item_forall;
diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c
index 9fe21e7..9cc190a 100644
--- a/gtk/gtkmodelbutton.c
+++ b/gtk/gtkmodelbutton.c
@@ -632,10 +632,13 @@ needs_indicator (GtkModelButton *button)
 }
 
 static void
-gtk_model_button_get_preferred_width_for_height (GtkWidget *widget,
-                                                 gint       height,
-                                                 gint      *minimum,
-                                                 gint      *natural)
+gtk_model_button_measure_ (GtkWidget      *widget,
+                           GtkOrientation  orientation,
+                           int             for_size,
+                           int            *minimum,
+                           int            *natural,
+                           int            *minimum_baseline,
+                           int            *natural_baseline)
 {
   GtkCssGadget *gadget;
 
@@ -645,93 +648,13 @@ gtk_model_button_get_preferred_width_for_height (GtkWidget *widget,
     gadget = GTK_MODEL_BUTTON (widget)->gadget;
 
   gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_model_button_get_preferred_width (GtkWidget *widget,
-                                      gint      *minimum,
-                                      gint      *natural)
-{
-  GtkCssGadget *gadget;
-
-  if (GTK_MODEL_BUTTON (widget)->iconic)
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-  else
-    gadget = GTK_MODEL_BUTTON (widget)->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_model_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                              gint       width,
-                                                              gint      *minimum,
-                                                              gint      *natural,
-                                                              gint      *minimum_baseline,
-                                                              gint      *natural_baseline)
-{
-  GtkCssGadget *gadget;
-
-  if (GTK_MODEL_BUTTON (widget)->iconic)
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-  else
-    gadget = GTK_MODEL_BUTTON (widget)->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
 
 static void
-gtk_model_button_get_preferred_height_for_width (GtkWidget *widget,
-                                                 gint       width,
-                                                 gint      *minimum,
-                                                 gint      *natural)
-{
-  GtkCssGadget *gadget;
-
-  if (GTK_MODEL_BUTTON (widget)->iconic)
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-  else
-    gadget = GTK_MODEL_BUTTON (widget)->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_model_button_get_preferred_height (GtkWidget *widget,
-                                       gint      *minimum,
-                                       gint      *natural)
-{
-  GtkCssGadget *gadget;
-
-  if (GTK_MODEL_BUTTON (widget)->iconic)
-    gadget = GTK_BUTTON (widget)->priv->gadget;
-  else
-    gadget = GTK_MODEL_BUTTON (widget)->gadget;
-
-  gtk_css_gadget_get_preferred_size (gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
 gtk_model_button_measure (GtkCssGadget   *gadget,
                           GtkOrientation  orientation,
                           int             for_size,
@@ -761,11 +684,11 @@ gtk_model_button_measure (GtkCssGadget   *gadget,
 
       if (child && gtk_widget_get_visible (child))
         {
-          _gtk_widget_get_preferred_size_for_size (child,
-                                                   GTK_ORIENTATION_HORIZONTAL,
-                                                   for_size,
-                                                   minimum, natural,
-                                                   minimum_baseline, natural_baseline);
+          gtk_widget_measure (child,
+                              orientation,
+                              for_size,
+                              minimum, natural,
+                              minimum_baseline, natural_baseline);
         }
       else
         {
@@ -1073,11 +996,7 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
   object_class->get_property = gtk_model_button_get_property;
   object_class->set_property = gtk_model_button_set_property;
 
-  widget_class->get_preferred_width = gtk_model_button_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_model_button_get_preferred_width_for_height;
-  widget_class->get_preferred_height = gtk_model_button_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_model_button_get_preferred_height_for_width;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_model_button_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_model_button_measure_;
   widget_class->size_allocate = gtk_model_button_size_allocate;
   widget_class->draw = gtk_model_button_draw;
   widget_class->destroy = gtk_model_button_destroy;
diff --git a/gtk/gtknotebook.c b/gtk/gtknotebook.c
index c7755db..9e768b1 100644
--- a/gtk/gtknotebook.c
+++ b/gtk/gtknotebook.c
@@ -361,22 +361,13 @@ static void gtk_notebook_map                 (GtkWidget        *widget);
 static void gtk_notebook_unmap               (GtkWidget        *widget);
 static void gtk_notebook_realize             (GtkWidget        *widget);
 static void gtk_notebook_unrealize           (GtkWidget        *widget);
-static void gtk_notebook_get_preferred_width (GtkWidget        *widget,
-                                              gint             *minimum,
-                                              gint             *natural);
-static void gtk_notebook_get_preferred_height(GtkWidget        *widget,
-                                              gint             *minimum,
-                                              gint             *natural);
-static void gtk_notebook_get_preferred_width_for_height
-                                             (GtkWidget        *widget,
-                                              gint              height,
-                                              gint             *minimum,
-                                              gint             *natural);
-static void gtk_notebook_get_preferred_height_for_width
-                                             (GtkWidget        *widget,
-                                              gint              width,
-                                              gint             *minimum,
-                                              gint             *natural);
+static void gtk_notebook_measure (GtkWidget      *widget,
+                                  GtkOrientation  orientation,
+                                  int             for_size,
+                                  int            *minimum,
+                                  int            *natural,
+                                  int            *minimum_baseline,
+                                  int            *natural_baseline);
 static void gtk_notebook_size_allocate       (GtkWidget        *widget,
                                               GtkAllocation    *allocation);
 static gboolean gtk_notebook_draw            (GtkWidget        *widget,
@@ -711,10 +702,7 @@ gtk_notebook_class_init (GtkNotebookClass *class)
   widget_class->unmap = gtk_notebook_unmap;
   widget_class->realize = gtk_notebook_realize;
   widget_class->unrealize = gtk_notebook_unrealize;
-  widget_class->get_preferred_width = gtk_notebook_get_preferred_width;
-  widget_class->get_preferred_height = gtk_notebook_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_notebook_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_notebook_get_preferred_height_for_width;
+  widget_class->measure = gtk_notebook_measure;
   widget_class->size_allocate = gtk_notebook_size_allocate;
   widget_class->draw = gtk_notebook_draw;
   widget_class->button_press_event = gtk_notebook_button_press;
@@ -2254,64 +2242,34 @@ gtk_notebook_measure_stack (GtkCssGadget   *gadget,
 
       if (gtk_widget_get_visible (page->child))
         {
-          _gtk_widget_get_preferred_size_for_size (page->child,
-                                                   orientation,
-                                                   size, 
-                                                   &child_minimum,
-                                                   &child_natural,
-                                                   NULL,
-                                                   NULL);
+          gtk_widget_measure (page->child,
+                              orientation,
+                              size,
+                              &child_minimum, &child_natural,
+                              NULL, NULL);
 
           *minimum = MAX (*minimum, child_minimum);
           *natural = MAX (*natural, child_natural);
         }
     }
 }
-
-static void
-gtk_notebook_get_preferred_width_for_height (GtkWidget *widget,
-                                             gint       height,
-                                             gint      *minimum,
-                                             gint      *natural)
-{
-  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
-  GtkNotebookPrivate *priv = notebook->priv;
-
-  gtk_css_gadget_get_preferred_size (priv->gadget, GTK_ORIENTATION_HORIZONTAL, height, minimum, natural, 
NULL, NULL);
-}
-
-static void
-gtk_notebook_get_preferred_height_for_width (GtkWidget *widget,
-                                             gint       width,
-                                             gint      *minimum,
-                                             gint      *natural)
-{
-  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
-  GtkNotebookPrivate *priv = notebook->priv;
-
-  gtk_css_gadget_get_preferred_size (priv->gadget, GTK_ORIENTATION_VERTICAL, width, minimum, natural, NULL, 
NULL);
-}
-
-static void
-gtk_notebook_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
-{
-  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
-  GtkNotebookPrivate *priv = notebook->priv;
-
-  gtk_css_gadget_get_preferred_size (priv->gadget, GTK_ORIENTATION_HORIZONTAL, -1, minimum, natural, NULL, 
NULL);
-}
-
 static void
-gtk_notebook_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
+gtk_notebook_measure (GtkWidget      *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
 {
   GtkNotebook *notebook = GTK_NOTEBOOK (widget);
   GtkNotebookPrivate *priv = notebook->priv;
 
-  gtk_css_gadget_get_preferred_size (priv->gadget, GTK_ORIENTATION_VERTICAL, -1, minimum, natural, NULL, 
NULL);
+  gtk_css_gadget_get_preferred_size (priv->gadget,
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -4530,11 +4488,11 @@ measure_tab (GtkCssGadget           *gadget,
 {
   GtkNotebookPage *page = data;
 
-  _gtk_widget_get_preferred_size_for_size (page->tab_label,
-                                           orientation,
-                                           for_size,
-                                           minimum, natural,
-                                           minimum_baseline, natural_baseline);
+  gtk_widget_measure (page->tab_label,
+                      orientation,
+                      for_size,
+                      minimum, natural,
+                      minimum_baseline, natural_baseline);
 }
 
 static void
diff --git a/gtk/gtkoffscreenwindow.c b/gtk/gtkoffscreenwindow.c
index 367927f..1c6204c 100644
--- a/gtk/gtkoffscreenwindow.c
+++ b/gtk/gtkoffscreenwindow.c
@@ -50,65 +50,37 @@
 G_DEFINE_TYPE (GtkOffscreenWindow, gtk_offscreen_window, GTK_TYPE_WINDOW);
 
 static void
-gtk_offscreen_window_get_preferred_width (GtkWidget *widget,
-                                         gint      *minimum,
-                                         gint      *natural)
+gtk_offscreen_window_measure (GtkWidget      *widget,
+                              GtkOrientation  orientation,
+                              int             for_size,
+                              int            *minimum,
+                              int            *natural,
+                              int            *minimum_baseline,
+                              int            *natural_baseline)
 {
   GtkBin *bin = GTK_BIN (widget);
-  GtkWidget *child;
-  gint default_width;
+  GtkWidget *child = gtk_bin_get_child (bin);
+  int default_size;
 
   *minimum = 0;
   *natural = 0;
 
-  child = gtk_bin_get_child (bin);
-
   if (child != NULL && gtk_widget_get_visible (child))
     {
-      gint child_min, child_nat;
-
-      gtk_widget_get_preferred_width (child, &child_min, &child_nat);
-
-      *minimum += child_min;
-      *natural += child_nat;
-    }
-
-  gtk_window_get_default_size (GTK_WINDOW (widget),
-                               &default_width, NULL);
-
-  *minimum = MAX (*minimum, default_width);
-  *natural = MAX (*natural, default_width);
-}
-
-static void
-gtk_offscreen_window_get_preferred_height (GtkWidget *widget,
-                                          gint      *minimum,
-                                          gint      *natural)
-{
-  GtkBin *bin = GTK_BIN (widget);
-  GtkWidget *child;
-  gint default_height;
-
-  *minimum = 0;
-  *natural = 0;
-
-  child = gtk_bin_get_child (bin);
-
-  if (child != NULL && gtk_widget_get_visible (child))
-    {
-      gint child_min, child_nat;
-
-      gtk_widget_get_preferred_height (child, &child_min, &child_nat);
+      int child_min, child_nat;
 
+      gtk_widget_measure (child, orientation, for_size, &child_min, &child_nat, NULL, NULL);
       *minimum += child_min;
       *natural += child_nat;
     }
 
-  gtk_window_get_default_size (GTK_WINDOW (widget),
-                               NULL, &default_height);
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    gtk_window_get_default_size (GTK_WINDOW (widget), &default_size, NULL);
+  else
+    gtk_window_get_default_size (GTK_WINDOW (widget), NULL, &default_size);
 
-  *minimum = MAX (*minimum, default_height);
-  *natural = MAX (*natural, default_height);
+  *minimum = MAX (*minimum, default_size);
+  *natural = MAX (*natural, default_size);
 }
 
 static void
@@ -250,8 +222,7 @@ gtk_offscreen_window_class_init (GtkOffscreenWindowClass *class)
   widget_class->realize = gtk_offscreen_window_realize;
   widget_class->show = gtk_offscreen_window_show;
   widget_class->hide = gtk_offscreen_window_hide;
-  widget_class->get_preferred_width = gtk_offscreen_window_get_preferred_width;
-  widget_class->get_preferred_height = gtk_offscreen_window_get_preferred_height;
+  widget_class->measure = gtk_offscreen_window_measure;
   widget_class->size_allocate = gtk_offscreen_window_size_allocate;
 
   container_class->check_resize = gtk_offscreen_window_check_resize;
diff --git a/gtk/gtkpaned.c b/gtk/gtkpaned.c
index 5ecc415..088b6c7 100644
--- a/gtk/gtkpaned.c
+++ b/gtk/gtkpaned.c
@@ -205,24 +205,13 @@ static void     gtk_paned_get_child_property    (GtkContainer     *container,
                                                  GValue           *value,
                                                  GParamSpec       *pspec);
 static void     gtk_paned_finalize              (GObject          *object);
-
-static void     gtk_paned_get_preferred_width   (GtkWidget        *widget,
-                                                 gint             *minimum,
-                                                 gint             *natural);
-static void     gtk_paned_get_preferred_height  (GtkWidget        *widget,
-                                                 gint             *minimum,
-                                                 gint             *natural);
-static void     gtk_paned_get_preferred_width_for_height
-                                                (GtkWidget        *widget,
-                                                 gint              height,
-                                                 gint             *minimum,
-                                                 gint             *natural);
-static void     gtk_paned_get_preferred_height_for_width
-                                                (GtkWidget        *widget,
-                                                 gint              width,
-                                                 gint             *minimum,
-                                                 gint              *natural);
-
+static void     gtk_paned_measure_ (GtkWidget *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 static void     gtk_paned_size_allocate         (GtkWidget        *widget,
                                                  GtkAllocation    *allocation);
 static void     gtk_paned_realize               (GtkWidget        *widget);
@@ -326,10 +315,7 @@ gtk_paned_class_init (GtkPanedClass *class)
   object_class->get_property = gtk_paned_get_property;
   object_class->finalize = gtk_paned_finalize;
 
-  widget_class->get_preferred_width = gtk_paned_get_preferred_width;
-  widget_class->get_preferred_height = gtk_paned_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_paned_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_paned_get_preferred_height_for_width;
+  widget_class->measure = gtk_paned_measure_;
   widget_class->size_allocate = gtk_paned_size_allocate;
   widget_class->realize = gtk_paned_realize;
   widget_class->unrealize = gtk_paned_unrealize;
@@ -1056,7 +1042,7 @@ gtk_paned_get_preferred_size_for_orientation (GtkWidget      *widget,
 
   if (priv->child1 && gtk_widget_get_visible (priv->child1))
     {
-      _gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, size, &child_min, 
&child_nat, NULL, NULL);
+      gtk_widget_measure (priv->child1, priv->orientation, size, &child_min, &child_nat, NULL, NULL);
       if (priv->child1_shrink)
         *minimum = 0;
       else
@@ -1066,7 +1052,7 @@ gtk_paned_get_preferred_size_for_orientation (GtkWidget      *widget,
 
   if (priv->child2 && gtk_widget_get_visible (priv->child2))
     {
-      _gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, size, &child_min, 
&child_nat, NULL, NULL);
+      gtk_widget_measure (priv->child2, priv->orientation, size, &child_min, &child_nat, NULL, NULL);
 
       if (!priv->child2_shrink)
         *minimum += child_min;
@@ -1113,8 +1099,8 @@ gtk_paned_get_preferred_size_for_opposite_orientation (GtkWidget      *widget,
                                          NULL, &handle_size,
                                          NULL, NULL);
 
-      _gtk_widget_get_preferred_size_for_size (priv->child1, priv->orientation, -1, &child1_req, NULL, NULL, 
NULL);
-      _gtk_widget_get_preferred_size_for_size (priv->child2, priv->orientation, -1, &child2_req, NULL, NULL, 
NULL);
+      gtk_widget_measure (priv->child1, priv->orientation, -1, &child1_req, NULL, NULL, NULL);
+      gtk_widget_measure (priv->child2, priv->orientation, -1, &child2_req, NULL, NULL, NULL);
 
       gtk_paned_compute_position (paned,
                                   size - handle_size, child1_req, child2_req,
@@ -1132,23 +1118,23 @@ gtk_paned_get_preferred_size_for_opposite_orientation (GtkWidget      *widget,
 
   if (priv->child1 && gtk_widget_get_visible (priv->child1))
     {
-      _gtk_widget_get_preferred_size_for_size (priv->child1,
-                                               OPPOSITE_ORIENTATION (priv->orientation),
-                                               for_child1,
-                                               &child_min, &child_nat,
-                                               NULL, NULL);
-      
+      gtk_widget_measure (priv->child1,
+                          OPPOSITE_ORIENTATION (priv->orientation),
+                          for_child1,
+                          &child_min, &child_nat,
+                          NULL, NULL);
+
       *minimum = child_min;
       *natural = child_nat;
     }
 
   if (priv->child2 && gtk_widget_get_visible (priv->child2))
     {
-      _gtk_widget_get_preferred_size_for_size (priv->child2,
-                                               OPPOSITE_ORIENTATION (priv->orientation),
-                                               for_child2,
-                                               &child_min, &child_nat,
-                                               NULL, NULL);
+      gtk_widget_measure (priv->child2,
+                          OPPOSITE_ORIENTATION (priv->orientation),
+                          for_child2,
+                          &child_min, &child_nat,
+                          NULL, NULL);
 
       *minimum = MAX (*minimum, child_min);
       *natural = MAX (*natural, child_nat);
@@ -1176,53 +1162,19 @@ gtk_paned_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_paned_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_PANED (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_paned_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_PANED (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_paned_get_preferred_width_for_height (GtkWidget *widget,
-                                          gint       height,
-                                          gint      *minimum,
-                                          gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_PANED (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_paned_get_preferred_height_for_width (GtkWidget *widget,
-                                          gint       width,
-                                          gint      *minimum,
-                                          gint      *natural)
+gtk_paned_measure_ (GtkWidget *widget,
+                   GtkOrientation  orientation,
+                   int             for_size,
+                   int            *minimum,
+                   int            *natural,
+                   int            *minimum_baseline,
+                   int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_PANED (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
diff --git a/gtk/gtkpathbar.c b/gtk/gtkpathbar.c
index e8a90bf..7ad0c83 100644
--- a/gtk/gtkpathbar.c
+++ b/gtk/gtkpathbar.c
@@ -117,12 +117,13 @@ static void gtk_path_bar_finalize                 (GObject          *object);
 static void gtk_path_bar_dispose                  (GObject          *object);
 static void gtk_path_bar_realize                  (GtkWidget        *widget);
 static void gtk_path_bar_unrealize                (GtkWidget        *widget);
-static void gtk_path_bar_get_preferred_width      (GtkWidget        *widget,
-                                                   gint             *minimum,
-                                                   gint             *natural);
-static void gtk_path_bar_get_preferred_height     (GtkWidget        *widget,
-                                                   gint             *minimum,
-                                                   gint             *natural);
+static void gtk_path_bar_measure (GtkWidget *widget,
+                                  GtkOrientation  orientation,
+                                  int             for_size,
+                                  int            *minimum,
+                                  int            *natural,
+                                  int            *minimum_baseline,
+                                  int            *natural_baseline);
 static void gtk_path_bar_map                      (GtkWidget        *widget);
 static void gtk_path_bar_unmap                    (GtkWidget        *widget);
 static void gtk_path_bar_size_allocate            (GtkWidget        *widget,
@@ -221,8 +222,7 @@ gtk_path_bar_class_init (GtkPathBarClass *path_bar_class)
   gobject_class->finalize = gtk_path_bar_finalize;
   gobject_class->dispose = gtk_path_bar_dispose;
 
-  widget_class->get_preferred_width = gtk_path_bar_get_preferred_width;
-  widget_class->get_preferred_height = gtk_path_bar_get_preferred_height;
+  widget_class->measure = gtk_path_bar_measure;
   widget_class->realize = gtk_path_bar_realize;
   widget_class->unrealize = gtk_path_bar_unrealize;
   widget_class->map = gtk_path_bar_map;
@@ -328,94 +328,89 @@ gtk_path_bar_dispose (GObject *object)
  * Ideally, our size is determined by another widget, and we are just filling
  * available space.
  */
+
 static void
-gtk_path_bar_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
+gtk_path_bar_measure (GtkWidget *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
 {
+  GtkPathBar *path_bar = GTK_PATH_BAR (widget);
   ButtonData *button_data;
-  GtkPathBar *path_bar;
   GList *list;
-  gint child_height;
-  gint height;
-  gint child_min, child_nat;
+  int child_size;
+  int size = 0;
+  int child_min, child_nat;
 
-  path_bar = GTK_PATH_BAR (widget);
+  *minimum = 0;
+  *natural = 0;
 
-  *minimum = *natural = 0;
-  height = 0;
 
-  for (list = path_bar->priv->button_list; list; list = list->next)
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
-      button_data = BUTTON_DATA (list->data);
-      gtk_widget_get_preferred_width (button_data->button, &child_min, &child_nat);
-      gtk_widget_get_preferred_height (button_data->button, &child_height, NULL);
-      height = MAX (height, child_height);
-
-      if (button_data->type == NORMAL_BUTTON)
+      for (list = path_bar->priv->button_list; list; list = list->next)
         {
-          /* Use 2*Height as button width because of ellipsized label.  */
-          child_min = MAX (child_min, child_height * 2);
-          child_nat = MAX (child_min, child_height * 2);
+          button_data = BUTTON_DATA (list->data);
+          gtk_widget_get_preferred_width (button_data->button, &child_min, &child_nat);
+          gtk_widget_get_preferred_height (button_data->button, &child_size, NULL);
+          size = MAX (size, child_size);
+
+          if (button_data->type == NORMAL_BUTTON)
+            {
+              /* Use 2*Height as button width because of ellipsized label.  */
+              child_min = MAX (child_min, child_size * 2);
+              child_nat = MAX (child_min, child_size * 2);
+            }
+
+          *minimum = MAX (*minimum, child_min);
+          *natural = *natural + child_nat;
         }
 
-      *minimum = MAX (*minimum, child_min);
-      *natural = *natural + child_nat;
-    }
+      /* Add space for slider, if we have more than one path */
+      /* Theoretically, the slider could be bigger than the other button.  But we're
+       * not going to worry about that now.
+       */
+      path_bar->priv->slider_width = 0;
 
-  /* Add space for slider, if we have more than one path */
-  /* Theoretically, the slider could be bigger than the other button.  But we're
-   * not going to worry about that now.
-   */
-  path_bar->priv->slider_width = 0;
+      gtk_widget_get_preferred_width (path_bar->priv->up_slider_button, &child_min, &child_nat);
+      if (path_bar->priv->button_list && path_bar->priv->button_list->next != NULL)
+        {
+          *minimum += child_min;
+          *natural += child_nat;
+        }
+      path_bar->priv->slider_width = MAX (path_bar->priv->slider_width, child_min);
 
-  gtk_widget_get_preferred_width (path_bar->priv->up_slider_button, &child_min, &child_nat);
-  if (path_bar->priv->button_list && path_bar->priv->button_list->next != NULL)
-    {
-      *minimum += child_min;
-      *natural += child_nat;
-    }
-  path_bar->priv->slider_width = MAX (path_bar->priv->slider_width, child_min);
+      gtk_widget_get_preferred_width (path_bar->priv->down_slider_button, &child_min, &child_nat);
+      if (path_bar->priv->button_list && path_bar->priv->button_list->next != NULL)
+        {
+          *minimum += child_min;
+          *natural += child_nat;
+        }
+      path_bar->priv->slider_width = MAX (path_bar->priv->slider_width, child_min);
 
-  gtk_widget_get_preferred_width (path_bar->priv->down_slider_button, &child_min, &child_nat);
-  if (path_bar->priv->button_list && path_bar->priv->button_list->next != NULL)
-    {
-      *minimum += child_min;
-      *natural += child_nat;
     }
-  path_bar->priv->slider_width = MAX (path_bar->priv->slider_width, child_min);
-}
-
-static void
-gtk_path_bar_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  ButtonData *button_data;
-  GtkPathBar *path_bar;
-  GList *list;
-  gint child_min, child_nat;
-
-  path_bar = GTK_PATH_BAR (widget);
+  else /* VERTICAL */
+    {
+      for (list = path_bar->priv->button_list; list; list = list->next)
+        {
+          button_data = BUTTON_DATA (list->data);
+          gtk_widget_get_preferred_height (button_data->button, &child_min, &child_nat);
 
-  *minimum = *natural = 0;
+          *minimum = MAX (*minimum, child_min);
+          *natural = MAX (*natural, child_nat);
+        }
 
-  for (list = path_bar->priv->button_list; list; list = list->next)
-    {
-      button_data = BUTTON_DATA (list->data);
-      gtk_widget_get_preferred_height (button_data->button, &child_min, &child_nat);
+      gtk_widget_get_preferred_height (path_bar->priv->up_slider_button, &child_min, &child_nat);
+      *minimum = MAX (*minimum, child_min);
+      *natural = MAX (*natural, child_nat);
 
+      gtk_widget_get_preferred_height (path_bar->priv->down_slider_button, &child_min, &child_nat);
       *minimum = MAX (*minimum, child_min);
       *natural = MAX (*natural, child_nat);
     }
-
-  gtk_widget_get_preferred_height (path_bar->priv->up_slider_button, &child_min, &child_nat);
-  *minimum = MAX (*minimum, child_min);
-  *natural = MAX (*natural, child_nat);
-
-  gtk_widget_get_preferred_height (path_bar->priv->down_slider_button, &child_min, &child_nat);
-  *minimum = MAX (*minimum, child_min);
-  *natural = MAX (*natural, child_nat);
 }
 
 static void
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 97df45b..743f8a2 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -1241,145 +1241,69 @@ get_minimal_size (GtkPopover     *popover,
 }
 
 static void
-gtk_popover_get_preferred_width (GtkWidget *widget,
-                                 gint      *minimum_width,
-                                 gint      *natural_width)
+gtk_popover_measure (GtkWidget      *widget,
+                     GtkOrientation  orientation,
+                     int             for_size,
+                     int            *minimum,
+                     int            *natural,
+                     int            *minimum_baseline,
+                     int            *natural_baseline)
 {
   GtkPopover *popover = GTK_POPOVER (widget);
-  GtkWidget *child;
-  gint min, nat, extra, minimal_size;
-  GtkBorder border, margin;
-
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  min = nat = 0;
-
-  if (child)
-    gtk_widget_get_preferred_width (child, &min, &nat);
-
-  get_padding_and_border (widget, &border);
-  get_margin (widget, &margin);
-  minimal_size = get_minimal_size (popover, GTK_ORIENTATION_HORIZONTAL);
-
-  min = MAX (min, minimal_size) + border.left + border.right;
-  nat = MAX (nat, minimal_size) + border.left + border.right;
-  extra = MAX (TAIL_HEIGHT, margin.left) + MAX (TAIL_HEIGHT, margin.right);
-
-  min += extra;
-  nat += extra;
-
-  *minimum_width = min;
-  *natural_width = nat;
-}
-
-static void
-gtk_popover_get_preferred_width_for_height (GtkWidget *widget,
-                                            gint       height,
-                                            gint      *minimum_width,
-                                            gint      *natural_width)
-{
-  GtkPopover *popover = GTK_POPOVER (widget);
-  GtkWidget *child;
-  GdkRectangle child_rect;
-  gint min, nat, extra, minimal_size;
-  gint child_height;
+  GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
   GtkBorder border, margin;
-
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  min = nat = 0;
-
-  gtk_popover_get_rect_for_size (popover, 0, height, &child_rect);
-  child_height = child_rect.height;
-
+  int minimal_size, extra;
 
   get_padding_and_border (widget, &border);
   get_margin (widget, &margin);
-  child_height -= border.top + border.bottom;
-  minimal_size = get_minimal_size (popover, GTK_ORIENTATION_HORIZONTAL);
-
-  if (child)
-    gtk_widget_get_preferred_width_for_height (child, child_height, &min, &nat);
-
-  min = MAX (min, minimal_size) + border.left + border.right;
-  nat = MAX (nat, minimal_size) + border.left + border.right;
-  extra = MAX (TAIL_HEIGHT, margin.left) + MAX (TAIL_HEIGHT, margin.right);
-
-  min += extra;
-  nat += extra;
-
-  *minimum_width = min;
-  *natural_width = nat;
-}
 
-static void
-gtk_popover_get_preferred_height (GtkWidget *widget,
-                                  gint      *minimum_height,
-                                  gint      *natural_height)
-{
-  GtkPopover *popover = GTK_POPOVER (widget);
-  GtkWidget *child;
-  gint min, nat, extra, minimal_size;
-  GtkBorder border, margin;
-
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  min = nat = 0;
+  *minimum = 0;
+  *natural = 0;
 
-  if (child)
-    gtk_widget_get_preferred_height (child, &min, &nat);
-
-  get_padding_and_border (widget, &border);
-  get_margin (widget, &margin);
-  minimal_size = get_minimal_size (popover, GTK_ORIENTATION_VERTICAL);
-
-  min = MAX (min, minimal_size) + border.top + border.bottom;
-  nat = MAX (nat, minimal_size) + border.top + border.bottom;
-  extra = MAX (TAIL_HEIGHT, margin.top) + MAX (TAIL_HEIGHT, margin.bottom);
-
-  min += extra;
-  nat += extra;
-
-  *minimum_height = min;
-  *natural_height = nat;
-}
-
-static void
-gtk_popover_get_preferred_height_for_width (GtkWidget *widget,
-                                            gint       width,
-                                            gint      *minimum_height,
-                                            gint      *natural_height)
-{
-  GtkPopover *popover = GTK_POPOVER (widget);
-  GtkWidget *child;
-  GdkRectangle child_rect;
-  gint min, nat, extra, minimal_size;
-  gint child_width;
-  GtkBorder border, margin;
-
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  min = nat = 0;
-
-  get_padding_and_border (widget, &border);
-  get_margin (widget, &margin);
+  if (child != NULL)
+    {
+      if (for_size >= 0)
+        {
+          int child_size;
+          GdkRectangle child_rect;
 
-  gtk_popover_get_rect_for_size (popover, width, 0, &child_rect);
-  child_width = child_rect.width;
+          if (orientation == GTK_ORIENTATION_HORIZONTAL)
+            {
+              gtk_popover_get_rect_for_size (popover, for_size, 0, &child_rect);
+              child_size = child_rect.width;
+            }
+          else
+            {
+              gtk_popover_get_rect_for_size (popover, 0, for_size, &child_rect);
+              child_size = child_rect.height;
+            }
 
-  child_width -= border.left + border.right;
-  minimal_size = get_minimal_size (popover, GTK_ORIENTATION_VERTICAL);
-  if (child)
-    gtk_widget_get_preferred_height_for_width (child, child_width, &min, &nat);
+          gtk_widget_measure (child, orientation, child_size, minimum, natural, NULL, NULL);
 
-  min = MAX (min, minimal_size) + border.top + border.bottom;
-  nat = MAX (nat, minimal_size) + border.top + border.bottom;
-  extra = MAX (TAIL_HEIGHT, margin.top) + MAX (TAIL_HEIGHT, margin.bottom);
+        }
+      else
+        {
+          gtk_widget_measure (child, orientation, -1, minimum, natural, NULL, NULL);
+        }
+    }
 
-  min += extra;
-  nat += extra;
+  minimal_size = get_minimal_size (popover, orientation);
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      *minimum = MAX (*minimum, minimal_size) + border.left + border.right;
+      *natural = MAX (*natural, minimal_size) + border.left + border.right;
+      extra = MAX (TAIL_HEIGHT, margin.left) + MAX (TAIL_HEIGHT, margin.right);
+    }
+  else
+    {
+      *minimum = MAX (*minimum, minimal_size) + border.top + border.bottom;
+      *natural = MAX (*natural, minimal_size) + border.top + border.bottom;
+      extra = MAX (TAIL_HEIGHT, margin.bottom) + MAX (TAIL_HEIGHT, margin.top);
 
-  if (minimum_height)
-    *minimum_height = min;
+    }
 
-  if (natural_height)
-    *natural_height = nat;
+  *minimum += extra;
+  *natural += extra;
 }
 
 static void
@@ -1635,10 +1559,7 @@ gtk_popover_class_init (GtkPopoverClass *klass)
   widget_class->realize = gtk_popover_realize;
   widget_class->map = gtk_popover_map;
   widget_class->unmap = gtk_popover_unmap;
-  widget_class->get_preferred_width = gtk_popover_get_preferred_width;
-  widget_class->get_preferred_height = gtk_popover_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_popover_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_popover_get_preferred_height_for_width;
+  widget_class->measure = gtk_popover_measure;
   widget_class->size_allocate = gtk_popover_size_allocate;
   widget_class->draw = gtk_popover_draw;
   widget_class->button_press_event = gtk_popover_button_press;
diff --git a/gtk/gtkprogressbar.c b/gtk/gtkprogressbar.c
index 7056a31..d42f7f4 100644
--- a/gtk/gtkprogressbar.c
+++ b/gtk/gtkprogressbar.c
@@ -150,12 +150,6 @@ static void gtk_progress_bar_get_property         (GObject        *object,
                                                    GParamSpec     *pspec);
 static void gtk_progress_bar_size_allocate        (GtkWidget      *widget,
                                                    GtkAllocation  *allocation);
-static void gtk_progress_bar_get_preferred_width  (GtkWidget      *widget,
-                                                   gint           *minimum,
-                                                   gint           *natural);
-static void gtk_progress_bar_get_preferred_height (GtkWidget      *widget,
-                                                   gint           *minimum,
-                                                   gint           *natural);
 
 static gboolean gtk_progress_bar_draw             (GtkWidget      *widget,
                                                    cairo_t        *cr);
@@ -169,6 +163,13 @@ static void     gtk_progress_bar_direction_changed (GtkWidget        *widget,
 static void     gtk_progress_bar_state_flags_changed (GtkWidget      *widget,
                                                       GtkStateFlags   previous_state);
 
+static void     gtk_progress_bar_measure_          (GtkWidget           *widget,
+                                                    GtkOrientation       orientation,
+                                                    gint                 for_size,
+                                                    gint                *minimum,
+                                                    gint                *natural,
+                                                    gint                *minimum_baseline,
+                                                    gint                *natural_baseline);
 static void     gtk_progress_bar_measure           (GtkCssGadget        *gadget,
                                                     GtkOrientation       orientation,
                                                     gint                 for_size,
@@ -236,8 +237,7 @@ gtk_progress_bar_class_init (GtkProgressBarClass *class)
 
   widget_class->draw = gtk_progress_bar_draw;
   widget_class->size_allocate = gtk_progress_bar_size_allocate;
-  widget_class->get_preferred_width = gtk_progress_bar_get_preferred_width;
-  widget_class->get_preferred_height = gtk_progress_bar_get_preferred_height;
+  widget_class->measure = gtk_progress_bar_measure_;
   widget_class->direction_changed = gtk_progress_bar_direction_changed;
   widget_class->state_flags_changed = gtk_progress_bar_state_flags_changed;
 
@@ -914,28 +914,21 @@ gtk_progress_bar_allocate_trough (GtkCssGadget        *gadget,
   gtk_css_gadget_allocate (priv->progress_gadget, &alloc, -1, out_clip);
 }
 
-static void
-gtk_progress_bar_get_preferred_width (GtkWidget *widget,
-                                      gint      *minimum,
-                                      gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_PROGRESS_BAR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
 
 static void
-gtk_progress_bar_get_preferred_height (GtkWidget *widget,
-                                       gint      *minimum,
-                                       gint      *natural)
+gtk_progress_bar_measure_ (GtkWidget      *widget,
+                           GtkOrientation  orientation,
+                           int             for_size,
+                           int            *minimum,
+                           int            *natural,
+                           int            *minimum_baseline,
+                           int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_PROGRESS_BAR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static gboolean
diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c
index 6a7394b..6c881af 100644
--- a/gtk/gtkrange.c
+++ b/gtk/gtkrange.c
@@ -177,14 +177,13 @@ static void gtk_range_get_property   (GObject          *object,
                                       GParamSpec       *pspec);
 static void gtk_range_finalize       (GObject          *object);
 static void gtk_range_destroy        (GtkWidget        *widget);
-static void gtk_range_get_preferred_width
-                                     (GtkWidget        *widget,
-                                      gint             *minimum,
-                                      gint             *natural);
-static void gtk_range_get_preferred_height
-                                     (GtkWidget        *widget,
-                                      gint             *minimum,
-                                      gint             *natural);
+static void gtk_range_measure_       (GtkWidget      *widget,
+                                      GtkOrientation  orientation,
+                                      int             for_size,
+                                      int            *minimum,
+                                      int            *natural,
+                                      int            *minimum_baseline,
+                                      int            *natural_baseline);
 static void gtk_range_size_allocate  (GtkWidget        *widget,
                                       GtkAllocation    *allocation);
 static void gtk_range_realize        (GtkWidget        *widget);
@@ -323,8 +322,7 @@ gtk_range_class_init (GtkRangeClass *class)
   gobject_class->finalize = gtk_range_finalize;
 
   widget_class->destroy = gtk_range_destroy;
-  widget_class->get_preferred_width = gtk_range_get_preferred_width;
-  widget_class->get_preferred_height = gtk_range_get_preferred_height;
+  widget_class->measure = gtk_range_measure_;
   widget_class->size_allocate = gtk_range_size_allocate;
   widget_class->realize = gtk_range_realize;
   widget_class->unrealize = gtk_range_unrealize;
@@ -1677,11 +1675,13 @@ gtk_range_measure (GtkCssGadget   *gadget,
     }
 }
 
-static void
-gtk_range_size_request (GtkWidget      *widget,
-                        GtkOrientation  orientation,
-                        gint           *minimum,
-                        gint           *natural)
+static void gtk_range_measure_ (GtkWidget     *widget,
+                               GtkOrientation  orientation,
+                               int             for_size,
+                               int            *minimum,
+                               int            *natural,
+                               int            *minimum_baseline,
+                               int            *natural_baseline)
 {
   GtkRange *range = GTK_RANGE (widget);
   GtkRangePrivate *priv = range->priv;
@@ -1703,24 +1703,6 @@ gtk_range_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_range_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  gtk_range_size_request (widget, GTK_ORIENTATION_HORIZONTAL,
-                          minimum, natural);
-}
-
-static void
-gtk_range_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
-{
-  gtk_range_size_request (widget, GTK_ORIENTATION_VERTICAL,
-                          minimum, natural);
-}
-
-static void
 gtk_range_allocate_trough (GtkCssGadget        *gadget,
                            const GtkAllocation *allocation,
                            int                  baseline,
diff --git a/gtk/gtkrevealer.c b/gtk/gtkrevealer.c
index 2b54613..857cd7a 100644
--- a/gtk/gtkrevealer.c
+++ b/gtk/gtkrevealer.c
@@ -102,20 +102,13 @@ static void     gtk_revealer_real_map                            (GtkWidget
 static void     gtk_revealer_real_unmap                          (GtkWidget     *widget);
 static gboolean gtk_revealer_real_draw                           (GtkWidget     *widget,
                                                                   cairo_t       *cr);
-static void     gtk_revealer_real_get_preferred_height           (GtkWidget     *widget,
-                                                                  gint          *minimum_height,
-                                                                  gint          *natural_height);
-static void     gtk_revealer_real_get_preferred_height_for_width (GtkWidget     *widget,
-                                                                  gint           width,
-                                                                  gint          *minimum_height,
-                                                                  gint          *natural_height);
-static void     gtk_revealer_real_get_preferred_width            (GtkWidget     *widget,
-                                                                  gint          *minimum_width,
-                                                                  gint          *natural_width);
-static void     gtk_revealer_real_get_preferred_width_for_height (GtkWidget     *widget,
-                                                                  gint           height,
-                                                                  gint          *minimum_width,
-                                                                  gint          *natural_width);
+static void gtk_revealer_measure (GtkWidget      *widget,
+                                  GtkOrientation  orientation,
+                                  int             for_size,
+                                  int            *minimum,
+                                  int            *natural,
+                                  int            *minimum_baseline,
+                                  int            *natural_baseline);
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkRevealer, gtk_revealer, GTK_TYPE_BIN)
 
@@ -228,10 +221,7 @@ gtk_revealer_class_init (GtkRevealerClass *klass)
   widget_class->map = gtk_revealer_real_map;
   widget_class->unmap = gtk_revealer_real_unmap;
   widget_class->draw = gtk_revealer_real_draw;
-  widget_class->get_preferred_height = gtk_revealer_real_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_revealer_real_get_preferred_height_for_width;
-  widget_class->get_preferred_width = gtk_revealer_real_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_revealer_real_get_preferred_width_for_height;
+  widget_class->measure = gtk_revealer_measure;
 
   container_class->add = gtk_revealer_real_add;
 
@@ -783,37 +773,6 @@ set_height_with_paddings (GtkRevealer *revealer,
 }
 
 static void
-gtk_revealer_real_get_preferred_height (GtkWidget *widget,
-                                        gint      *minimum_height_out,
-                                        gint      *natural_height_out)
-{
-  GtkRevealer *revealer = GTK_REVEALER (widget);
-  gint minimum_height;
-  gint natural_height;
-
-  GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height (widget, &minimum_height, 
&natural_height);
-
-  set_height_with_paddings (revealer, minimum_height, natural_height,
-                            minimum_height_out, natural_height_out);
-}
-
-static void
-gtk_revealer_real_get_preferred_height_for_width (GtkWidget *widget,
-                                                  gint       width,
-                                                  gint      *minimum_height_out,
-                                                  gint      *natural_height_out)
-{
-  GtkRevealer *revealer = GTK_REVEALER (widget);
-  gint minimum_height;
-  gint natural_height;
-
-  GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_height_for_width (widget, width, 
&minimum_height, &natural_height);
-
-  set_height_with_paddings (revealer, minimum_height, natural_height,
-                            minimum_height_out, natural_height_out);
-}
-
-static void
 set_width_with_paddings (GtkRevealer *revealer,
                          gint         preferred_minimum_width,
                          gint         preferred_natural_width,
@@ -847,33 +806,24 @@ set_width_with_paddings (GtkRevealer *revealer,
 }
 
 static void
-gtk_revealer_real_get_preferred_width (GtkWidget *widget,
-                                       gint      *minimum_width_out,
-                                       gint      *natural_width_out)
-{
-  GtkRevealer *revealer = GTK_REVEALER (widget);
-  gint minimum_width;
-  gint natural_width;
-
-  GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width (widget, &minimum_width, &natural_width);
-  set_width_with_paddings (revealer, minimum_width, natural_width,
-                           minimum_width_out, natural_width_out);
-}
-
-static void
-gtk_revealer_real_get_preferred_width_for_height (GtkWidget *widget,
-                                                  gint       height,
-                                                  gint      *minimum_width_out,
-                                                  gint      *natural_width_out)
-{
-  GtkRevealer *revealer = GTK_REVEALER (widget);
-  gint minimum_width;
-  gint natural_width;
-
-  GTK_WIDGET_CLASS (gtk_revealer_parent_class)->get_preferred_width_for_height (widget, height, 
&minimum_width, &natural_width);
-
-  set_width_with_paddings (revealer, minimum_width, natural_width,
-                           minimum_width_out, natural_width_out);
+gtk_revealer_measure (GtkWidget      *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
+{
+  int min_size, nat_size;
+  GTK_WIDGET_CLASS (gtk_revealer_parent_class)->measure (widget,
+                                                         orientation,
+                                                         for_size,
+                                                         &min_size, &nat_size,
+                                                         NULL, NULL);
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    set_width_with_paddings (GTK_REVEALER (widget), min_size, nat_size, minimum, natural);
+  else
+    set_height_with_paddings (GTK_REVEALER (widget), min_size, nat_size, minimum, natural);
 }
 
 /**
diff --git a/gtk/gtkscale.c b/gtk/gtkscale.c
index 2ca2764..f621ab4 100644
--- a/gtk/gtkscale.c
+++ b/gtk/gtkscale.c
@@ -190,12 +190,13 @@ static void     gtk_scale_get_property            (GObject        *object,
                                                    guint           prop_id,
                                                    GValue         *value,
                                                    GParamSpec     *pspec);
-static void     gtk_scale_get_preferred_width     (GtkWidget      *widget,
-                                                   gint           *minimum,
-                                                   gint           *natural);
-static void     gtk_scale_get_preferred_height    (GtkWidget      *widget,
-                                                   gint           *minimum,
-                                                   gint           *natural);
+static void     gtk_scale_measure (GtkWidget      *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 static void     gtk_scale_get_range_border        (GtkRange       *range,
                                                    GtkBorder      *border);
 static void     gtk_scale_get_range_size_request  (GtkRange       *range,
@@ -718,8 +719,7 @@ gtk_scale_class_init (GtkScaleClass *class)
   widget_class->screen_changed = gtk_scale_screen_changed;
   widget_class->draw = gtk_scale_draw;
   widget_class->size_allocate = gtk_scale_size_allocate;
-  widget_class->get_preferred_width = gtk_scale_get_preferred_width;
-  widget_class->get_preferred_height = gtk_scale_get_preferred_height;
+  widget_class->measure = gtk_scale_measure;
 
   range_class->get_range_border = gtk_scale_get_range_border;
   range_class->get_range_size_request = gtk_scale_get_range_size_request;
@@ -1699,66 +1699,42 @@ gtk_scale_measure_marks (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_scale_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  GtkScale *scale = GTK_SCALE (widget);
-  GtkScalePrivate *priv = scale->priv;
-
-  GTK_WIDGET_CLASS (gtk_scale_parent_class)->get_preferred_width (widget, minimum, natural);
-  
-  if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_HORIZONTAL)
-    {
-      int top_marks_width = 0, bottom_marks_width = 0, marks_width;
-
-      if (priv->top_marks_gadget)
-        gtk_css_gadget_get_preferred_size (priv->top_marks_gadget,
-                                           GTK_ORIENTATION_HORIZONTAL, -1,
-                                           &top_marks_width, NULL,
-                                           NULL, NULL);
-      if (priv->bottom_marks_gadget)
-        gtk_css_gadget_get_preferred_size (priv->bottom_marks_gadget,
-                                           GTK_ORIENTATION_HORIZONTAL, -1,
-                                           &bottom_marks_width, NULL,
-                                           NULL, NULL);
-
-      marks_width = MAX (top_marks_width, bottom_marks_width);
-
-      *minimum = MAX (*minimum, marks_width);
-      *natural = MAX (*natural, marks_width);
-    }
-}
-
-static void
-gtk_scale_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
+gtk_scale_measure (GtkWidget      *widget,
+                   GtkOrientation  orientation,
+                   int             for_size,
+                   int            *minimum,
+                   int            *natural,
+                   int            *minimum_baseline,
+                   int            *natural_baseline)
 {
   GtkScale *scale = GTK_SCALE (widget);
   GtkScalePrivate *priv = scale->priv;
 
-  GTK_WIDGET_CLASS (gtk_scale_parent_class)->get_preferred_height (widget, minimum, natural);
+  GTK_WIDGET_CLASS (gtk_scale_parent_class)->measure (widget,
+                                                      orientation,
+                                                      for_size,
+                                                      minimum, natural,
+                                                      minimum_baseline, natural_baseline);
 
-  if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == GTK_ORIENTATION_VERTICAL)
+  if (gtk_orientable_get_orientation (GTK_ORIENTABLE (widget)) == orientation)
     {
-      int top_marks_height = 0, bottom_marks_height = 0, marks_height;
+      int top_marks_size = 0, bottom_marks_size = 0, marks_size;
 
       if (priv->top_marks_gadget)
         gtk_css_gadget_get_preferred_size (priv->top_marks_gadget,
-                                           GTK_ORIENTATION_VERTICAL, -1,
-                                           &top_marks_height, NULL,
+                                           orientation, for_size,
+                                           &top_marks_size, NULL,
                                            NULL, NULL);
       if (priv->bottom_marks_gadget)
         gtk_css_gadget_get_preferred_size (priv->bottom_marks_gadget,
-                                           GTK_ORIENTATION_VERTICAL, -1,
-                                           &bottom_marks_height, NULL,
+                                           orientation, for_size,
+                                           &bottom_marks_size, NULL,
                                            NULL, NULL);
 
-      marks_height = MAX (top_marks_height, bottom_marks_height);
+      marks_size = MAX (top_marks_size, bottom_marks_size);
 
-      *minimum = MAX (*minimum, marks_height);
-      *natural = MAX (*natural, marks_height);
+      *minimum = MAX (*minimum, marks_size);
+      *natural = MAX (*natural, marks_size);
     }
 }
 
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 28add4a..c6724cc 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -366,21 +366,13 @@ static void     gtk_scrolled_window_adjustment_value_changed (GtkAdjustment
                                                               gpointer           data);
 static gboolean gtk_widget_should_animate              (GtkWidget           *widget);
 
-static void  gtk_scrolled_window_get_preferred_width   (GtkWidget           *widget,
-                                                       gint                *minimum_size,
-                                                       gint                *natural_size);
-static void  gtk_scrolled_window_get_preferred_height  (GtkWidget           *widget,
-                                                       gint                *minimum_size,
-                                                       gint                *natural_size);
-static void  gtk_scrolled_window_get_preferred_height_for_width  (GtkWidget           *layout,
-                                                       gint                 width,
-                                                       gint                *minimum_height,
-                                                       gint                *natural_height);
-static void  gtk_scrolled_window_get_preferred_width_for_height  (GtkWidget           *layout,
-                                                       gint                 width,
-                                                       gint                *minimum_height,
-                                                       gint                *natural_height);
-
+static void gtk_scrolled_window_measure_ (GtkWidget      *widget,
+                                          GtkOrientation  orientation,
+                                          int             for_size,
+                                          int            *minimum,
+                                          int            *natural,
+                                          int            *minimum_baseline,
+                                          int            *natural_baseline);
 static void  gtk_scrolled_window_map                   (GtkWidget           *widget);
 static void  gtk_scrolled_window_unmap                 (GtkWidget           *widget);
 static void  gtk_scrolled_window_realize               (GtkWidget           *widget);
@@ -541,10 +533,7 @@ gtk_scrolled_window_class_init (GtkScrolledWindowClass *class)
   widget_class->size_allocate = gtk_scrolled_window_size_allocate;
   widget_class->scroll_event = gtk_scrolled_window_scroll_event;
   widget_class->focus = gtk_scrolled_window_focus;
-  widget_class->get_preferred_width = gtk_scrolled_window_get_preferred_width;
-  widget_class->get_preferred_height = gtk_scrolled_window_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_scrolled_window_get_preferred_height_for_width;
-  widget_class->get_preferred_width_for_height = gtk_scrolled_window_get_preferred_width_for_height;
+  widget_class->measure = gtk_scrolled_window_measure_;
   widget_class->map = gtk_scrolled_window_map;
   widget_class->unmap = gtk_scrolled_window_unmap;
   widget_class->grab_notify = gtk_scrolled_window_grab_notify;
@@ -3899,45 +3888,19 @@ gtk_scrolled_window_remove (GtkContainer *container,
 }
 
 static void
-gtk_scrolled_window_get_preferred_width (GtkWidget *widget,
-                                         gint      *minimum_size,
-                                         gint      *natural_size)
+gtk_scrolled_window_measure_ (GtkWidget      *widget,
+                              GtkOrientation  orientation,
+                              int             for_size,
+                              int            *minimum,
+                              int            *natural,
+                              int            *minimum_baseline,
+                              int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_SCROLLED_WINDOW (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_scrolled_window_get_preferred_height (GtkWidget *widget,
-                                          gint      *minimum_size,
-                                          gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_SCROLLED_WINDOW (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_scrolled_window_get_preferred_height_for_width (GtkWidget *widget,
-                                                    gint       width,
-                                                    gint      *minimum_height,
-                                                    gint      *natural_height)
-{
-  GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
-}
-
-static void
-gtk_scrolled_window_get_preferred_width_for_height (GtkWidget *widget,
-                                                    gint       height,
-                                                    gint      *minimum_width,
-                                                    gint      *natural_width)
-{
-  GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
 }
 
 static gboolean
diff --git a/gtk/gtkseparator.c b/gtk/gtkseparator.c
index f76fb36..c25bd0c 100644
--- a/gtk/gtkseparator.c
+++ b/gtk/gtkseparator.c
@@ -114,28 +114,19 @@ gtk_separator_get_property (GObject    *object,
     }
 }
 
-static void
-gtk_separator_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_SEPARATOR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_separator_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
+static void gtk_separator_measure (GtkWidget *widget,
+                                   GtkOrientation  orientation,
+                                   gint            for_size,
+                                   gint           *minimum,
+                                   gint           *natural,
+                                   gint           *minimum_baseline,
+                                   gint           *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_SEPARATOR (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -203,8 +194,7 @@ gtk_separator_class_init (GtkSeparatorClass *class)
   object_class->get_property = gtk_separator_get_property;
   object_class->finalize = gtk_separator_finalize;
 
-  widget_class->get_preferred_width = gtk_separator_get_preferred_width;
-  widget_class->get_preferred_height = gtk_separator_get_preferred_height;
+  widget_class->measure = gtk_separator_measure;
   widget_class->size_allocate = gtk_separator_size_allocate;
 
   widget_class->draw = gtk_separator_draw;
diff --git a/gtk/gtkseparatortoolitem.c b/gtk/gtkseparatortoolitem.c
index 0aa35ea..219955e 100644
--- a/gtk/gtkseparatortoolitem.c
+++ b/gtk/gtkseparatortoolitem.c
@@ -71,12 +71,13 @@ static void     gtk_separator_tool_item_get_property      (GObject
                                                            guint                      prop_id,
                                                            GValue                    *value,
                                                            GParamSpec                *pspec);
-static void     gtk_separator_tool_item_get_preferred_width (GtkWidget               *widget,
-                                                           gint                      *minimum,
-                                                           gint                      *natural);
-static void     gtk_separator_tool_item_get_preferred_height (GtkWidget              *widget,
-                                                           gint                      *minimum,
-                                                           gint                      *natural);
+static void     gtk_separator_tool_item_measure           (GtkWidget *widget,
+                                                           GtkOrientation  orientation,
+                                                           gint            for_size,
+                                                           gint           *minimum,
+                                                           gint           *natural,
+                                                           gint           *minimum_baseline,
+                                                           gint           *natural_baseline);
 static void     gtk_separator_tool_item_size_allocate     (GtkWidget                 *widget,
                                                            GtkAllocation             *allocation);
 static gboolean gtk_separator_tool_item_draw              (GtkWidget                 *widget,
@@ -121,8 +122,7 @@ gtk_separator_tool_item_class_init (GtkSeparatorToolItemClass *class)
   object_class->get_property = gtk_separator_tool_item_get_property;
   object_class->finalize = gtk_separator_tool_item_finalize;
 
-  widget_class->get_preferred_width = gtk_separator_tool_item_get_preferred_width;
-  widget_class->get_preferred_height = gtk_separator_tool_item_get_preferred_height;
+  widget_class->measure = gtk_separator_tool_item_measure;
   widget_class->size_allocate = gtk_separator_tool_item_size_allocate;
   widget_class->draw = gtk_separator_tool_item_draw;
   widget_class->realize = gtk_separator_tool_item_realize;
@@ -225,29 +225,20 @@ gtk_separator_tool_item_get_property (GObject      *object,
       break;
     }
 }
-
-static void
-gtk_separator_tool_item_get_preferred_width (GtkWidget *widget,
-                                             gint      *minimum,
-                                             gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_SEPARATOR_TOOL_ITEM (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
 static void
-gtk_separator_tool_item_get_preferred_height (GtkWidget *widget,
-                                              gint      *minimum,
-                                              gint      *natural)
+gtk_separator_tool_item_measure (GtkWidget *widget,
+                                 GtkOrientation  orientation,
+                                 gint            for_size,
+                                 gint           *minimum,
+                                 gint           *natural,
+                                 gint           *minimum_baseline,
+                                 gint           *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_SEPARATOR_TOOL_ITEM (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
diff --git a/gtk/gtksizerequest.c b/gtk/gtksizerequest.c
index 94617c8..d80e47f 100644
--- a/gtk/gtksizerequest.c
+++ b/gtk/gtksizerequest.c
@@ -91,46 +91,6 @@ get_vfunc_name (GtkOrientation orientation,
     return for_size < 0 ? "get_preferred_height" : "get_preferred_height_for_width";
 }
 
-static gboolean
-widget_class_has_baseline_support (GtkWidgetClass *widget_class)
-{
-  GtkWidgetClass *parent_class;
-
-  if (widget_class->get_preferred_height_and_baseline_for_width == NULL)
-    return FALSE;
-
-  /* This is kinda hacky, but for backwards compatibility reasons we have to handle the case
-     where a class previously did not support get_preferred_height_and_baseline_for_width,
-     but then gained support for it, and a subclass of it overrides the previous non-baseline
-     methods. If this happens we need to call the overridden (non-baseline supporting) versions
-     on the subclass, rather than the inherited but not overriddent new 
get_preferred_height_and_baseline_for_width.
-  */
-
-  /* Loop over all parent classes that inherit the same get_preferred_height_and_baseline_for_width */
-  parent_class = g_type_class_peek_parent (widget_class);
-  while (parent_class != NULL &&
-        parent_class->get_preferred_height_and_baseline_for_width == 
widget_class->get_preferred_height_and_baseline_for_width)
-    {
-      if (parent_class->get_preferred_height != widget_class->get_preferred_height ||
-          parent_class->get_preferred_height_for_width != widget_class->get_preferred_height_for_width)
-        return FALSE;
-
-      parent_class = g_type_class_peek_parent (parent_class);
-    }
-
-  return TRUE;
-}
-
-gboolean
-_gtk_widget_has_baseline_support (GtkWidget *widget)
-{
-  GtkWidgetClass *widget_class;
-
-  widget_class = GTK_WIDGET_GET_CLASS (widget);
-
-  return widget_class_has_baseline_support (widget_class);
-}
-
 static void
 gtk_widget_query_size_for_orientation (GtkWidget        *widget,
                                        GtkOrientation    orientation,
@@ -173,7 +133,8 @@ gtk_widget_query_size_for_orientation (GtkWidget        *widget,
           if (for_size < 0)
             {
              push_recursion_check (widget, orientation, for_size);
-              widget_class->get_preferred_width (widget, &min_size, &nat_size);
+              widget_class->measure (widget, GTK_ORIENTATION_HORIZONTAL, -1,
+                                     &min_size, &nat_size, NULL, NULL);
              pop_recursion_check (widget, orientation);
             }
           else
@@ -195,9 +156,11 @@ gtk_widget_query_size_for_orientation (GtkWidget        *widget,
                                                    &adjusted_for_size);
 
              push_recursion_check (widget, orientation, for_size);
-              widget_class->get_preferred_width_for_height (widget,
-                                                           MAX (adjusted_for_size, minimum_height),
-                                                           &min_size, &nat_size);
+              widget_class->measure (widget,
+                                     GTK_ORIENTATION_HORIZONTAL,
+                                     MAX (adjusted_for_size, minimum_height),
+                                     &min_size, &nat_size,
+                                     NULL, NULL);
              pop_recursion_check (widget, orientation);
             }
         }
@@ -206,12 +169,11 @@ gtk_widget_query_size_for_orientation (GtkWidget        *widget,
           if (for_size < 0)
             {
              push_recursion_check (widget, orientation, for_size);
-             if (widget_class_has_baseline_support (widget_class))
-               widget_class->get_preferred_height_and_baseline_for_width (widget, -1,
-                                                                          &min_size, &nat_size,
-                                                                          &min_baseline, &nat_baseline);
-             else
-               widget_class->get_preferred_height (widget, &min_size, &nat_size);
+              widget_class->measure (widget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     -1,
+                                     &min_size, &nat_size,
+                                     &min_baseline, &nat_baseline);
              pop_recursion_check (widget, orientation);
             }
           else
@@ -233,13 +195,11 @@ gtk_widget_query_size_for_orientation (GtkWidget        *widget,
                                                    &adjusted_for_size);
 
              push_recursion_check (widget, orientation, for_size);
-             if (widget_class_has_baseline_support (widget_class))
-               widget_class->get_preferred_height_and_baseline_for_width (widget, MAX (adjusted_for_size, 
minimum_width),
-                                                                          &min_size, &nat_size,
-                                                                          &min_baseline, &nat_baseline);
-             else
-               widget_class->get_preferred_height_for_width (widget, MAX (adjusted_for_size, minimum_width),
-                                                             &min_size, &nat_size);
+              widget_class->measure (widget,
+                                     GTK_ORIENTATION_VERTICAL,
+                                     MAX (adjusted_for_size, minimum_width),
+                                     &min_size, &nat_size,
+                                     &min_baseline, &nat_baseline);
              pop_recursion_check (widget, orientation);
             }
         }
@@ -849,23 +809,23 @@ gtk_distribute_natural_allocation (gint              extra_space,
 }
 
 void
-_gtk_widget_get_preferred_size_for_size (GtkWidget      *widget,
-                                         GtkOrientation  orientation,
-                                         gint            size,
-                                         gint           *minimum,
-                                         gint           *natural,
-                                         gint           *minimum_baseline,
-                                         gint           *natural_baseline)
+gtk_widget_measure (GtkWidget      *widget,
+                    GtkOrientation  orientation,
+                    int             for_size,
+                    int            *minimum,
+                    int            *natural,
+                    int            *minimum_baseline,
+                    int            *natural_baseline)
 {
   g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (size >= -1);
+  g_return_if_fail (for_size >= -1);
 
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
-      if (size < 0)
+      if (for_size < 0)
         gtk_widget_get_preferred_width (widget, minimum, natural);
       else
-        gtk_widget_get_preferred_width_for_height (widget, size, minimum, natural);
+        gtk_widget_get_preferred_width_for_height (widget, for_size, minimum, natural);
 
       if (minimum_baseline)
         *minimum_baseline = -1;
@@ -875,7 +835,7 @@ _gtk_widget_get_preferred_size_for_size (GtkWidget      *widget,
   else
     {
       gtk_widget_get_preferred_height_and_baseline_for_width (widget,
-                                                              size,
+                                                              for_size,
                                                               minimum,
                                                               natural,
                                                               minimum_baseline,
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index 09a809d..9f0444f 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -253,18 +253,13 @@ static void gtk_spin_button_map            (GtkWidget          *widget);
 static void gtk_spin_button_unmap          (GtkWidget          *widget);
 static void gtk_spin_button_realize        (GtkWidget          *widget);
 static void gtk_spin_button_unrealize      (GtkWidget          *widget);
-static void gtk_spin_button_get_preferred_width  (GtkWidget          *widget,
-                                                  gint               *minimum,
-                                                  gint               *natural);
-static void gtk_spin_button_get_preferred_height (GtkWidget          *widget,
-                                                  gint               *minimum,
-                                                  gint               *natural);
-static void gtk_spin_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                                        gint       width,
-                                                                        gint      *minimum,
-                                                                        gint      *natural,
-                                                                        gint      *minimum_baseline,
-                                                                        gint      *natural_baseline);
+static void gtk_spin_button_measure (GtkWidget      *widget,
+                                     GtkOrientation  orientation,
+                                     int             for_size,
+                                     int            *minimum,
+                                     int            *natural,
+                                     int            *minimum_baseline,
+                                     int            *natural_baseline);
 static void gtk_spin_button_size_allocate  (GtkWidget          *widget,
                                             GtkAllocation      *allocation);
 static gint gtk_spin_button_draw           (GtkWidget          *widget,
@@ -345,9 +340,7 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
   widget_class->unmap = gtk_spin_button_unmap;
   widget_class->realize = gtk_spin_button_realize;
   widget_class->unrealize = gtk_spin_button_unrealize;
-  widget_class->get_preferred_width = gtk_spin_button_get_preferred_width;
-  widget_class->get_preferred_height = gtk_spin_button_get_preferred_height;
-  widget_class->get_preferred_height_and_baseline_for_width = 
gtk_spin_button_get_preferred_height_and_baseline_for_width;
+  widget_class->measure = gtk_spin_button_measure;
   widget_class->size_allocate = gtk_spin_button_size_allocate;
   widget_class->draw = gtk_spin_button_draw;
   widget_class->scroll_event = gtk_spin_button_scroll;
@@ -1141,41 +1134,22 @@ gtk_spin_button_get_text_width (GtkSpinButton *spin_button)
 }
 
 static void
-gtk_spin_button_get_preferred_width (GtkWidget *widget,
-                                     gint      *minimum,
-                                     gint      *natural)
+gtk_spin_button_measure (GtkWidget      *widget,
+                         GtkOrientation  orientation,
+                         int             for_size,
+                         int            *minimum,
+                         int            *natural,
+                         int            *minimum_baseline,
+                         int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_SPIN_BUTTON (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_spin_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
-                                                            gint       width,
-                                                            gint      *minimum,
-                                                            gint      *natural,
-                                                            gint      *minimum_baseline,
-                                                            gint      *natural_baseline)
-{
-  gtk_css_gadget_get_preferred_size (GTK_SPIN_BUTTON (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
                                      minimum_baseline, natural_baseline);
 }
 
 static void
-gtk_spin_button_get_preferred_height (GtkWidget *widget,
-                                      gint      *minimum,
-                                      gint      *natural)
-{
-  gtk_spin_button_get_preferred_height_and_baseline_for_width (widget, -1, minimum, natural, NULL, NULL);
-}
-
-static void
 gtk_spin_button_size_allocate (GtkWidget     *widget,
                                GtkAllocation *allocation)
 {
diff --git a/gtk/gtkspinner.c b/gtk/gtkspinner.c
index 97d8e58..db1316e 100644
--- a/gtk/gtkspinner.c
+++ b/gtk/gtkspinner.c
@@ -84,27 +84,19 @@ gtk_spinner_finalize (GObject *object)
 }
 
 static void
-gtk_spinner_get_preferred_width (GtkWidget *widget,
-                                 gint      *minimum,
-                                 gint      *natural)
+gtk_spinner_measure (GtkWidget      *widget,
+                     GtkOrientation  orientation,
+                     int             for_size,
+                     int            *minimum,
+                     int            *natural,
+                     int            *minimum_baseline,
+                     int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_SPINNER (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_spinner_get_preferred_height (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_SPINNER (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -205,8 +197,7 @@ gtk_spinner_class_init (GtkSpinnerClass *klass)
   widget_class = GTK_WIDGET_CLASS(klass);
   widget_class->size_allocate = gtk_spinner_size_allocate;
   widget_class->get_render_node = gtk_spinner_get_render_node;
-  widget_class->get_preferred_width = gtk_spinner_get_preferred_width;
-  widget_class->get_preferred_height = gtk_spinner_get_preferred_height;
+  widget_class->measure = gtk_spinner_measure;
 
   /* GtkSpinner:active:
    *
diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c
index bed1fe6..fb30df8 100644
--- a/gtk/gtkstack.c
+++ b/gtk/gtkstack.c
@@ -178,20 +178,13 @@ static void     gtk_stack_size_allocate                  (GtkWidget     *widget,
                                                           GtkAllocation *allocation);
 static gboolean gtk_stack_draw                           (GtkWidget     *widget,
                                                           cairo_t       *cr);
-static void     gtk_stack_get_preferred_height           (GtkWidget     *widget,
-                                                          gint          *minimum_height,
-                                                          gint          *natural_height);
-static void     gtk_stack_get_preferred_height_for_width (GtkWidget     *widget,
-                                                          gint           width,
-                                                          gint          *minimum_height,
-                                                          gint          *natural_height);
-static void     gtk_stack_get_preferred_width            (GtkWidget     *widget,
-                                                          gint          *minimum_width,
-                                                          gint          *natural_width);
-static void     gtk_stack_get_preferred_width_for_height (GtkWidget     *widget,
-                                                          gint           height,
-                                                          gint          *minimum_width,
-                                                          gint          *natural_width);
+static void     gtk_stack_measure_                       (GtkWidget      *widget,
+                                                          GtkOrientation  orientation,
+                                                          int             for_size,
+                                                          int            *minimum,
+                                                          int            *natural,
+                                                          int            *minimum_baseline,
+                                                          int            *natural_baseline);
 static void     gtk_stack_finalize                       (GObject       *obj);
 static void     gtk_stack_get_property                   (GObject       *object,
                                                           guint          property_id,
@@ -433,10 +426,7 @@ gtk_stack_class_init (GtkStackClass *klass)
   widget_class->unrealize = gtk_stack_unrealize;
   widget_class->map = gtk_stack_map;
   widget_class->unmap = gtk_stack_unmap;
-  widget_class->get_preferred_height = gtk_stack_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_stack_get_preferred_height_for_width;
-  widget_class->get_preferred_width = gtk_stack_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_stack_get_preferred_width_for_height;
+  widget_class->measure = gtk_stack_measure_;
   widget_class->compute_expand = gtk_stack_compute_expand;
 
   container_class->add = gtk_stack_add;
@@ -2287,67 +2277,22 @@ gtk_stack_allocate (GtkCssGadget        *gadget,
 
   gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
 }
-
-static void
-gtk_stack_get_preferred_width (GtkWidget *widget,
-                               gint      *minimum,
-                               gint      *natural)
-{
-  GtkStack *stack = GTK_STACK (widget);
-  GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_stack_get_preferred_width_for_height (GtkWidget *widget,
-                                          gint       height,
-                                          gint      *minimum,
-                                          gint      *natural)
-{
-  GtkStack *stack = GTK_STACK (widget);
-  GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
 static void
-gtk_stack_get_preferred_height (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
+gtk_stack_measure_ (GtkWidget      *widget,
+                    GtkOrientation  orientation,
+                    int             for_size,
+                    int            *minimum,
+                    int            *natural,
+                    int            *minimum_baseline,
+                    int            *natural_baseline)
 {
-  GtkStack *stack = GTK_STACK (widget);
-  GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_stack_get_preferred_height_for_width (GtkWidget *widget,
-                                          gint       width,
-                                          gint      *minimum,
-                                          gint      *natural)
-{
-  GtkStack *stack = GTK_STACK (widget);
-  GtkStackPrivate *priv = gtk_stack_get_instance_private (stack);
+  GtkStackPrivate *priv = gtk_stack_get_instance_private (GTK_STACK (widget));
 
   gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 #define LERP(a, b, t) ((a) + (((b) - (a)) * (1.0 - (t))))
diff --git a/gtk/gtkswitch.c b/gtk/gtkswitch.c
index 4e31fbf..8fa9643 100644
--- a/gtk/gtkswitch.c
+++ b/gtk/gtkswitch.c
@@ -404,27 +404,19 @@ gtk_switch_get_content_size (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_switch_get_preferred_width (GtkWidget *widget,
-                                gint      *minimum,
-                                gint      *natural)
+gtk_switch_measure (GtkWidget      *widget,
+                    GtkOrientation  orientation,
+                    int             for_size,
+                    int            *minimum,
+                    int            *natural,
+                    int            *minimum_baseline,
+                    int            *natural_baseline)
 {
   gtk_css_gadget_get_preferred_size (GTK_SWITCH (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
-}
-
-static void
-gtk_switch_get_preferred_height (GtkWidget *widget,
-                                 gint      *minimum,
-                                 gint      *natural)
-{
-  gtk_css_gadget_get_preferred_size (GTK_SWITCH (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
+                                     minimum_baseline, natural_baseline);
 }
 
 static void
@@ -782,8 +774,7 @@ gtk_switch_class_init (GtkSwitchClass *klass)
 
   g_object_class_install_properties (gobject_class, LAST_PROP, switch_props);
 
-  widget_class->get_preferred_width = gtk_switch_get_preferred_width;
-  widget_class->get_preferred_height = gtk_switch_get_preferred_height;
+  widget_class->measure = gtk_switch_measure;
   widget_class->size_allocate = gtk_switch_size_allocate;
   widget_class->realize = gtk_switch_realize;
   widget_class->unrealize = gtk_switch_unrealize;
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 7fffd99..9197bf7 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -383,12 +383,13 @@ static void gtk_text_view_get_property         (GObject         *object,
 static void gtk_text_view_destroy              (GtkWidget        *widget);
 static void gtk_text_view_size_request         (GtkWidget        *widget,
                                                 GtkRequisition   *requisition);
-static void gtk_text_view_get_preferred_width  (GtkWidget        *widget,
-                                               gint             *minimum,
-                                               gint             *natural);
-static void gtk_text_view_get_preferred_height (GtkWidget        *widget,
-                                               gint             *minimum,
-                                               gint             *natural);
+static void gtk_text_view_measure (GtkWidget      *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 static void gtk_text_view_size_allocate        (GtkWidget        *widget,
                                                 GtkAllocation    *allocation);
 static void gtk_text_view_map                  (GtkWidget        *widget);
@@ -747,8 +748,7 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   widget_class->style_updated = gtk_text_view_style_updated;
   widget_class->direction_changed = gtk_text_view_direction_changed;
   widget_class->state_flags_changed = gtk_text_view_state_flags_changed;
-  widget_class->get_preferred_width = gtk_text_view_get_preferred_width;
-  widget_class->get_preferred_height = gtk_text_view_get_preferred_height;
+  widget_class->measure = gtk_text_view_measure;
   widget_class->size_allocate = gtk_text_view_size_allocate;
   widget_class->event = gtk_text_view_event;
   widget_class->key_press_event = gtk_text_view_key_press_event;
@@ -4035,30 +4035,24 @@ gtk_text_view_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_text_view_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
+gtk_text_view_measure (GtkWidget      *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   GtkRequisition requisition;
 
   gtk_text_view_size_request (widget, &requisition);
 
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_text_view_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_text_view_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    *minimum = *natural = requisition.width;
+  else
+    *minimum = *natural = requisition.height;
 }
 
-
 static void
 gtk_text_view_compute_child_allocation (GtkTextView      *text_view,
                                         GtkTextViewChild *vc,
diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c
index 28a4646..a708506 100644
--- a/gtk/gtktoolbar.c
+++ b/gtk/gtktoolbar.c
@@ -196,13 +196,13 @@ static gint       gtk_toolbar_draw                 (GtkWidget           *widget,
                                                     cairo_t             *cr);
 static void       gtk_toolbar_realize              (GtkWidget           *widget);
 static void       gtk_toolbar_unrealize            (GtkWidget           *widget);
-static void       gtk_toolbar_get_preferred_width  (GtkWidget           *widget,
-                                                    gint                *minimum,
-                                                    gint                *natural);
-static void       gtk_toolbar_get_preferred_height (GtkWidget           *widget,
-                                                    gint                *minimum,
-                                                    gint                *natural);
-
+static void       gtk_toolbar_measure_             (GtkWidget      *widget,
+                                                    GtkOrientation  orientation,
+                                                    int             for_size,
+                                                    int            *minimum,
+                                                    int            *natural,
+                                                    int            *minimum_baseline,
+                                                    int            *natural_baseline);
 static void       gtk_toolbar_size_allocate        (GtkWidget           *widget,
                                                    GtkAllocation       *allocation);
 static void       gtk_toolbar_style_updated        (GtkWidget           *widget);
@@ -397,8 +397,7 @@ gtk_toolbar_class_init (GtkToolbarClass *klass)
   
   widget_class->button_press_event = gtk_toolbar_button_press;
   widget_class->draw = gtk_toolbar_draw;
-  widget_class->get_preferred_width = gtk_toolbar_get_preferred_width;
-  widget_class->get_preferred_height = gtk_toolbar_get_preferred_height;
+  widget_class->measure = gtk_toolbar_measure_;
   widget_class->size_allocate = gtk_toolbar_size_allocate;
   widget_class->style_updated = gtk_toolbar_style_updated;
   widget_class->focus = gtk_toolbar_focus;
@@ -970,33 +969,23 @@ gtk_toolbar_measure (GtkCssGadget   *gadget,
 }
 
 static void
-gtk_toolbar_get_preferred_width (GtkWidget *widget,
-                                 gint      *minimum,
-                                 gint      *natural)
+gtk_toolbar_measure_ (GtkWidget      *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
 {
   GtkToolbar *toolbar = GTK_TOOLBAR (widget);
   GtkToolbarPrivate *priv = toolbar->priv;
 
   gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
+                                     orientation,
+                                     for_size,
                                      minimum, natural,
-                                     NULL, NULL);
-}
+                                     minimum_baseline, natural_baseline);
 
-static void
-gtk_toolbar_get_preferred_height (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
-{
-  GtkToolbar *toolbar = GTK_TOOLBAR (widget);
-  GtkToolbarPrivate *priv = toolbar->priv;
-
-  gtk_css_gadget_get_preferred_size (priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum, natural,
-                                     NULL, NULL);
 }
 
 static gint
diff --git a/gtk/gtktoolitem.c b/gtk/gtktoolitem.c
index 71a86d6..54e54a1 100644
--- a/gtk/gtktoolitem.c
+++ b/gtk/gtktoolitem.c
@@ -105,14 +105,6 @@ static void gtk_tool_item_realize       (GtkWidget      *widget);
 static void gtk_tool_item_unrealize     (GtkWidget      *widget);
 static void gtk_tool_item_map           (GtkWidget      *widget);
 static void gtk_tool_item_unmap         (GtkWidget      *widget);
-static void gtk_tool_item_get_preferred_width
-                                        (GtkWidget      *widget,
-                                         gint           *minimum,
-                                         gint           *natural);
-static void gtk_tool_item_get_preferred_height
-                                        (GtkWidget      *widget,
-                                         gint           *minimum,
-                                         gint           *natural);
 static void gtk_tool_item_size_allocate (GtkWidget      *widget,
                                         GtkAllocation  *allocation);
 
@@ -139,8 +131,6 @@ gtk_tool_item_class_init (GtkToolItemClass *klass)
   widget_class->unrealize     = gtk_tool_item_unrealize;
   widget_class->map           = gtk_tool_item_map;
   widget_class->unmap         = gtk_tool_item_unmap;
-  widget_class->get_preferred_width = gtk_tool_item_get_preferred_width;
-  widget_class->get_preferred_height = gtk_tool_item_get_preferred_height;
   widget_class->size_allocate = gtk_tool_item_size_allocate;
   widget_class->parent_set    = gtk_tool_item_parent_set;
 
@@ -406,34 +396,6 @@ gtk_tool_item_unmap (GtkWidget *widget)
 }
 
 static void
-gtk_tool_item_get_preferred_width (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkWidget *child;
-
-  *minimum = *natural = 0;
-
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  if (child && gtk_widget_get_visible (child))
-    gtk_widget_get_preferred_width (child, minimum, natural);
-}
-
-static void
-gtk_tool_item_get_preferred_height (GtkWidget *widget,
-                                    gint      *minimum,
-                                    gint      *natural)
-{
-  GtkWidget *child;
-
-  *minimum = *natural = 0;
-
-  child = gtk_bin_get_child (GTK_BIN (widget));
-  if (child && gtk_widget_get_visible (child))
-    gtk_widget_get_preferred_height (child, minimum, natural);
-}
-
-static void
 gtk_tool_item_size_allocate (GtkWidget     *widget,
                             GtkAllocation *allocation)
 {
diff --git a/gtk/gtktoolitemgroup.c b/gtk/gtktoolitemgroup.c
index 5a104d6..ab6534b 100644
--- a/gtk/gtktoolitemgroup.c
+++ b/gtk/gtktoolitemgroup.c
@@ -602,30 +602,24 @@ gtk_tool_item_group_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_tool_item_group_get_preferred_width (GtkWidget *widget,
-                                        gint      *minimum,
-                                        gint      *natural)
+gtk_tool_item_group_measure (GtkWidget      *widget,
+                             GtkOrientation  orientation,
+                             int             for_size,
+                             int            *minimum,
+                             int            *natural,
+                             int            *minimum_baseline,
+                             int            *natural_baseline)
 {
   GtkRequisition requisition;
 
   gtk_tool_item_group_size_request (widget, &requisition);
 
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_tool_item_group_get_preferred_height (GtkWidget *widget,
-                                         gint      *minimum,
-                                         gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_tool_item_group_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    *minimum = *natural = requisition.width;
+  else
+    *minimum = *natural = requisition.height;
 }
 
-
 static gboolean
 gtk_tool_item_group_is_item_visible (GtkToolItemGroup      *group,
                                      GtkToolItemGroupChild *child)
@@ -1592,8 +1586,7 @@ gtk_tool_item_group_class_init (GtkToolItemGroupClass *cls)
   oclass->finalize           = gtk_tool_item_group_finalize;
   oclass->dispose            = gtk_tool_item_group_dispose;
 
-  wclass->get_preferred_width  = gtk_tool_item_group_get_preferred_width;
-  wclass->get_preferred_height = gtk_tool_item_group_get_preferred_height;
+  wclass->measure              = gtk_tool_item_group_measure;
   wclass->size_allocate        = gtk_tool_item_group_size_allocate;
   wclass->realize              = gtk_tool_item_group_realize;
   wclass->unrealize            = gtk_tool_item_group_unrealize;
diff --git a/gtk/gtktoolpalette.c b/gtk/gtktoolpalette.c
index 52936f0..8a1af54 100644
--- a/gtk/gtktoolpalette.c
+++ b/gtk/gtktoolpalette.c
@@ -449,27 +449,22 @@ gtk_tool_palette_size_request (GtkWidget      *widget,
 }
 
 static void
-gtk_tool_palette_get_preferred_width (GtkWidget *widget,
-                                     gint      *minimum,
-                                     gint      *natural)
+gtk_tool_palette_measure (GtkWidget      *widget,
+                          GtkOrientation  orientation,
+                          int             for_size,
+                          int            *minimum,
+                          int            *natural,
+                          int            *minimum_baseline,
+                          int            *natural_baseline)
 {
   GtkRequisition requisition;
 
   gtk_tool_palette_size_request (widget, &requisition);
 
-  *minimum = *natural = requisition.width;
-}
-
-static void
-gtk_tool_palette_get_preferred_height (GtkWidget *widget,
-                                      gint      *minimum,
-                                      gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_tool_palette_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    *minimum = *natural = requisition.width;
+  else
+    *minimum = *natural = requisition.height;
 }
 
 
@@ -899,8 +894,7 @@ gtk_tool_palette_class_init (GtkToolPaletteClass *cls)
   oclass->dispose             = gtk_tool_palette_dispose;
   oclass->finalize            = gtk_tool_palette_finalize;
 
-  wclass->get_preferred_width = gtk_tool_palette_get_preferred_width;
-  wclass->get_preferred_height= gtk_tool_palette_get_preferred_height;
+  wclass->measure             = gtk_tool_palette_measure;
   wclass->size_allocate       = gtk_tool_palette_size_allocate;
   wclass->realize             = gtk_tool_palette_realize;
   wclass->draw                = gtk_tool_palette_draw;
diff --git a/gtk/gtktreemenu.c b/gtk/gtktreemenu.c
index 60eaa2e..c4ccfb8 100644
--- a/gtk/gtktreemenu.c
+++ b/gtk/gtktreemenu.c
@@ -63,20 +63,13 @@ static void      gtk_tree_menu_get_property                   (GObject
                                                                GParamSpec         *pspec);
 
 /* GtkWidgetClass */
-static void      gtk_tree_menu_get_preferred_width            (GtkWidget           *widget,
-                                                               gint                *minimum_size,
-                                                               gint                *natural_size);
-static void      gtk_tree_menu_get_preferred_height           (GtkWidget           *widget,
-                                                               gint                *minimum_size,
-                                                               gint                *natural_size);
-static void      gtk_tree_menu_get_preferred_width_for_height (GtkWidget           *widget,
-                                                               gint                 for_height,
-                                                               gint                *minimum_size,
-                                                               gint                *natural_size);
-static void      gtk_tree_menu_get_preferred_height_for_width (GtkWidget           *widget,
-                                                               gint                 for_width,
-                                                               gint                *minimum_size,
-                                                               gint                *natural_size);
+static void gtk_tree_menu_measure (GtkWidget      *widget,
+                                   GtkOrientation  orientation,
+                                   int             for_size,
+                                   int            *minimum,
+                                   int            *natural,
+                                   int            *minimum_baseline,
+                                   int            *natural_baseline);
 
 /* GtkCellLayoutIface */
 static void      gtk_tree_menu_cell_layout_init               (GtkCellLayoutIface  *iface);
@@ -222,10 +215,7 @@ _gtk_tree_menu_class_init (GtkTreeMenuClass *class)
   object_class->set_property = gtk_tree_menu_set_property;
   object_class->get_property = gtk_tree_menu_get_property;
 
-  widget_class->get_preferred_width  = gtk_tree_menu_get_preferred_width;
-  widget_class->get_preferred_height = gtk_tree_menu_get_preferred_height;
-  widget_class->get_preferred_width_for_height  = gtk_tree_menu_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_tree_menu_get_preferred_height_for_width;
+  widget_class->measure = gtk_tree_menu_measure;
 
   /*
    * GtkTreeMenu::menu-activate:
@@ -542,54 +532,17 @@ sync_reserve_submenu_size (GtkTreeMenu *menu)
   g_list_free (children);
 }
 
-static void
-gtk_tree_menu_get_preferred_width (GtkWidget           *widget,
-                                   gint                *minimum_size,
-                                   gint                *natural_size)
-{
-  GtkTreeMenu        *menu = GTK_TREE_MENU (widget);
-  GtkTreeMenuPrivate *priv = menu->priv;
-
-  /* We leave the requesting work up to the cellviews which operate in the same
-   * context, reserving space for the submenu indicator if any of the items have
-   * submenus ensures that every cellview will receive the same allocated width.
-   *
-   * Since GtkMenu does hieght-for-width correctly, we know that the width of
-   * every cell will be requested before the height-for-widths are requested.
-   */
-  g_signal_handler_block (priv->context, priv->size_changed_id);
-
-  sync_reserve_submenu_size (menu);
-
-  GTK_WIDGET_CLASS (_gtk_tree_menu_parent_class)->get_preferred_width (widget, minimum_size, natural_size);
-
-  g_signal_handler_unblock (priv->context, priv->size_changed_id);
-}
 
 static void
-gtk_tree_menu_get_preferred_height (GtkWidget           *widget,
-                                    gint                *minimum_size,
-                                    gint                *natural_size)
+gtk_tree_menu_measure (GtkWidget      *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
-  GtkTreeMenu        *menu = GTK_TREE_MENU (widget);
-  GtkTreeMenuPrivate *priv = menu->priv;
-
-  g_signal_handler_block (priv->context, priv->size_changed_id);
-
-  sync_reserve_submenu_size (menu);
-
-  GTK_WIDGET_CLASS (_gtk_tree_menu_parent_class)->get_preferred_height (widget, minimum_size, natural_size);
-
-  g_signal_handler_unblock (priv->context, priv->size_changed_id);
-}
-
-static void
-gtk_tree_menu_get_preferred_width_for_height (GtkWidget           *widget,
-                                              gint                 for_height,
-                                              gint                *minimum_size,
-                                              gint                *natural_size)
-{
-  GtkTreeMenu        *menu = GTK_TREE_MENU (widget);
+  GtkTreeMenu *menu = GTK_TREE_MENU (widget);
   GtkTreeMenuPrivate *priv = menu->priv;
 
   /* We leave the requesting work up to the cellviews which operate in the same
@@ -603,28 +556,15 @@ gtk_tree_menu_get_preferred_width_for_height (GtkWidget           *widget,
 
   sync_reserve_submenu_size (menu);
 
-  GTK_WIDGET_CLASS (_gtk_tree_menu_parent_class)->get_preferred_width_for_height (widget, for_height, 
minimum_size, natural_size);
+  GTK_WIDGET_CLASS (_gtk_tree_menu_parent_class)->measure (widget,
+                                                           orientation,
+                                                           for_size,
+                                                           minimum, natural,
+                                                           minimum_baseline, natural_baseline);
 
   g_signal_handler_unblock (priv->context, priv->size_changed_id);
 }
 
-static void
-gtk_tree_menu_get_preferred_height_for_width (GtkWidget           *widget,
-                                              gint                 for_width,
-                                              gint                *minimum_size,
-                                              gint                *natural_size)
-{
-  GtkTreeMenu        *menu = GTK_TREE_MENU (widget);
-  GtkTreeMenuPrivate *priv = menu->priv;
-
-  g_signal_handler_block (priv->context, priv->size_changed_id);
-
-  sync_reserve_submenu_size (menu);
-
-  GTK_WIDGET_CLASS (_gtk_tree_menu_parent_class)->get_preferred_height_for_width (widget, for_width, 
minimum_size, natural_size);
-
-  g_signal_handler_unblock (priv->context, priv->size_changed_id);
-}
 
 /****************************************************************
  *                      GtkCellLayoutIface                      *
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 00d205c..3382f06 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -590,12 +590,13 @@ static void     gtk_tree_view_realize              (GtkWidget        *widget);
 static void     gtk_tree_view_unrealize            (GtkWidget        *widget);
 static void     gtk_tree_view_map                  (GtkWidget        *widget);
 static void     gtk_tree_view_unmap                (GtkWidget        *widget);
-static void     gtk_tree_view_get_preferred_width  (GtkWidget        *widget,
-                                                   gint             *minimum,
-                                                   gint             *natural);
-static void     gtk_tree_view_get_preferred_height (GtkWidget        *widget,
-                                                   gint             *minimum,
-                                                   gint             *natural);
+static void     gtk_tree_view_measure              (GtkWidget        *widget,
+                                                    GtkOrientation  orientation,
+                                                    int             for_size,
+                                                    int            *minimum,
+                                                    int            *natural,
+                                                    int            *minimum_baseline,
+                                                    int            *natural_baseline);
 static void     gtk_tree_view_size_allocate        (GtkWidget        *widget,
                                                    GtkAllocation    *allocation);
 static gboolean gtk_tree_view_draw                 (GtkWidget        *widget,
@@ -982,8 +983,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   widget_class->unmap = gtk_tree_view_unmap;
   widget_class->realize = gtk_tree_view_realize;
   widget_class->unrealize = gtk_tree_view_unrealize;
-  widget_class->get_preferred_width = gtk_tree_view_get_preferred_width;
-  widget_class->get_preferred_height = gtk_tree_view_get_preferred_height;
+  widget_class->measure = gtk_tree_view_measure;
   widget_class->size_allocate = gtk_tree_view_size_allocate;
   widget_class->motion_notify_event = gtk_tree_view_motion;
   widget_class->draw = gtk_tree_view_draw;
@@ -2589,46 +2589,48 @@ gtk_tree_view_get_height (GtkTreeView *tree_view)
 }
 
 static void
-gtk_tree_view_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum,
-                                  gint      *natural)
+gtk_tree_view_measure (GtkWidget        *widget,
+                       GtkOrientation  orientation,
+                       int             for_size,
+                       int            *minimum,
+                       int            *natural,
+                       int            *minimum_baseline,
+                       int            *natural_baseline)
 {
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-  GList *list;
-  GtkTreeViewColumn *column;
-  gint width = 0;
 
-  /* we validate some rows initially just to make sure we have some size.
-   * In practice, with a lot of static lists, this should get a good width.
-   */
-  do_validate_rows (tree_view, FALSE);
-
-  /* keep this in sync with size_allocate below */
-  for (list = tree_view->priv->columns; list; list = list->next)
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
-      column = list->data;
-      if (!gtk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column)
-       continue;
+      GList *list;
+      GtkTreeViewColumn *column;
+      gint width = 0;
 
-      width += _gtk_tree_view_column_request_width (column);
-    }
+      /* we validate some rows initially just to make sure we have some size.
+       * In practice, with a lot of static lists, this should get a good width.
+       */
+      do_validate_rows (tree_view, FALSE);
 
-  *minimum = *natural = width;
-}
+      /* keep this in sync with size_allocate below */
+      for (list = tree_view->priv->columns; list; list = list->next)
+        {
+          column = list->data;
+          if (!gtk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column)
+            continue;
 
-static void
-gtk_tree_view_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum,
-                                   gint      *natural)
-{
-  GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-  gint height;
+          width += _gtk_tree_view_column_request_width (column);
+        }
 
-  gtk_tree_view_update_height (tree_view);
+      *minimum = *natural = width;
+    }
+  else /* VERTICAL */
+    {
+      int height;
 
-  height = gtk_tree_view_get_height (tree_view) + gtk_tree_view_get_effective_header_height (tree_view);
+      gtk_tree_view_update_height (tree_view);
+      height = gtk_tree_view_get_height (tree_view) + gtk_tree_view_get_effective_header_height (tree_view);
 
-  *minimum = *natural = height;
+      *minimum = *natural = height;
+    }
 }
 
 static int
@@ -6976,8 +6978,16 @@ do_validate_rows (GtkTreeView *tree_view, gboolean queue_resize)
        * untill we've recieved an allocation (never update scroll adjustments from size-requests).
        */
       prevent_recursion_hack = TRUE;
-      gtk_tree_view_get_preferred_width (GTK_WIDGET (tree_view), &requisition.width, &dummy);
-      gtk_tree_view_get_preferred_height (GTK_WIDGET (tree_view), &requisition.height, &dummy);
+      gtk_tree_view_measure (GTK_WIDGET (tree_view),
+                             GTK_ORIENTATION_HORIZONTAL,
+                             -1,
+                             &requisition.width, &dummy,
+                             NULL, NULL);
+      gtk_tree_view_measure (GTK_WIDGET (tree_view),
+                             GTK_ORIENTATION_VERTICAL,
+                             -1,
+                             &requisition.height, &dummy,
+                             NULL, NULL);
       prevent_recursion_hack = FALSE;
 
       /* If rows above the current position have changed height, this has
diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c
index 3bfb3f4..13db3a3 100644
--- a/gtk/gtkviewport.c
+++ b/gtk/gtkviewport.c
@@ -119,22 +119,6 @@ static void gtk_viewport_size_allocate            (GtkWidget        *widget,
                                                   GtkAllocation    *allocation);
 static void gtk_viewport_adjustment_value_changed (GtkAdjustment    *adjustment,
                                                   gpointer          data);
-
-static void gtk_viewport_get_preferred_width      (GtkWidget        *widget,
-                                                  gint             *minimum_size,
-                                                  gint             *natural_size);
-static void gtk_viewport_get_preferred_height     (GtkWidget        *widget,
-                                                  gint             *minimum_size,
-                                                  gint             *natural_size);
-static void gtk_viewport_get_preferred_width_for_height (GtkWidget  *widget,
-                                                   gint              height,
-                                                  gint             *minimum_size,
-                                                  gint             *natural_size);
-static void gtk_viewport_get_preferred_height_for_width (GtkWidget  *widget,
-                                                   gint              width,
-                                                  gint             *minimum_size,
-                                                  gint             *natural_size);
-
 static void viewport_set_adjustment               (GtkViewport      *viewport,
                                                    GtkOrientation    orientation,
                                                    GtkAdjustment    *adjustment);
@@ -162,11 +146,11 @@ gtk_viewport_measure (GtkCssGadget   *gadget,
 
   child = gtk_bin_get_child (GTK_BIN (widget));
   if (child && gtk_widget_get_visible (child))
-    _gtk_widget_get_preferred_size_for_size (child,
-                                             orientation,
-                                             for_size,
-                                             minimum, natural,
-                                             NULL, NULL);
+    gtk_widget_measure (child,
+                        orientation,
+                        for_size,
+                        minimum, natural,
+                        NULL, NULL);
 }
 
 static void
@@ -363,6 +347,22 @@ gtk_viewport_render (GtkCssGadget *gadget,
 }
 
 static void
+gtk_viewport_measure_ (GtkWidget     *widget,
+                      GtkOrientation  orientation,
+                      int             for_size,
+                      int            *minimum,
+                      int            *natural,
+                      int            *minimum_baseline,
+                      int            *natural_baseline)
+{
+  gtk_css_gadget_get_preferred_size (GTK_VIEWPORT (widget)->priv->gadget,
+                                     orientation,
+                                     for_size,
+                                     minimum, natural,
+                                     minimum_baseline, natural_baseline);
+}
+
+static void
 gtk_viewport_class_init (GtkViewportClass *class)
 {
   GObjectClass   *gobject_class;
@@ -384,10 +384,7 @@ gtk_viewport_class_init (GtkViewportClass *class)
   widget_class->unmap = gtk_viewport_unmap;
   widget_class->draw = gtk_viewport_draw;
   widget_class->size_allocate = gtk_viewport_size_allocate;
-  widget_class->get_preferred_width = gtk_viewport_get_preferred_width;
-  widget_class->get_preferred_height = gtk_viewport_get_preferred_height;
-  widget_class->get_preferred_width_for_height = gtk_viewport_get_preferred_width_for_height;
-  widget_class->get_preferred_height_for_width = gtk_viewport_get_preferred_height_for_width;
+  widget_class->measure = gtk_viewport_measure_;
   widget_class->queue_draw_region = gtk_viewport_queue_draw_region;
   
   gtk_widget_class_set_accessible_role (widget_class, ATK_ROLE_VIEWPORT);
@@ -961,53 +958,3 @@ gtk_viewport_adjustment_value_changed (GtkAdjustment *adjustment,
        gdk_window_move (priv->bin_window, new_x, new_y);
     }
 }
-
-static void
-gtk_viewport_get_preferred_width (GtkWidget *widget,
-                                  gint      *minimum_size,
-                                  gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_VIEWPORT (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_viewport_get_preferred_height (GtkWidget *widget,
-                                   gint      *minimum_size,
-                                   gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_VIEWPORT (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     -1,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_viewport_get_preferred_width_for_height (GtkWidget *widget,
-                                             gint       height,
-                                             gint      *minimum_size,
-                                             gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_VIEWPORT (widget)->priv->gadget,
-                                     GTK_ORIENTATION_HORIZONTAL,
-                                     height,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
-
-static void
-gtk_viewport_get_preferred_height_for_width (GtkWidget *widget,
-                                             gint       width,
-                                             gint      *minimum_size,
-                                             gint      *natural_size)
-{
-  gtk_css_gadget_get_preferred_size (GTK_VIEWPORT (widget)->priv->gadget,
-                                     GTK_ORIENTATION_VERTICAL,
-                                     width,
-                                     minimum_size, natural_size,
-                                     NULL, NULL);
-}
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index df6c2bd..25f2193 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -694,20 +694,13 @@ static gint               gtk_widget_event_internal               (GtkWidget        
*widget,
                                                                 GdkEvent         *event);
 static gboolean                gtk_widget_real_mnemonic_activate       (GtkWidget        *widget,
                                                                 gboolean          group_cycling);
-static void             gtk_widget_real_get_width               (GtkWidget        *widget,
-                                                                 gint             *minimum_size,
-                                                                 gint             *natural_size);
-static void             gtk_widget_real_get_height              (GtkWidget        *widget,
-                                                                 gint             *minimum_size,
-                                                                 gint             *natural_size);
-static void             gtk_widget_real_get_height_for_width    (GtkWidget        *widget,
-                                                                 gint              width,
-                                                                 gint             *minimum_height,
-                                                                 gint             *natural_height);
-static void             gtk_widget_real_get_width_for_height    (GtkWidget        *widget,
-                                                                 gint              height,
-                                                                 gint             *minimum_width,
-                                                                 gint             *natural_width);
+static void             gtk_widget_real_measure                 (GtkWidget        *widget,
+                                                                 GtkOrientation    orientation,
+                                                                 int               for_size,
+                                                                 int              *minimum,
+                                                                 int              *natural,
+                                                                 int              *minimum_baseline,
+                                                                 int              *natural_baseline);
 static void             gtk_widget_real_state_flags_changed     (GtkWidget        *widget,
                                                                  GtkStateFlags     old_state);
 static void             gtk_widget_real_queue_draw_region       (GtkWidget         *widget,
@@ -1012,11 +1005,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
   klass->unrealize = gtk_widget_real_unrealize;
   klass->size_allocate = gtk_widget_real_size_allocate;
   klass->get_request_mode = gtk_widget_real_get_request_mode;
-  klass->get_preferred_width = gtk_widget_real_get_width;
-  klass->get_preferred_height = gtk_widget_real_get_height;
-  klass->get_preferred_width_for_height = gtk_widget_real_get_width_for_height;
-  klass->get_preferred_height_for_width = gtk_widget_real_get_height_for_width;
-  klass->get_preferred_height_and_baseline_for_width = NULL;
+  klass->measure = gtk_widget_real_measure;
   klass->state_flags_changed = gtk_widget_real_state_flags_changed;
   klass->parent_set = NULL;
   klass->hierarchy_changed = NULL;
@@ -5450,8 +5439,7 @@ gtk_widget_size_allocate_with_baseline (GtkWidget     *widget,
   /* Never pass a baseline to a child unless it requested it.
      This means containers don't have to manually check for this. */
   if (baseline != -1 &&
-      (gtk_widget_get_valign_with_baseline (widget) != GTK_ALIGN_BASELINE ||
-       !_gtk_widget_has_baseline_support (widget)))
+      gtk_widget_get_valign_with_baseline (widget) != GTK_ALIGN_BASELINE)
     baseline = -1;
 
   alloc_needed = priv->alloc_needed;
@@ -13103,39 +13091,16 @@ gtk_widget_real_get_request_mode (GtkWidget *widget)
 }
 
 static void
-gtk_widget_real_get_width (GtkWidget *widget,
-                          gint      *minimum_size,
-                          gint      *natural_size)
-{
-  *minimum_size = 0;
-  *natural_size = 0;
-}
-
-static void
-gtk_widget_real_get_height (GtkWidget *widget,
-                           gint      *minimum_size,
-                           gint      *natural_size)
-{
-  *minimum_size = 0;
-  *natural_size = 0;
-}
-
-static void
-gtk_widget_real_get_height_for_width (GtkWidget *widget,
-                                      gint       width,
-                                      gint      *minimum_height,
-                                      gint      *natural_height)
-{
-  GTK_WIDGET_GET_CLASS (widget)->get_preferred_height (widget, minimum_height, natural_height);
-}
-
-static void
-gtk_widget_real_get_width_for_height (GtkWidget *widget,
-                                      gint       height,
-                                      gint      *minimum_width,
-                                      gint      *natural_width)
-{
-  GTK_WIDGET_GET_CLASS (widget)->get_preferred_width (widget, minimum_width, natural_width);
+gtk_widget_real_measure (GtkWidget *widget,
+                         GtkOrientation orientation,
+                         int        for_size,
+                         int       *minimum,
+                         int       *natural,
+                         int       *minimum_baseline,
+                         int       *natural_baseline)
+{
+  *minimum = 0;
+  *natural = 0;
 }
 
 /**
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 41ef613..ad373d2 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -400,20 +400,30 @@ struct _GtkWidgetClass
   /* size requests */
   GtkSizeRequestMode (* get_request_mode)               (GtkWidget      *widget);
 
-  void               (* get_preferred_height)           (GtkWidget       *widget,
-                                                         gint            *minimum_height,
-                                                         gint            *natural_height);
-  void               (* get_preferred_width_for_height) (GtkWidget       *widget,
-                                                         gint             height,
-                                                         gint            *minimum_width,
-                                                         gint            *natural_width);
-  void               (* get_preferred_width)            (GtkWidget       *widget,
-                                                         gint            *minimum_width,
-                                                         gint            *natural_width);
-  void               (* get_preferred_height_for_width) (GtkWidget       *widget,
-                                                         gint             width,
-                                                         gint            *minimum_height,
-                                                         gint            *natural_height);
+  //void               (* get_preferred_height)           (GtkWidget       *widget,
+                                                         //gint            *minimum_height,
+                                                         //gint            *natural_height);
+  //void               (* get_preferred_width_for_height) (GtkWidget       *widget,
+                                                         //gint             height,
+                                                         //gint            *minimum_width,
+                                                         //gint            *natural_width);
+  //void               (* get_preferred_width)            (GtkWidget       *widget,
+                                                         //gint            *minimum_width,
+                                                         //gint            *natural_width);
+  //void               (* get_preferred_height_for_width) (GtkWidget       *widget,
+                                                         //gint             width,
+                                                         //gint            *minimum_height,
+                                                         //gint            *natural_height);
+
+  void              (* measure) (GtkWidget      *widget,
+                                 GtkOrientation  orientation,
+                                 int             for_size,
+                                 int            *minimum,
+                                 int            *natural,
+                                 int            *minimum_baseline,
+                                 int            *natural_baseline);
+
+
 
   /* Mnemonics */
   gboolean (* mnemonic_activate)        (GtkWidget           *widget,
@@ -580,12 +590,6 @@ struct _GtkWidgetClass
   gboolean     (* touch_event)            (GtkWidget     *widget,
                                            GdkEventTouch *event);
 
-  void         (* get_preferred_height_and_baseline_for_width)  (GtkWidget     *widget,
-                                                                gint           width,
-                                                                gint          *minimum_height,
-                                                                gint          *natural_height,
-                                                                gint          *minimum_baseline,
-                                                                gint          *natural_baseline);
   void         (* adjust_baseline_request)(GtkWidget         *widget,
                                            gint              *minimum_baseline,
                                            gint              *natural_baseline);
@@ -693,6 +697,14 @@ void                gtk_widget_get_preferred_width_for_height (GtkWidget      *w
                                                                gint            height,
                                                                gint           *minimum_width,
                                                                gint           *natural_width);
+GDK_AVAILABLE_IN_3_90
+void gtk_widget_measure (GtkWidget      *widget,
+                         GtkOrientation  orientation,
+                         int             for_size,
+                         int            *minimum,
+                         int            *natural,
+                         int            *minimum_baseline,
+                         int            *natural_baseline);
 GDK_AVAILABLE_IN_3_10
 void   gtk_widget_get_preferred_height_and_baseline_for_width (GtkWidget     *widget,
                                                               gint           width,
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 4403ae3..b4b28fc 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -188,19 +188,11 @@ void         _gtk_widget_add_attached_window    (GtkWidget    *widget,
 void         _gtk_widget_remove_attached_window (GtkWidget    *widget,
                                                  GtkWindow    *window);
 
-void _gtk_widget_get_preferred_size_for_size   (GtkWidget         *widget,
-                                                GtkOrientation     orientation,
-                                                gint               size,
-                                                gint              *minimum,
-                                                gint              *natural,
-                                                gint              *minimum_baseline,
-                                                gint              *natural_baseline);
 void _gtk_widget_get_preferred_size_and_baseline(GtkWidget        *widget,
                                                 GtkRequisition    *minimum_size,
                                                 GtkRequisition    *natural_size,
                                                 gint              *minimum_baseline,
                                                 gint              *natural_baseline);
-gboolean _gtk_widget_has_baseline_support (GtkWidget *widget);
 
 const gchar*      _gtk_widget_get_accel_path               (GtkWidget *widget,
                                                             gboolean  *locked);
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 7499344..30ff7aa 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -516,22 +516,6 @@ static void        gtk_window_set_theme_variant         (GtkWindow  *window);
 
 static void        gtk_window_do_popup         (GtkWindow      *window,
                                                 GdkEventButton *event);
-
-static void gtk_window_get_preferred_width (GtkWidget *widget,
-                                            gint      *minimum_size,
-                                            gint      *natural_size);
-static void gtk_window_get_preferred_width_for_height (GtkWidget *widget,
-                                                       gint       height,
-                                                       gint      *minimum_size,
-                                                       gint      *natural_size);
-
-static void gtk_window_get_preferred_height (GtkWidget *widget,
-                                             gint      *minimum_size,
-                                             gint      *natural_size);
-static void gtk_window_get_preferred_height_for_width (GtkWidget *widget,
-                                                       gint       width,
-                                                       gint      *minimum_size,
-                                                       gint      *natural_size);
 static void gtk_window_style_updated (GtkWidget     *widget);
 static void gtk_window_state_flags_changed (GtkWidget     *widget,
                                             GtkStateFlags  previous_state);
@@ -665,6 +649,89 @@ startup_id_is_fake (const gchar* startup_id)
 }
 
 static void
+gtk_window_measure (GtkWidget      *widget,
+                    GtkOrientation  orientation,
+                    int             for_size,
+                    int            *minimum,
+                    int            *natural,
+                    int            *minimum_baseline,
+                    int            *natural_baseline)
+{
+  GtkWindow *window = GTK_WINDOW (widget);
+  GtkWindowPrivate *priv = window->priv;
+  GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
+  gboolean has_size_request = gtk_widget_has_size_request (widget);
+  int title_min_size = 0;
+  int title_nat_size = 0;
+  int child_min_size = 0;
+  int child_nat_size = 0;
+  GtkBorder window_border = { 0 };
+
+
+  if (priv->decorated && !priv->fullscreen)
+    {
+      get_shadow_width (window, &window_border);
+
+      if (orientation == GTK_ORIENTATION_HORIZONTAL)
+        for_size -= window_border.left + window_border.right;
+      else
+        for_size -= window_border.top + window_border.bottom;
+
+      if (priv->title_box != NULL &&
+          gtk_widget_get_visible (priv->title_box) &&
+          gtk_widget_get_child_visible (priv->title_box))
+        {
+          int size = for_size;
+          if (orientation == GTK_ORIENTATION_HORIZONTAL && for_size >= 0)
+            gtk_widget_measure (priv->title_box,
+                                orientation == GTK_ORIENTATION_HORIZONTAL ? GTK_ORIENTATION_VERTICAL :
+                                                                            GTK_ORIENTATION_HORIZONTAL,
+                                -1,
+                                NULL, &size,
+                                NULL, NULL);
+
+          gtk_widget_measure (priv->title_box,
+                              orientation,
+                              MAX (size, 0),
+                              &title_min_size, &title_nat_size,
+                              NULL, NULL);
+        }
+    }
+
+  if (child != NULL && gtk_widget_get_visible (child))
+    {
+      gtk_widget_measure (child,
+                          orientation,
+                          MAX (for_size, 0),
+                          &child_min_size, &child_nat_size,
+                          NULL, NULL);
+
+      if (child_nat_size == 0 && !has_size_request)
+        child_nat_size = NO_CONTENT_CHILD_NAT;
+    }
+  else if (!has_size_request)
+    {
+      child_nat_size = NO_CONTENT_CHILD_NAT;
+    }
+
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      title_min_size += window_border.left + window_border.right;
+      title_nat_size += window_border.left + window_border.right;
+      child_min_size += window_border.left + window_border.right;
+      child_nat_size += window_border.left + window_border.right;
+      *minimum = MAX (title_min_size, child_min_size);
+      *natural = MAX (title_nat_size, child_nat_size);
+    }
+  else
+    {
+      *minimum = title_min_size + child_min_size + window_border.top + window_border.bottom;
+      *natural = title_nat_size + child_nat_size + window_border.top + window_border.bottom;
+    }
+}
+
+
+static void
 gtk_window_class_init (GtkWindowClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -705,10 +772,7 @@ gtk_window_class_init (GtkWindowClass *klass)
   widget_class->focus = gtk_window_focus;
   widget_class->move_focus = gtk_window_move_focus;
   widget_class->window_state_event = gtk_window_state_event;
-  widget_class->get_preferred_width = gtk_window_get_preferred_width;
-  widget_class->get_preferred_width_for_height = gtk_window_get_preferred_width_for_height;
-  widget_class->get_preferred_height = gtk_window_get_preferred_height;
-  widget_class->get_preferred_height_for_width = gtk_window_get_preferred_height_for_width;
+  widget_class->measure = gtk_window_measure;
   widget_class->state_flags_changed = gtk_window_state_flags_changed;
   widget_class->style_updated = gtk_window_style_updated;
   widget_class->get_render_node = gtk_window_get_render_node;
@@ -8111,239 +8175,6 @@ gtk_window_real_set_focus (GtkWindow *window,
 }
 
 static void
-gtk_window_get_preferred_width (GtkWidget *widget,
-                                gint      *minimum_size,
-                                gint      *natural_size)
-{
-  GtkWindow *window;
-  GtkWidget *child;
-  GtkWindowPrivate *priv;
-  gint title_min = 0, title_nat = 0;
-  gint child_min = 0, child_nat = 0;
-  GtkBorder window_border = { 0 };
-  gboolean has_size_request;
-
-  window = GTK_WINDOW (widget);
-  priv = window->priv;
-  child  = gtk_bin_get_child (GTK_BIN (window));
-  has_size_request = gtk_widget_has_size_request (widget);
-
-  if (priv->decorated &&
-      !priv->fullscreen)
-    {
-      get_shadow_width (window, &window_border);
-
-      if (priv->title_box != NULL &&
-          gtk_widget_get_visible (priv->title_box) &&
-          gtk_widget_get_child_visible (priv->title_box))
-        gtk_widget_get_preferred_width (priv->title_box,
-                                        &title_min, &title_nat);
-
-      title_min += window_border.left + window_border.right;
-      title_nat += window_border.left + window_border.right;
-    }
-
-  if (child && gtk_widget_get_visible (child))
-    {
-      gtk_widget_get_preferred_width (child, &child_min, &child_nat);
-
-      if (child_nat == 0 && !has_size_request)
-        child_nat = NO_CONTENT_CHILD_NAT;
-      child_min += window_border.left + window_border.right;
-      child_nat += window_border.left + window_border.right;
-    }
-  else if (!has_size_request)
-    {
-      child_nat = NO_CONTENT_CHILD_NAT;
-    }
-
-  *minimum_size = MAX (title_min, child_min);
-  *natural_size = MAX (title_nat, child_nat);
-}
-
-
-static void
-gtk_window_get_preferred_width_for_height (GtkWidget *widget,
-                                           gint       height,
-                                           gint      *minimum_size,
-                                           gint      *natural_size)
-{
-  GtkWindow *window;
-  GtkWidget *child;
-  GtkWindowPrivate *priv;
-  gint title_min = 0, title_nat = 0;
-  gint child_min = 0, child_nat = 0;
-  gint title_height = 0;
-  GtkBorder window_border = { 0 };
-  gboolean has_size_request;
-
-  window = GTK_WINDOW (widget);
-  priv = window->priv;
-  child  = gtk_bin_get_child (GTK_BIN (window));
-  has_size_request = gtk_widget_has_size_request (widget);
-
-  if (priv->decorated &&
-      !priv->fullscreen)
-    {
-      get_shadow_width (window, &window_border);
-
-      height -= window_border.top + window_border.bottom;
-
-      if (priv->title_box != NULL &&
-          gtk_widget_get_visible (priv->title_box) &&
-          gtk_widget_get_child_visible (priv->title_box))
-        {
-          gtk_widget_get_preferred_height (priv->title_box,
-                                           NULL, &title_height);
-          gtk_widget_get_preferred_width_for_height (priv->title_box,
-                                                     title_height,
-                                                     &title_min, &title_nat);
-          height -= title_height;
-        }
-
-      title_min += window_border.left + window_border.right;
-      title_nat += window_border.left + window_border.right;
-    }
-
-  if (child && gtk_widget_get_visible (child))
-    {
-      gtk_widget_get_preferred_width_for_height (child,
-                                                 MAX (height, 0),
-                                                 &child_min, &child_nat);
-
-      if (child_nat == 0 && height == 0 && !has_size_request)
-        child_nat = NO_CONTENT_CHILD_NAT;
-      child_min += window_border.left + window_border.right;
-      child_nat += window_border.left + window_border.right;
-    }
-  else if (!has_size_request)
-    {
-      child_nat = NO_CONTENT_CHILD_NAT;
-    }
-
-  *minimum_size = MAX (title_min, child_min);
-  *natural_size = MAX (title_nat, child_nat);
-}
-
-static void
-gtk_window_get_preferred_height (GtkWidget *widget,
-                                 gint      *minimum_size,
-                                 gint      *natural_size)
-{
-  GtkWindow *window;
-  GtkWindowPrivate *priv;
-  GtkWidget *child;
-  int title_min = 0;
-  int title_height = 0;
-  GtkBorder window_border = { 0 };
-  gboolean has_size_request;
-
-  window = GTK_WINDOW (widget);
-  priv = window->priv;
-  child  = gtk_bin_get_child (GTK_BIN (window));
-  has_size_request = gtk_widget_has_size_request (widget);
-
-  *minimum_size = 0;
-  *natural_size = 0;
-
-  if (priv->decorated &&
-      !priv->fullscreen)
-    {
-      get_shadow_width (window, &window_border);
-
-      if (priv->title_box != NULL &&
-          gtk_widget_get_visible (priv->title_box) &&
-          gtk_widget_get_child_visible (priv->title_box))
-        gtk_widget_get_preferred_height (priv->title_box,
-                                         &title_min,
-                                         &title_height);
-
-      *minimum_size = title_min +
-                      window_border.top + window_border.bottom;
-
-      *natural_size = title_height +
-                      window_border.top + window_border.bottom;
-    }
-
-  if (child && gtk_widget_get_visible (child))
-    {
-      gint child_min, child_nat;
-      gtk_widget_get_preferred_height (child, &child_min, &child_nat);
-
-      if (child_nat == 0 && !has_size_request)
-        child_nat = NO_CONTENT_CHILD_NAT;
-      *minimum_size += child_min;
-      *natural_size += child_nat;
-    }
-  else if (!has_size_request)
-    {
-      *natural_size += NO_CONTENT_CHILD_NAT;
-    }
-}
-
-
-static void
-gtk_window_get_preferred_height_for_width (GtkWidget *widget,
-                                           gint       width,
-                                           gint      *minimum_size,
-                                           gint      *natural_size)
-{
-  GtkWindow *window;
-  GtkWindowPrivate *priv;
-  GtkWidget *child;
-  int title_min = 0;
-  int title_height = 0;
-  GtkBorder window_border = { 0 };
-  gboolean has_size_request;
-
-  window = GTK_WINDOW (widget);
-  priv = window->priv;
-  child  = gtk_bin_get_child (GTK_BIN (window));
-  has_size_request = gtk_widget_has_size_request (widget);
-
-  *minimum_size = 0;
-  *natural_size = 0;
-
-  if (priv->decorated &&
-      !priv->fullscreen)
-    {
-      get_shadow_width (window, &window_border);
-
-      width -= window_border.left + window_border.right;
-
-      if (priv->title_box != NULL &&
-          gtk_widget_get_visible (priv->title_box) &&
-          gtk_widget_get_child_visible (priv->title_box))
-        gtk_widget_get_preferred_height_for_width (priv->title_box,
-                                                   MAX (width, 0),
-                                                   &title_min,
-                                                   &title_height);
-
-      *minimum_size = title_min +
-                      window_border.top + window_border.bottom;
-
-      *natural_size = title_height +
-                      window_border.top + window_border.bottom;
-    }
-
-  if (child && gtk_widget_get_visible (child))
-    {
-      gint child_min, child_nat;
-      gtk_widget_get_preferred_height_for_width (child, MAX (width, 0),
-                                                 &child_min, &child_nat);
-
-      if (child_nat == 0 && width == 0 && !has_size_request)
-        child_nat = NO_CONTENT_CHILD_NAT;
-      *minimum_size += child_min;
-      *natural_size += child_nat;
-    }
-  else if (!has_size_request)
-    {
-      *natural_size += NO_CONTENT_CHILD_NAT;
-    }
-}
-
-static void
 gtk_window_state_flags_changed (GtkWidget     *widget,
                                 GtkStateFlags  previous_state)
 {
diff --git a/tests/gtkoffscreenbox.c b/tests/gtkoffscreenbox.c
index 2879be6..ed456eb 100644
--- a/tests/gtkoffscreenbox.c
+++ b/tests/gtkoffscreenbox.c
@@ -11,12 +11,13 @@
 
 static void        gtk_offscreen_box_realize       (GtkWidget       *widget);
 static void        gtk_offscreen_box_unrealize     (GtkWidget       *widget);
-static void        gtk_offscreen_box_get_preferred_width  (GtkWidget *widget,
-                                                           gint      *minimum,
-                                                           gint      *natural);
-static void        gtk_offscreen_box_get_preferred_height (GtkWidget *widget,
-                                                           gint      *minimum,
-                                                           gint      *natural);
+static void        gtk_offscreen_box_measure       (GtkWidget       *widget,
+                                                    GtkOrientation   orientation,
+                                                    int              for_size,
+                                                    int             *minimum,
+                                                    int             *natural,
+                                                    int             *minimum_baseline,
+                                                    int             *natural_baseline);
 static void        gtk_offscreen_box_size_allocate (GtkWidget       *widget,
                                                     GtkAllocation   *allocation);
 static gboolean    gtk_offscreen_box_damage        (GtkWidget       *widget,
@@ -123,8 +124,7 @@ gtk_offscreen_box_class_init (GtkOffscreenBoxClass *klass)
 
   widget_class->realize = gtk_offscreen_box_realize;
   widget_class->unrealize = gtk_offscreen_box_unrealize;
-  widget_class->get_preferred_width = gtk_offscreen_box_get_preferred_width;
-  widget_class->get_preferred_height = gtk_offscreen_box_get_preferred_height;
+  widget_class->measure = gtk_offscreen_box_measure;
   widget_class->size_allocate = gtk_offscreen_box_size_allocate;
   widget_class->draw = gtk_offscreen_box_draw;
 
@@ -512,28 +512,24 @@ gtk_offscreen_box_size_request (GtkWidget      *widget,
   requisition->height = h;
 }
 
-static void
-gtk_offscreen_box_get_preferred_width (GtkWidget *widget,
-                                       gint      *minimum,
-                                       gint      *natural)
-{
-  GtkRequisition requisition;
-
-  gtk_offscreen_box_size_request (widget, &requisition);
-
-  *minimum = *natural = requisition.width;
-}
 
 static void
-gtk_offscreen_box_get_preferred_height (GtkWidget *widget,
-                                        gint      *minimum,
-                                        gint      *natural)
+gtk_offscreen_box_measure (GtkWidget       *widget,
+                           GtkOrientation   orientation,
+                           int              for_size,
+                           int             *minimum,
+                           int             *natural,
+                           int             *minimum_baseline,
+                           int             *natural_baseline)
 {
   GtkRequisition requisition;
 
   gtk_offscreen_box_size_request (widget, &requisition);
 
-  *minimum = *natural = requisition.height;
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    *minimum = *natural = requisition.width;
+  else
+    *minimum = *natural = requisition.height;
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]