ec022ed37c76d74f2ebb7b3b772261fe037340b1
diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c
index 65f760b..e176812 100644
--- a/gtk/gtkcellview.c
+++ b/gtk/gtkcellview.c
@@ -25,6 +25,7 @@
 #include "gtksignal.h"
 #include "gtkcellrenderertext.h"
 #include "gtkcellrendererpixbuf.h"
+#include "gtkextendedlayout.h"
 #include "gtkprivate.h"
 #include <gobject/gmarshal.h>
 #include "gtkbuildable.h"
@@ -36,6 +37,7 @@ struct _GtkCellViewCellInfo
   GtkCellRenderer *cell;
 
   gint requested_width;
+  gint natural_width;
   gint real_width;
   guint expand : 1;
   guint pack : 1;
@@ -121,6 +123,9 @@ static void       gtk_cell_view_buildable_custom_tag_end       (GtkBuildable
 								const gchar   	      *tagname,
 								gpointer      	      *data);
 
+/* extended layout */
+static void       gtk_cell_view_extended_layout_init           (GtkExtendedLayoutIface *iface);
+
 static GtkBuildableIface *parent_buildable_iface;
 
 #define GTK_CELL_VIEW_GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_VIEW, GtkCellViewPrivate))
@@ -138,7 +143,9 @@ G_DEFINE_TYPE_WITH_CODE (GtkCellView, gtk_cell_view, GTK_TYPE_WIDGET,
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
 						gtk_cell_view_cell_layout_init)
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
-						gtk_cell_view_buildable_init))
+						gtk_cell_view_buildable_init)
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
+						gtk_cell_view_extended_layout_init))
 
 static void
 gtk_cell_view_class_init (GtkCellViewClass *klass)
@@ -317,6 +324,7 @@ gtk_cell_view_size_request (GtkWidget      *widget,
   GList *i;
   gboolean first_cell = TRUE;
   GtkCellView *cellview;
+  GtkRequisition natural_size;
 
   cellview = GTK_CELL_VIEW (widget);
 
@@ -341,6 +349,15 @@ gtk_cell_view_size_request (GtkWidget      *widget,
                                   &width, &height);
 
       info->requested_width = width;
+
+      if (GTK_EXTENDED_LAYOUT_HAS_NATURAL_SIZE (info->cell))
+        {
+          gtk_extended_layout_get_natural_size (GTK_EXTENDED_LAYOUT (info->cell), &natural_size);
+          info->natural_width = natural_size.width;
+        }
+      else
+        info->natural_width = info->requested_width;
+
       requisition->width += width;
       requisition->height = MAX (requisition->height, height);
 
@@ -352,11 +369,13 @@ static void
 gtk_cell_view_size_allocate (GtkWidget     *widget,
                              GtkAllocation *allocation)
 {
-  GList *i;
-  gint expand_cell_count = 0;
-  gint full_requested_width = 0;
-  gint extra_space;
   GtkCellView *cellview;
+  GList *i;
+
+  gint nexpand_cells = 0;
+  gint requested_width = 0;
+  gint natural_width = 0;
+  gint available, natural, extra;
 
   widget->allocation = *allocation;
 
@@ -371,43 +390,43 @@ gtk_cell_view_size_allocate (GtkWidget     *widget,
         continue;
 
       if (info->expand)
-        expand_cell_count++;
+        nexpand_cells++;
 
-      full_requested_width += info->requested_width;
+      requested_width += info->requested_width;
+      natural_width += info->natural_width - info->requested_width;
     }
 
-  extra_space = widget->allocation.width - full_requested_width;
-  if (extra_space < 0)
-    extra_space = 0;
-  else if (extra_space > 0 && expand_cell_count > 0)
-    extra_space /= expand_cell_count;
+  available = MAX (0, widget->allocation.width - requested_width);
+  natural = MIN (available, natural_width);
+  available -= natural;
+
+  if (nexpand_cells > 0)
+    extra = available / nexpand_cells;
+  else
+    extra = 0;
 
-  /* iterate list for PACK_START cells */
   for (i = cellview->priv->cell_list; i; i = i->next)
     {
       GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
 
-      if (info->pack == GTK_PACK_END)
-        continue;
-
       if (!info->cell->visible)
         continue;
 
-      info->real_width = info->requested_width + (info->expand?extra_space:0);
-    }
+      info->real_width = info->requested_width;
 
-  /* iterate list for PACK_END cells */
-  for (i = cellview->priv->cell_list; i; i = i->next)
-    {
-      GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
+      if (natural_width > 0)
+          info->real_width += natural * (info->natural_width - info->requested_width) / natural_width;
 
-      if (info->pack == GTK_PACK_START)
-        continue;
-
-      if (!info->cell->visible)
-        continue;
+      if (info->expand)
+        {
+          if (1 == nexpand_cells)
+            info->real_width += available;
+          else
+            info->real_width += extra;
 
-      info->real_width = info->requested_width + (info->expand?extra_space:0);
+          nexpand_cells -= 1;
+          available -= extra;
+        }
     }
 }
 
@@ -1128,6 +1147,36 @@ gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable,
 					    data);
 }
 
+static GtkExtendedLayoutFeatures
+gtk_cell_view_extended_layout_get_features (GtkExtendedLayout *layout)
+{
+  return GTK_EXTENDED_LAYOUT_NATURAL_SIZE;
+}
+
+static void
+gtk_cell_view_extended_layout_get_natural_size (GtkExtendedLayout *layout,
+                                                GtkRequisition    *requisition)
+{
+  GList *i;
+
+  requisition->width = 0;
+  requisition->height = GTK_WIDGET (layout)->requisition.height;
+
+  for (i = GTK_CELL_VIEW (layout)->priv->cell_list; i; i = i->next)
+    {
+      GtkCellViewCellInfo *info = (GtkCellViewCellInfo *)i->data;
+
+      if (info->cell->visible)
+        requisition->width += info->natural_width;
+    }
+}
+
+static void
+gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface)
+{
+  iface->get_features = gtk_cell_view_extended_layout_get_features;
+  iface->get_natural_size = gtk_cell_view_extended_layout_get_natural_size;
+}
 
 #define __GTK_CELL_VIEW_C__
 #include "gtkaliasdef.c"
