]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkcellarea.c
Correct calculation of the cell focus rectangle
[~andy/gtk] / gtk / gtkcellarea.c
index 9f5616b2ce216b8befb57f4bc9910f2798bcaba5..10190214e672d6ae3c56a0152a142f2f6af94c91 100644 (file)
  * @Short_Description: An abstract class for laying out #GtkCellRenderers
  * @Title: GtkCellArea
  *
- * The #GtkCellArea is an abstract class for laying out #GtkCellRenderers
- * onto a given area of a #GtkWidget.
+ * The #GtkCellArea is an abstract class for #GtkCellLayout widgets (also referred 
+ * to as "layouting widgets") to interface with an arbitrary number of #GtkCellRenderers
+ * and interact with the user for a given #GtkTreeModel row.
  *
- * The work of rendering #GtkCellRenderers can be very complicated; it involves
- * requesting size for cells, driving keyboard focus from cell to cell, rendering
- * the actual cells, painting the focus onto the currently focused cell and finally
- * activating cells which are %GTK_CELL_RENDERER_MODE_ACTIVATABLE and editing cells
- * which are %GTK_CELL_RENDERER_MODE_EDITABLE. The work is even more complex since
- * a cell renderer as opposed to a widget, is used to interact with an arbitrary
- * number of #GtkTreeModel rows instead of always displaying the same data.
+ * The cell area handles events, focus navigation, drawing and wraps geometrical
+ * size requests and allocations for a given row of data.
+ *
+ * Usually users dont have to interact with the #GtkCellArea directly unless they
+ * are implementing a cell layouting widget themselves.
  *
  * <refsect2 id="cell-area-geometry-management">
  * <title>Requesting area sizes</title>
  * interfaces. #GtkCellArea uses the same semantics to calculate the
  * size of an area for an arbitrary number of #GtkTreeModel rows.
  *
- * When requesting the size of a #GtkCellArea one needs to calculate
- * the size of a handful of rows, this will be done differently by
- * different #GtkCellLayout widgets. For instance a #GtkTreeViewColumn
+ * When requesting the size of a cell area one needs to calculate
+ * the size for a handful of rows, this will be done differently by
+ * different layouting widgets. For instance a #GtkTreeViewColumn
  * always lines up the areas from top to bottom while a #GtkIconView
- * on the other hand might enforce that areas maintain a fixed width
- * and then wrap the area around, thus requesting height for more
+ * on the other hand might enforce that all areas received the same
+ * width and wrap the areas around, requesting height for more cell 
  * areas when allocated less width.
  *
- * It's also important for #GtkCellAreas to maintain some cell 
- * alignments with areas rendered for different rows so that
- * a handful of rendered rows can allocate the same size for
- * a said cell across rows (and also to make sure to request
- * an appropriate size for the largest row after requesting
- * a hand full of rows). For this reason the #GtkCellArea
+ * It's also important for areas to maintain some cell 
+ * alignments with areas rendered for adjacent rows (cells can 
+ * appear "columnized" inside an area even when the size of
+ * cells are different in each row). For this reason the #GtkCellArea
  * uses a #GtkCellAreaContext object to store the alignments
- * and sizes along the way.
+ * and sizes along the way (as well as the overall largest minimum
+ * and natural size for all the rows which have been calculated
+ * with the said context).
+ *
+ * The #GtkCellAreaContext is an opaque object specific to the
+ * #GtkCellArea which created it (see gtk_cell_area_create_context()).
+ * The owning cell layouting widget can create as many contexts as
+ * it wishes to calculate sizes of rows which should receive the
+ * same size in at least one orientation (horizontally or vertically), 
+ * however it's important that the same #GtkCellAreaContext which
+ * was used to request the sizes for a given #GtkTreeModel row be
+ * used when rendering or processing events for that row.
  *
  * In order to request the width of all the rows at the root level
  * of a #GtkTreeModel one would do the following:
  * A simple example where rows are rendered from top to bottom and take up the full
  * width of the layouting widget would look like:
  * <example>
- *   <title>Requesting the width of a hand full of GtkTreeModel rows.</title>
+ *   <title>A typical #GtkWidgetClass.get_preferred_width() for a layouting widget.</title>
  *   <programlisting>
  * static void
  * foo_get_preferred_width (GtkWidget       *widget,
  * Note that the cached height in this example really depends on how the layouting
  * widget works. The layouting widget might decide to give every row it's minimum
  * or natural height or if the model content is expected to fit inside the layouting
- * widget with not scrolled window it would make sense to calculate the allocation
+ * widget with no scrolled window it would make sense to calculate the allocation
  * for each row at #GtkWidget.size_allocate() time using gtk_distribute_natural_allocation().
  * </para>
  * </refsect2>
  * customized derived areas can be implemented who are interested in handling
  * other events. Handling an event can trigger the #GtkCellArea::focus-changed
  * signal to fire as well as #GtkCellArea::add-editable in the case that
- * an editable cell was clicked and needs to start editing.
+ * an editable cell was clicked and needs to start editing. You can call
+ * gtk_cell_area_stop_editing() at any time to cancel any cell editing
+ * that is currently in progress.
  *
  * The #GtkCellArea drives keyboard focus from cell to cell in a way similar
  * to #GtkWidget. For layouting widgets that support giving focus to cells it's
  * <example>
  *   <title>Implementing keyboard focus navigation when displaying rows from top to bottom.</title>
  *   <programlisting>
- * static void
+ * static gboolean
  * foo_focus (GtkWidget       *widget,
  *            GtkDirectionType direction)
  * {
  *         }
  *       else
  *         {
- *          if (direction == GTK_DIR_RIGHT ||
- *              direction == GTK_DIR_LEFT)
- *            break;
- *          else if (direction == GTK_DIR_UP ||
- *                   direction == GTK_DIR_TAB_BACKWARD)
- *            {
- *                      if (focus_row == 0)
+ *           if (direction == GTK_DIR_RIGHT ||
+ *               direction == GTK_DIR_LEFT)
+ *             break;
+ *           else if (direction == GTK_DIR_UP ||
+ *                    direction == GTK_DIR_TAB_BACKWARD)
+ *            {
+ *               if (focus_row == 0)
  *                 break;
  *               else
  *                {
  *           else
  *             {
  *               if (focus_row == last_row)
- *                        break;
+ *                 break;
  *               else
  *                 {
  *                   focus_row++;
  * </example>
  * </para>
  * </refsect2>
+ * <refsect2 id="cell-properties">
+ * <title>Cell Properties</title>
+ * <para>
+ * The #GtkCellArea introduces <emphasis>cell properties</emphasis> for #GtkCellRenderers in very
+ * much the same way that #GtkContainer introduces <link linkend="child-properties">child properties</link>
+ * for #GtkWidgets. This provides some general interfaces for defining the relationship cell areas
+ * have with their cells. For instance in a #GtkCellAreaBox a cell might "expand" and recieve extra
+ * space when the area is allocated more than it's full natural request, or a cell might be configured
+ * to "align" with adjacent rows which were requested and rendered with the same #GtkCellAreaContext.
+ *
+ * Use gtk_cell_area_class_install_cell_property() to install cell properties
+ * for a cell area class and gtk_cell_area_class_find_cell_property() or
+ * gtk_cell_area_class_list_cell_properties() to get information about existing
+ * cell properties.
+ *
+ * To set the value of a cell property, use gtk_cell_area_cell_set_property(),
+ * gtk_cell_area_cell_set() or gtk_cell_area_cell_set_valist().
+ * To obtain the value of a cell property, use
+ * gtk_cell_area_cell_get_property(), gtk_cell_area_cell_get() or
+ * gtk_cell_area_cell_get_valist().
+ * </para>
+ * </refsect2>
  *
  */
 
@@ -339,6 +371,14 @@ static gint      gtk_cell_area_real_event                          (GtkCellArea
                                                                    GdkEvent             *event,
                                                                    const GdkRectangle   *cell_area,
                                                                    GtkCellRendererState  flags);
+static void      gtk_cell_area_real_render                         (GtkCellArea          *area,
+                                                                   GtkCellAreaContext   *context,
+                                                                   GtkWidget            *widget,
+                                                                   cairo_t              *cr,
+                                                                   const GdkRectangle   *background_area,
+                                                                   const GdkRectangle   *cell_area,
+                                                                   GtkCellRendererState  flags,
+                                                                   gboolean              paint_focus);
 static void      gtk_cell_area_real_apply_attributes               (GtkCellArea           *area,
                                                                    GtkTreeModel          *tree_model,
                                                                    GtkTreeIter           *iter,
@@ -361,7 +401,8 @@ static gboolean  gtk_cell_area_real_activate                       (GtkCellArea
                                                                    GtkCellAreaContext    *context,
                                                                    GtkWidget             *widget,
                                                                    const GdkRectangle    *cell_area,
-                                                                   GtkCellRendererState   flags);
+                                                                   GtkCellRendererState   flags,
+                                                                   gboolean               edit_only);
 
 /* GtkCellLayoutIface */
 static void      gtk_cell_area_cell_layout_init              (GtkCellLayoutIface    *iface);
@@ -384,14 +425,48 @@ static void      gtk_cell_area_reorder                       (GtkCellLayout
                                                              GtkCellRenderer       *cell,
                                                              gint                   position);
 static GList    *gtk_cell_area_get_cells                     (GtkCellLayout         *cell_layout);
+static GtkCellArea *gtk_cell_area_get_area                   (GtkCellLayout         *cell_layout);
 
+/* GtkBuildableIface */
+static void      gtk_cell_area_buildable_init                (GtkBuildableIface     *iface);
+static void      gtk_cell_area_buildable_custom_tag_end      (GtkBuildable          *buildable,
+                                                             GtkBuilder            *builder,
+                                                             GObject               *child,
+                                                             const gchar           *tagname,
+                                                             gpointer              *data);
 
-/* Used in forall loop to check if a child renderer is present */
+/* Used in foreach loop to check if a child renderer is present */
 typedef struct {
   GtkCellRenderer *renderer;
   gboolean         has_renderer;
 } HasRendererCheck;
 
+/* Used in foreach loop to get a cell's allocation */
+typedef struct {
+  GtkCellRenderer *renderer;
+  GdkRectangle     allocation;
+} RendererAllocationData;
+
+/* Used in foreach loop to render cells */
+typedef struct {
+  GtkCellArea         *area;
+  GtkWidget           *widget;
+  cairo_t             *cr;
+  GdkRectangle         focus_rect;
+  GtkCellRendererState render_flags;
+  guint                paint_focus : 1;
+  guint                focus_all   : 1;
+  guint                first_focus : 1;
+} CellRenderData;
+
+/* Used in foreach loop to get a cell by position */
+typedef struct {
+  gint             x;
+  gint             y;
+  GtkCellRenderer *renderer;
+  GdkRectangle     cell_area;
+} CellByPositionData;
+
 /* Attribute/Cell metadata */
 typedef struct {
   const gchar *attribute;
@@ -421,7 +496,7 @@ static gint            cell_attribute_find (CellAttribute         *cell_attribut
 static void            gtk_cell_area_add_editable     (GtkCellArea        *area,
                                                       GtkCellRenderer    *renderer,
                                                       GtkCellEditable    *editable,
-                                                      GdkRectangle       *cell_area);
+                                                      const GdkRectangle *cell_area);
 static void            gtk_cell_area_remove_editable  (GtkCellArea        *area,
                                                       GtkCellRenderer    *renderer,
                                                       GtkCellEditable    *editable);
@@ -493,10 +568,11 @@ static guint           cell_area_signals[LAST_SIGNAL] = { 0 };
 #define PARAM_SPEC_PARAM_ID(pspec)              ((pspec)->param_id)
 #define PARAM_SPEC_SET_PARAM_ID(pspec, id)      ((pspec)->param_id = (id))
 
-
 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkCellArea, gtk_cell_area, G_TYPE_INITIALLY_UNOWNED,
                                  G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
-                                                        gtk_cell_area_cell_layout_init));
+                                                        gtk_cell_area_cell_layout_init)
+                                 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
+                                                        gtk_cell_area_buildable_init))
 
 static void
 gtk_cell_area_init (GtkCellArea *area)
@@ -539,9 +615,9 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
   /* general */
   class->add              = NULL;
   class->remove           = NULL;
-  class->forall           = NULL;
+  class->foreach          = NULL;
   class->event            = gtk_cell_area_real_event;
-  class->render           = NULL;
+  class->render           = gtk_cell_area_real_render;
   class->apply_attributes = gtk_cell_area_real_apply_attributes;
 
   /* geometry */
@@ -567,6 +643,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
    * @is_expanded: whether the view is currently showing the children of this row
    *
    * This signal is emitted whenever applying attributes to @area from @model
+   *
+   * Since: 3.0
    */
   cell_area_signals[SIGNAL_APPLY_ATTRIBUTES] =
     g_signal_new (I_("apply-attributes"),
@@ -588,10 +666,12 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
    * @editable: the #GtkCellEditable widget to add
    * @cell_area: the #GtkWidget relative #GdkRectangle coordinates
    *             where @editable should be added
-   * @path:      the #GtkTreePath string this edit was initiated for
+   * @path: the #GtkTreePath string this edit was initiated for
    *
    * Indicates that editing has started on @renderer and that @editable
    * should be added to the owning cell layouting widget at @cell_area.
+   *
+   * Since: 3.0
    */
   cell_area_signals[SIGNAL_ADD_EDITABLE] =
     g_signal_new (I_("add-editable"),
@@ -615,6 +695,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
    *
    * Indicates that editing finished on @renderer and that @editable
    * should be removed from the owning cell layouting widget.
+   *
+   * Since: 3.0
    */
   cell_area_signals[SIGNAL_REMOVE_EDITABLE] =
     g_signal_new (I_("remove-editable"),
@@ -641,6 +723,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
    * currently focused renderer did not change, this is
    * because focus may change to the same renderer in the
    * same cell area for a different row of data.
+   *
+   * Since: 3.0
    */
   cell_area_signals[SIGNAL_FOCUS_CHANGED] =
     g_signal_new (I_("focus-changed"),
@@ -658,6 +742,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
    * GtkCellArea:focus-cell:
    *
    * The cell in the area that currently has focus
+   *
+   * Since: 3.0
    */
   g_object_class_install_property (object_class,
                                    PROP_FOCUS_CELL,
@@ -675,6 +761,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
    *
    * This property is read-only and only changes as
    * a result of a call gtk_cell_area_activate_cell().
+   *
+   * Since: 3.0
    */
   g_object_class_install_property (object_class,
                                    PROP_EDITED_CELL,
@@ -692,6 +780,8 @@ gtk_cell_area_class_init (GtkCellAreaClass *class)
    *
    * This property is read-only and only changes as
    * a result of a call gtk_cell_area_activate_cell().
+   *
+   * Since: 3.0
    */
   g_object_class_install_property (object_class,
                                    PROP_EDIT_WIDGET,
@@ -873,6 +963,7 @@ gtk_cell_area_real_event (GtkCellArea          *area,
                          GtkCellRendererState  flags)
 {
   GtkCellAreaPrivate *priv = area->priv;
+  gboolean            retval = FALSE;
 
   if (event->type == GDK_KEY_PRESS && (flags & GTK_CELL_RENDERER_FOCUSED) != 0)
     {
@@ -882,13 +973,176 @@ gtk_cell_area_real_event (GtkCellArea          *area,
       if (priv->edited_cell && (key_event->keyval == GDK_KEY_Escape))
        {
          gtk_cell_area_stop_editing (area, TRUE);
-         return TRUE;
+         retval = TRUE;
+       }
+    }
+  else if (event->type == GDK_BUTTON_PRESS)
+    {
+      GdkEventButton *button_event = (GdkEventButton *)event;
+
+      if (button_event->button == 1)
+       {
+         GtkCellRenderer *renderer = NULL;
+         GtkCellRenderer *focus_renderer;
+         GdkRectangle     alloc_area;
+         gint             event_x, event_y;
+
+         /* We may need some semantics to tell us the offset of the event
+          * window we are handling events for (i.e. GtkTreeView has a bin_window) */
+         event_x = button_event->x;
+         event_y = button_event->y;
+
+         /* Dont try to search for an event coordinate that is not in the area, that will
+          * trigger a runtime warning.
+          */
+         if (event_x >= cell_area->x && event_x <= cell_area->x + cell_area->width &&
+             event_y >= cell_area->y && event_y <= cell_area->y + cell_area->height)
+           renderer = 
+             gtk_cell_area_get_cell_at_position (area, context, widget,
+                                                 cell_area, event_x, event_y,
+                                                 &alloc_area);
+
+         if (renderer)
+           {
+             focus_renderer = gtk_cell_area_get_focus_from_sibling (area, renderer);
+             if (!focus_renderer)
+               focus_renderer = renderer;
+
+             /* If we're already editing, cancel it and set focus */
+             if (gtk_cell_area_get_edited_cell (area))
+               {
+                 /* XXX Was it really canceled in this case ? */
+                 gtk_cell_area_stop_editing (area, TRUE);
+                 gtk_cell_area_set_focus_cell (area, focus_renderer);
+                 retval = TRUE;
+               }
+             else
+               {
+                 /* If we are activating via a focus sibling, 
+                  * we need to fetch the right cell area for the real event renderer */
+                 if (focus_renderer != renderer)
+                   gtk_cell_area_get_cell_allocation (area, context, widget, focus_renderer,
+                                                      cell_area, &alloc_area);
+                 
+                 gtk_cell_area_set_focus_cell (area, focus_renderer);
+                 retval = gtk_cell_area_activate_cell (area, widget, focus_renderer,
+                                                       event, &alloc_area, flags);
+               }
+           }
+       }
+    }
+
+  return retval;
+}
+
+static gboolean
+render_cell (GtkCellRenderer        *renderer,
+            const GdkRectangle     *cell_area,
+            const GdkRectangle     *cell_background,
+            CellRenderData         *data)
+{
+  GtkCellRenderer      *focus_cell;
+  GtkCellRendererState  flags;
+  GdkRectangle          inner_area;
+
+  focus_cell = gtk_cell_area_get_focus_cell (data->area);
+  flags      = data->render_flags;
+
+  gtk_cell_area_inner_cell_area (data->area, data->widget, cell_area, &inner_area);
+
+  if ((flags & GTK_CELL_RENDERER_FOCUSED) &&
+      (data->focus_all || 
+       (focus_cell && 
+       (renderer == focus_cell || 
+        gtk_cell_area_is_focus_sibling (data->area, focus_cell, renderer)))))
+    {
+      gint focus_line_width;
+      GdkRectangle cell_focus;
+
+      gtk_cell_renderer_get_aligned_area (renderer, data->widget, flags, &inner_area, &cell_focus);
+
+      gtk_widget_style_get (data->widget,
+                            "focus-line-width", &focus_line_width,
+                            NULL);
+
+      /* The focus rectangle is located around the aligned area of the cell */
+      cell_focus.x -= focus_line_width;
+      cell_focus.y -= focus_line_width;
+      cell_focus.width += 2 * focus_line_width;
+      cell_focus.height += 2 * focus_line_width;
+
+      if (data->first_focus)
+       {
+         data->first_focus = FALSE;
+         data->focus_rect  = cell_focus;
+       }
+      else
+       {
+         gdk_rectangle_union (&data->focus_rect, &cell_focus, &data->focus_rect);
        }
     }
+  else
+    flags &= ~GTK_CELL_RENDERER_FOCUSED;
+
+  gtk_cell_renderer_render (renderer, data->cr, data->widget,
+                           cell_background, &inner_area, flags);
 
   return FALSE;
 }
 
+static void
+gtk_cell_area_real_render (GtkCellArea          *area,
+                          GtkCellAreaContext   *context,
+                          GtkWidget            *widget,
+                          cairo_t              *cr,
+                          const GdkRectangle   *background_area,
+                          const GdkRectangle   *cell_area,
+                          GtkCellRendererState  flags,
+                          gboolean              paint_focus)
+{
+  CellRenderData render_data = 
+    { 
+      area, 
+      widget, 
+      cr, 
+      { 0, }, 
+      flags, 
+      paint_focus, 
+      FALSE, TRUE
+    };
+
+  /* Make sure we dont paint a focus rectangle while there
+   * is an editable widget in play 
+   */
+  if (gtk_cell_area_get_edited_cell (area))
+    render_data.paint_focus = FALSE;
+
+  /* If no cell can activate but the caller wants focus painted,
+   * then we paint focus around all cells */
+  if ((flags & GTK_CELL_RENDERER_FOCUSED) != 0 && paint_focus && 
+      !gtk_cell_area_is_activatable (area))
+    render_data.focus_all = TRUE;
+
+  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, background_area, 
+                              (GtkCellAllocCallback)render_cell, &render_data);
+
+  if (render_data.paint_focus && 
+      render_data.focus_rect.width != 0 && 
+      render_data.focus_rect.height != 0)
+    {
+      GtkStateType renderer_state = 
+       flags & GTK_CELL_RENDERER_SELECTED ? GTK_STATE_SELECTED :
+       (flags & GTK_CELL_RENDERER_PRELIT ? GTK_STATE_PRELIGHT :
+        (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL));
+
+      gtk_paint_focus (gtk_widget_get_style (widget), cr, 
+                      renderer_state, widget,
+                      gtk_cell_area_get_style_detail (area),
+                      render_data.focus_rect.x,     render_data.focus_rect.y,
+                      render_data.focus_rect.width, render_data.focus_rect.height);
+    }
+}
+
 static void
 apply_cell_attributes (GtkCellRenderer *renderer,
                       CellInfo        *info,
@@ -989,13 +1243,15 @@ gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea        *area,
   GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, context, widget, minimum_width, natural_width);
 }
 
-static void
+static gboolean
 get_is_activatable (GtkCellRenderer *renderer,
                    gboolean        *activatable)
 {
 
   if (gtk_cell_renderer_is_activatable (renderer))
     *activatable = TRUE;
+
+  return *activatable;
 }
 
 static gboolean
@@ -1009,7 +1265,7 @@ gtk_cell_area_real_is_activatable (GtkCellArea *area)
    * Subclasses can override this in the case that they are also
    * rendering widgets as well as renderers.
    */
-  gtk_cell_area_forall (area, (GtkCellCallback)get_is_activatable, &activatable);
+  gtk_cell_area_foreach (area, (GtkCellCallback)get_is_activatable, &activatable);
 
   return activatable;
 }
@@ -1019,14 +1275,23 @@ gtk_cell_area_real_activate (GtkCellArea         *area,
                             GtkCellAreaContext  *context,
                             GtkWidget           *widget,
                             const GdkRectangle  *cell_area,
-                            GtkCellRendererState flags)
+                            GtkCellRendererState flags,
+                            gboolean             edit_only)
 {
   GtkCellAreaPrivate *priv = area->priv;
-  GdkRectangle        background_area;
+  GdkRectangle        renderer_area;
   GtkCellRenderer    *activate_cell = NULL;
+  GtkCellRendererMode mode;
 
   if (priv->focus_cell)
-    activate_cell = priv->focus_cell;
+    {
+      g_object_get (priv->focus_cell, "mode", &mode, NULL);
+
+      if (gtk_cell_renderer_get_visible (priv->focus_cell) &&
+         (edit_only ? mode == GTK_CELL_RENDERER_MODE_EDITABLE :
+          mode != GTK_CELL_RENDERER_MODE_INERT))
+       activate_cell = priv->focus_cell;
+    }
   else
     {
       GList *cells, *l;
@@ -1039,19 +1304,22 @@ gtk_cell_area_real_activate (GtkCellArea         *area,
        {
          GtkCellRenderer *renderer = l->data;
 
-         if (gtk_cell_renderer_is_activatable (renderer))
+         g_object_get (renderer, "mode", &mode, NULL);
+
+         if (gtk_cell_renderer_get_visible (renderer) &&
+             (edit_only ? mode == GTK_CELL_RENDERER_MODE_EDITABLE :
+              mode != GTK_CELL_RENDERER_MODE_INERT))
            activate_cell = renderer;
        }
       g_list_free (cells);
     }
-  
 
   if (activate_cell)
     {
       /* Get the allocation of the focused cell.
        */
       gtk_cell_area_get_cell_allocation (area, context, widget, activate_cell,
-                                        cell_area, &background_area);
+                                        cell_area, &renderer_area);
       
       /* Activate or Edit the cell
        *
@@ -1059,7 +1327,7 @@ gtk_cell_area_real_activate (GtkCellArea         *area,
        * the event argument anyway, worst case is we can synthesize one.
        */
       if (gtk_cell_area_activate_cell (area, widget, activate_cell, NULL,
-                                      &background_area, flags))
+                                      &renderer_area, flags))
        return TRUE;
     }
 
@@ -1080,6 +1348,7 @@ gtk_cell_area_cell_layout_init (GtkCellLayoutIface *iface)
   iface->clear_attributes   = gtk_cell_area_clear_attributes;
   iface->reorder            = gtk_cell_area_reorder;
   iface->get_cells          = gtk_cell_area_get_cells;
+  iface->get_area           = gtk_cell_area_get_area;
 }
 
 static void
@@ -1183,11 +1452,13 @@ gtk_cell_area_reorder (GtkCellLayout   *cell_layout,
             g_type_name (G_TYPE_FROM_INSTANCE (cell_layout)));
 }
 
-static void
+static gboolean
 accum_cells (GtkCellRenderer *renderer,
             GList          **accum)
 {
   *accum = g_list_prepend (*accum, renderer);
+
+  return FALSE;
 }
 
 static GList *
@@ -1195,13 +1466,40 @@ gtk_cell_area_get_cells (GtkCellLayout *cell_layout)
 {
   GList *cells = NULL;
 
-  gtk_cell_area_forall (GTK_CELL_AREA (cell_layout), 
-                       (GtkCellCallback)accum_cells,
-                       &cells);
+  gtk_cell_area_foreach (GTK_CELL_AREA (cell_layout), 
+                        (GtkCellCallback)accum_cells,
+                        &cells);
 
   return g_list_reverse (cells);
 }
 
+static GtkCellArea *
+gtk_cell_area_get_area (GtkCellLayout *cell_layout)
+{
+  return GTK_CELL_AREA (cell_layout);
+}
+
+/*************************************************************
+ *                   GtkBuildableIface                       *
+ *************************************************************/
+static void
+gtk_cell_area_buildable_init (GtkBuildableIface *iface)
+{
+  iface->add_child = _gtk_cell_layout_buildable_add_child;
+  iface->custom_tag_start = _gtk_cell_layout_buildable_custom_tag_start;
+  iface->custom_tag_end = gtk_cell_area_buildable_custom_tag_end;
+}
+
+static void
+gtk_cell_area_buildable_custom_tag_end (GtkBuildable *buildable,
+                                       GtkBuilder   *builder,
+                                       GObject      *child,
+                                       const gchar  *tagname,
+                                       gpointer     *data)
+{
+  /* Just ignore the boolean return from here */
+  _gtk_cell_layout_buildable_custom_tag_end (buildable, builder, child, tagname, data);
+}
 
 /*************************************************************
  *                            API                            *
@@ -1213,6 +1511,8 @@ gtk_cell_area_get_cells (GtkCellLayout *cell_layout)
  * @renderer: the #GtkCellRenderer to add to @area
  *
  * Adds @renderer to @area with the default child cell properties.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_add (GtkCellArea        *area,
@@ -1235,9 +1535,11 @@ gtk_cell_area_add (GtkCellArea        *area,
 /**
  * gtk_cell_area_remove:
  * @area: a #GtkCellArea
- * @renderer: the #GtkCellRenderer to add to @area
+ * @renderer: the #GtkCellRenderer to remove from @area
  *
  * Removes @renderer from @area.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_remove (GtkCellArea        *area,
@@ -1282,12 +1584,14 @@ gtk_cell_area_remove (GtkCellArea        *area,
               g_type_name (G_TYPE_FROM_INSTANCE (area)));
 }
 
-static void
+static gboolean
 get_has_renderer (GtkCellRenderer  *renderer,
                  HasRendererCheck *check)
 {
   if (renderer == check->renderer)
     check->has_renderer = TRUE;
+
+  return check->has_renderer;
 }
 
 /**
@@ -1297,7 +1601,9 @@ get_has_renderer (GtkCellRenderer  *renderer,
  *
  * Checks if @area contains @renderer.
  *
- * Returns: %TRUE if @renderer is in the @area.
+ * Return value: %TRUE if @renderer is in the @area.
+ *
+ * Since: 3.0
  */
 gboolean
 gtk_cell_area_has_renderer (GtkCellArea     *area,
@@ -1308,23 +1614,25 @@ gtk_cell_area_has_renderer (GtkCellArea     *area,
   g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
   g_return_val_if_fail (GTK_IS_CELL_RENDERER (renderer), FALSE);
 
-  gtk_cell_area_forall (area, (GtkCellCallback)get_has_renderer, &check);
+  gtk_cell_area_foreach (area, (GtkCellCallback)get_has_renderer, &check);
 
   return check.has_renderer;
 }
 
 /**
- * gtk_cell_area_forall:
+ * gtk_cell_area_foreach:
  * @area: a #GtkCellArea
  * @callback: the #GtkCellCallback to call
  * @callback_data: user provided data pointer
  *
  * Calls @callback for every #GtkCellRenderer in @area.
+ *
+ * Since: 3.0
  */
 void
-gtk_cell_area_forall (GtkCellArea        *area,
-                     GtkCellCallback     callback,
-                     gpointer            callback_data)
+gtk_cell_area_foreach (GtkCellArea        *area,
+                      GtkCellCallback     callback,
+                      gpointer            callback_data)
 {
   GtkCellAreaClass *class;
 
@@ -1333,49 +1641,51 @@ gtk_cell_area_forall (GtkCellArea        *area,
 
   class = GTK_CELL_AREA_GET_CLASS (area);
 
-  if (class->forall)
-    class->forall (area, callback, callback_data);
+  if (class->foreach)
+    class->foreach (area, callback, callback_data);
   else
-    g_warning ("GtkCellAreaClass::forall not implemented for `%s'", 
+    g_warning ("GtkCellAreaClass::foreach not implemented for `%s'", 
               g_type_name (G_TYPE_FROM_INSTANCE (area)));
 }
 
 /**
- * gtk_cell_area_get_cell_allocation:
+ * gtk_cell_area_foreach_alloc:
  * @area: a #GtkCellArea
- * @context: the #GtkCellAreaContext used to hold sizes for @area.
- * @widget: the #GtkWidget that @area is rendering on
- * @renderer: the #GtkCellRenderer to get the allocation for
- * @cell_area: the whole allocated area for @area in @widget
- *             for this row
- * @allocation: where to store the allocation for @renderer
+ * @context: the #GtkCellAreaContext for this row of data.
+ * @widget: the #GtkWidget that @area is rendering to
+ * @cell_area: the @widget relative coordinates and size for @area
+ * @background_area: the @widget relative coordinates of the background area
+ * @callback: the #GtkCellAllocCallback to call
+ * @callback_data: user provided data pointer
  *
- * Derives the allocation of @renderer inside @area if @area
- * were to be renderered in @cell_area.
+ * Calls @callback for every #GtkCellRenderer in @area with the
+ * allocated rectangle inside @cell_area.
+ *
+ * Since: 3.0
  */
 void
-gtk_cell_area_get_cell_allocation (GtkCellArea          *area,
-                                  GtkCellAreaContext   *context,       
-                                  GtkWidget            *widget,
-                                  GtkCellRenderer      *renderer,
-                                  const GdkRectangle   *cell_area,
-                                  GdkRectangle         *allocation)
+gtk_cell_area_foreach_alloc (GtkCellArea          *area,
+                            GtkCellAreaContext   *context,
+                            GtkWidget            *widget,
+                            const GdkRectangle   *cell_area,
+                            const GdkRectangle   *background_area,
+                            GtkCellAllocCallback  callback,
+                            gpointer              callback_data)
 {
   GtkCellAreaClass *class;
 
   g_return_if_fail (GTK_IS_CELL_AREA (area));
   g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
   g_return_if_fail (GTK_IS_WIDGET (widget));
-  g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
   g_return_if_fail (cell_area != NULL);
-  g_return_if_fail (allocation != NULL);
+  g_return_if_fail (callback != NULL);
 
   class = GTK_CELL_AREA_GET_CLASS (area);
 
-  if (class->get_cell_allocation)
-    class->get_cell_allocation (area, context, widget, renderer, cell_area, allocation);
+  if (class->foreach_alloc)
+    class->foreach_alloc (area, context, widget, cell_area, background_area, callback, callback_data);
   else
-    g_warning ("GtkCellAreaClass::get_cell_allocation not implemented for `%s'", 
+    g_warning ("GtkCellAreaClass::foreach_alloc not implemented for `%s'", 
               g_type_name (G_TYPE_FROM_INSTANCE (area)));
 }
 
@@ -1390,7 +1700,9 @@ gtk_cell_area_get_cell_allocation (GtkCellArea          *area,
  *
  * Delegates event handling to a #GtkCellArea.
  *
- * Returns: %TRUE if the event was handled by @area.
+ * Return value: %TRUE if the event was handled by @area.
+ *
+ * Since: 3.0
  */
 gint
 gtk_cell_area_event (GtkCellArea          *area,
@@ -1431,6 +1743,8 @@ gtk_cell_area_event (GtkCellArea          *area,
  *
  * Renders @area's cells according to @area's layout onto @widget at
  * the given coordinates.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_render (GtkCellArea          *area,
@@ -1467,6 +1781,8 @@ gtk_cell_area_render (GtkCellArea          *area,
  *
  * Sets the detail string used in any gtk_paint_*() functions
  * used by @area.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_set_style_detail (GtkCellArea *area,
@@ -1492,7 +1808,9 @@ gtk_cell_area_set_style_detail (GtkCellArea *area,
  * Gets the detail string used in any gtk_paint_*() functions
  * used by @area.
  *
- * Returns: the detail string.
+ * Return value: the detail string, the string belongs to the area and should not be freed.
+ *
+ * Since: 3.0
  */
 G_CONST_RETURN gchar *
 gtk_cell_area_get_style_detail (GtkCellArea *area)
@@ -1506,6 +1824,118 @@ gtk_cell_area_get_style_detail (GtkCellArea *area)
   return priv->style_detail;
 }
 
+static gboolean
+get_cell_allocation (GtkCellRenderer        *renderer,
+                    const GdkRectangle     *cell_area,
+                    const GdkRectangle     *cell_background,
+                    RendererAllocationData *data)
+{
+  if (data->renderer == renderer)
+    data->allocation = *cell_area;
+
+  return (data->renderer == renderer);
+}
+
+/**
+ * gtk_cell_area_get_cell_allocation:
+ * @area: a #GtkCellArea
+ * @context: the #GtkCellAreaContext used to hold sizes for @area.
+ * @widget: the #GtkWidget that @area is rendering on
+ * @renderer: the #GtkCellRenderer to get the allocation for
+ * @cell_area: the whole allocated area for @area in @widget
+ *             for this row
+ * @allocation: (out): where to store the allocation for @renderer
+ *
+ * Derives the allocation of @renderer inside @area if @area
+ * were to be renderered in @cell_area.
+ *
+ * Since: 3.0
+ */
+void
+gtk_cell_area_get_cell_allocation (GtkCellArea          *area,
+                                  GtkCellAreaContext   *context,       
+                                  GtkWidget            *widget,
+                                  GtkCellRenderer      *renderer,
+                                  const GdkRectangle   *cell_area,
+                                  GdkRectangle         *allocation)
+{
+  RendererAllocationData data = { renderer, { 0, } };
+
+  g_return_if_fail (GTK_IS_CELL_AREA (area));
+  g_return_if_fail (GTK_IS_CELL_AREA_CONTEXT (context));
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
+  g_return_if_fail (cell_area != NULL);
+  g_return_if_fail (allocation != NULL);
+
+  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area, 
+                              (GtkCellAllocCallback)get_cell_allocation, &data);
+
+  *allocation = data.allocation;
+}
+
+static gboolean
+get_cell_by_position (GtkCellRenderer     *renderer,
+                     const GdkRectangle  *cell_area,
+                     const GdkRectangle  *cell_background,
+                     CellByPositionData  *data)
+{
+  if (data->x >= cell_area->x && data->x < cell_area->x + cell_area->width &&
+      data->y >= cell_area->y && data->y < cell_area->y + cell_area->height)
+    {
+      data->renderer  = renderer;
+      data->cell_area = *cell_area;
+    }
+
+  return (data->renderer != NULL);
+}
+
+/**
+ * gtk_cell_area_get_cell_at_position:
+ * @area: a #GtkCellArea
+ * @context: the #GtkCellAreaContext used to hold sizes for @area.
+ * @widget: the #GtkWidget that @area is rendering on
+ * @cell_area: the whole allocated area for @area in @widget
+ *             for this row
+ * @x: the x position
+ * @y: the y position
+ * @alloc_area: (out) (allow-none): where to store the inner allocated area of the 
+ *                                  returned cell renderer, or %NULL.
+ *
+ * Gets the #GtkCellRenderer at @x and @y coordinates inside @area and optionally
+ * returns the full cell allocation for it inside @cell_area.
+ *
+ * Return value: the #GtkCellRenderer at @x and @y.
+ *
+ * Since: 3.0
+ */
+GtkCellRenderer *
+gtk_cell_area_get_cell_at_position (GtkCellArea          *area,
+                                   GtkCellAreaContext   *context,
+                                   GtkWidget            *widget,
+                                   const GdkRectangle   *cell_area,
+                                   gint                  x,
+                                   gint                  y,
+                                   GdkRectangle         *alloc_area)
+{
+  CellByPositionData data = { x, y, NULL, { 0, } };
+
+  g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL);
+  g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
+  g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+  g_return_val_if_fail (cell_area != NULL, NULL);
+  g_return_val_if_fail (x >= cell_area->x && x <= cell_area->x + cell_area->width, NULL);
+  g_return_val_if_fail (y >= cell_area->y && y <= cell_area->y + cell_area->height, NULL);
+
+  gtk_cell_area_foreach_alloc (area, context, widget, cell_area, cell_area, 
+                              (GtkCellAllocCallback)get_cell_by_position, &data);
+
+  if (alloc_area)
+    *alloc_area = data.cell_area;
+
+  return data.renderer;
+}
+
 /*************************************************************
  *                      API: Geometry                        *
  *************************************************************/
@@ -1520,7 +1950,9 @@ gtk_cell_area_get_style_detail (GtkCellArea *area)
  * one should render and handle events with the same #GtkCellAreaContext
  * which was used to request the size of those rows of data).
  *
- * Returns: a newly created #GtkCellAreaContext which can be used with @area.
+ * Return value: (transfer full): a newly created #GtkCellAreaContext which can be used with @area.
+ *
+ * Since: 3.0
  */
 GtkCellAreaContext *
 gtk_cell_area_create_context (GtkCellArea *area)
@@ -1540,6 +1972,46 @@ gtk_cell_area_create_context (GtkCellArea *area)
   return NULL;
 }
 
+/**
+ * gtk_cell_area_copy_context:
+ * @area: a #GtkCellArea
+ * @context: the #GtkCellAreaContext to copy
+ *
+ * This is sometimes needed for cases where rows need to share
+ * alignments in one orientation but may be separately grouped
+ * in the opposing orientation.
+ *
+ * For instance, #GtkIconView creates all icons (rows) to have
+ * the same width and the cells theirin to have the same
+ * horizontal alignments. However each row of icons may have
+ * a separate collective height. #GtkIconView uses this to
+ * request the heights of each row based on a context which
+ * was already used to request all the row widths that are
+ * to be displayed.
+ *
+ * Return value: (transfer full): a newly created #GtkCellAreaContext copy of @context.
+ *
+ * Since: 3.0
+ */
+GtkCellAreaContext *
+gtk_cell_area_copy_context (GtkCellArea        *area,
+                           GtkCellAreaContext *context)
+{
+  GtkCellAreaClass *class;
+
+  g_return_val_if_fail (GTK_IS_CELL_AREA (area), NULL);
+  g_return_val_if_fail (GTK_IS_CELL_AREA_CONTEXT (context), NULL);
+
+  class = GTK_CELL_AREA_GET_CLASS (area);
+
+  if (class->copy_context)
+    return class->copy_context (area, context);
+
+  g_warning ("GtkCellAreaClass::copy_context not implemented for `%s'", 
+            g_type_name (G_TYPE_FROM_INSTANCE (area)));
+  
+  return NULL;
+}
 
 /**
  * gtk_cell_area_get_request_mode:
@@ -1548,7 +2020,7 @@ gtk_cell_area_create_context (GtkCellArea *area)
  * Gets whether the area prefers a height-for-width layout
  * or a width-for-height layout.
  *
- * Returns: The #GtkSizeRequestMode preferred by @area.
+ * Return value: The #GtkSizeRequestMode preferred by @area.
  *
  * Since: 3.0
  */
@@ -1587,7 +2059,6 @@ gtk_cell_area_get_request_mode (GtkCellArea *area)
  * consult gtk_cell_area_context_get_preferred_width() after a series of
  * requests.
  *
- *
  * Since: 3.0
  */
 void
@@ -1750,6 +2221,8 @@ gtk_cell_area_get_preferred_width_for_height (GtkCellArea        *area,
  *
  * Connects an @attribute to apply values from @column for the
  * #GtkTreeModel in use.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_attribute_connect (GtkCellArea        *area,
@@ -1817,6 +2290,8 @@ gtk_cell_area_attribute_connect (GtkCellArea        *area,
  * Disconnects @attribute for the @renderer in @area so that
  * attribute will no longer be updated with values from the
  * model.
+ *
+ * Since: 3.0
  */
 void 
 gtk_cell_area_attribute_disconnect (GtkCellArea        *area,
@@ -1854,7 +2329,7 @@ gtk_cell_area_attribute_disconnect (GtkCellArea        *area,
 /**
  * gtk_cell_area_apply_attributes
  * @area: a #GtkCellArea
- * @tree_model: a #GtkTreeModel to pull values from
+ * @tree_model: the #GtkTreeModel to pull values from
  * @iter: the #GtkTreeIter in @tree_model to apply values for
  * @is_expander: whether @iter has children
  * @is_expanded: whether @iter is expanded in the view and
@@ -1862,6 +2337,8 @@ gtk_cell_area_attribute_disconnect (GtkCellArea        *area,
  *
  * Applies any connected attributes to the renderers in 
  * @area by pulling the values from @tree_model.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_apply_attributes (GtkCellArea  *area,
@@ -1887,8 +2364,14 @@ gtk_cell_area_apply_attributes (GtkCellArea  *area,
  * gtk_cell_area_apply_attributes() is called and can be
  * used to interact with renderers from #GtkCellArea
  * subclasses.
+ *
+ * Return value: The current #GtkTreePath string for the current
+ * attributes applied to @area. This string belongs to the area and
+ * should not be freed.
+ *
+ * Since: 3.0
  */
-const gchar *
+G_CONST_RETURN gchar *
 gtk_cell_area_get_current_path_string (GtkCellArea *area)
 {
   GtkCellAreaPrivate *priv;
@@ -1911,6 +2394,8 @@ gtk_cell_area_get_current_path_string (GtkCellArea *area)
  * @pspec: the #GParamSpec for the property
  *
  * Installs a cell property on a cell area class.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_class_install_cell_property (GtkCellAreaClass   *aclass,
@@ -1943,10 +2428,13 @@ gtk_cell_area_class_install_cell_property (GtkCellAreaClass   *aclass,
  * gtk_cell_area_class_find_cell_property:
  * @aclass: a #GtkCellAreaClass
  * @property_name: the name of the child property to find
- * @returns: (allow-none): the #GParamSpec of the child property or %NULL if @aclass has no
- *   child property with that name.
  *
  * Finds a cell property of a cell area class by name.
+ *
+ * Return value: (allow-none): the #GParamSpec of the child property or %NULL if @aclass has no
+ *   child property with that name.
+ *
+ * Since: 3.0
  */
 GParamSpec*
 gtk_cell_area_class_find_cell_property (GtkCellAreaClass   *aclass,
@@ -1965,10 +2453,13 @@ gtk_cell_area_class_find_cell_property (GtkCellAreaClass   *aclass,
  * gtk_cell_area_class_list_cell_properties:
  * @aclass: a #GtkCellAreaClass
  * @n_properties: location to return the number of cell properties found
- * @returns: a newly allocated %NULL-terminated array of #GParamSpec*.
- *           The array must be freed with g_free().
  *
  * Returns all cell properties of a cell area class.
+ *
+ * Return value: a newly allocated %NULL-terminated array of #GParamSpec*.
+ *           The array must be freed with g_free().
+ *
+ * Since: 3.0
  */
 GParamSpec**
 gtk_cell_area_class_list_cell_properties (GtkCellAreaClass  *aclass,
@@ -1998,7 +2489,9 @@ gtk_cell_area_class_list_cell_properties (GtkCellAreaClass  *aclass,
  *
  * Adds @renderer to @area, setting cell properties at the same time.
  * See gtk_cell_area_add() and gtk_cell_area_child_set() for more details.
- **/
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_add_with_properties (GtkCellArea        *area,
                                   GtkCellRenderer    *renderer,
@@ -2036,7 +2529,9 @@ gtk_cell_area_add_with_properties (GtkCellArea        *area,
  *           with @first_prop_name
  *
  * Sets one or more cell properties for @cell in @area.
- **/
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_cell_set (GtkCellArea        *area,
                        GtkCellRenderer    *renderer,
@@ -2062,7 +2557,9 @@ gtk_cell_area_cell_set (GtkCellArea        *area,
  *     optionally by more name/return location pairs, followed by %NULL
  *
  * Gets the values of one or more cell properties for @renderer in @area.
- **/
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_cell_get (GtkCellArea        *area,
                        GtkCellRenderer    *renderer,
@@ -2133,7 +2630,9 @@ area_set_cell_property (GtkCellArea     *area,
  *           with @first_prop_name
  *
  * Sets one or more cell properties for @renderer in @area.
- **/
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_cell_set_valist (GtkCellArea        *area,
                               GtkCellRenderer    *renderer,
@@ -2193,7 +2692,9 @@ gtk_cell_area_cell_set_valist (GtkCellArea        *area,
  *     optionally by more name/return location pairs, followed by %NULL
  *
  * Gets the values of one or more cell properties for @renderer in @area.
- **/
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_cell_get_valist (GtkCellArea        *area,
                               GtkCellRenderer    *renderer,
@@ -2250,7 +2751,9 @@ gtk_cell_area_cell_get_valist (GtkCellArea        *area,
  * @value: the value to set the cell property to
  *
  * Sets a cell property for @renderer in @area.
- **/
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_cell_set_property (GtkCellArea        *area,
                                 GtkCellRenderer    *renderer,
@@ -2286,7 +2789,9 @@ gtk_cell_area_cell_set_property (GtkCellArea        *area,
  * @value: a location to return the value
  *
  * Gets the value of a cell property for @renderer in @area.
- **/
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_cell_get_property (GtkCellArea        *area,
                                 GtkCellRenderer    *renderer,
@@ -2354,7 +2859,9 @@ gtk_cell_area_cell_get_property (GtkCellArea        *area,
  * Returns whether the area can do anything when activated,
  * after applying new attributes to @area.
  *
- * Returns: whether @area can do anything when activated.
+ * Return value: whether @area can do anything when activated.
+ *
+ * Since: 3.0
  */
 gboolean
 gtk_cell_area_is_activatable (GtkCellArea *area)
@@ -2377,7 +2884,9 @@ gtk_cell_area_is_activatable (GtkCellArea *area)
  * method to receive and navigate focus in it's own way particular
  * to how it lays out cells.
  *
- * Returns: %TRUE if focus remains inside @area as a result of this call.
+ * Return value: %TRUE if focus remains inside @area as a result of this call.
+ *
+ * Since: 3.0
  */
 gboolean
 gtk_cell_area_focus (GtkCellArea      *area,
@@ -2405,23 +2914,28 @@ gtk_cell_area_focus (GtkCellArea      *area,
  * @widget: the #GtkWidget that @area is rendering on
  * @cell_area: the size and location of @area relative to @widget's allocation
  * @flags: the #GtkCellRendererState flags for @area for this row of data.
+ * @edit_only: if %TRUE then only cell renderers that are %GTK_CELL_RENDERER_MODE_EDITABLE
+ *             will be activated.
  *
  * Activates @area, usually by activating the currently focused
  * cell, however some subclasses which embed widgets in the area
  * can also activate a widget if it currently has the focus.
  *
- * Returns: Whether @area was successfully activated.
+ * Return value: Whether @area was successfully activated.
+ *
+ * Since: 3.0
  */
 gboolean
 gtk_cell_area_activate (GtkCellArea         *area,
                        GtkCellAreaContext  *context,
                        GtkWidget           *widget,
                        const GdkRectangle  *cell_area,
-                       GtkCellRendererState flags)
+                       GtkCellRendererState flags,
+                       gboolean             edit_only)
 {
   g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
 
-  return GTK_CELL_AREA_GET_CLASS (area)->activate (area, context, widget, cell_area, flags);
+  return GTK_CELL_AREA_GET_CLASS (area)->activate (area, context, widget, cell_area, flags, edit_only);
 }
 
 
@@ -2435,6 +2949,8 @@ gtk_cell_area_activate (GtkCellArea         *area,
  * is called. It's also up to the #GtkCellArea implementation
  * to update the focused cell when receiving events from
  * gtk_cell_area_event() appropriately.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_set_focus_cell (GtkCellArea     *area,
@@ -2474,7 +2990,9 @@ gtk_cell_area_set_focus_cell (GtkCellArea     *area,
  *
  * Retrieves the currently focused cell for @area
  *
- * Returns: the currently focused cell in @area.
+ * Return value: the currently focused cell in @area.
+ *
+ * Since: 3.0
  */
 GtkCellRenderer *
 gtk_cell_area_get_focus_cell (GtkCellArea *area)
@@ -2505,6 +3023,8 @@ gtk_cell_area_get_focus_cell (GtkCellArea *area)
  *
  * Events handled by focus siblings can also activate the given
  * focusable @renderer.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_add_focus_sibling (GtkCellArea     *area,
@@ -2548,6 +3068,8 @@ gtk_cell_area_add_focus_sibling (GtkCellArea     *area,
  * 
  * Removes @sibling from @renderer's focus sibling list 
  * (see gtk_cell_area_add_focus_sibling()).
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_remove_focus_sibling (GtkCellArea     *area,
@@ -2583,6 +3105,8 @@ gtk_cell_area_remove_focus_sibling (GtkCellArea     *area,
  * 
  * Returns %TRUE if @sibling is one of @renderer's focus siblings
  * (see gtk_cell_area_add_focus_sibling()).
+ *
+ * Since: 3.0
  */
 gboolean
 gtk_cell_area_is_focus_sibling (GtkCellArea     *area,
@@ -2618,7 +3142,10 @@ gtk_cell_area_is_focus_sibling (GtkCellArea     *area,
  *
  * Gets the focus sibling cell renderers for @renderer.
  *
- * Returns: A #GList of #GtkCellRenderers. The returned list is internal and should not be freed.
+ * Return value: (element-type GtkCellRenderer) (transfer none): A #GList of #GtkCellRenderers. 
+ *       The returned list is internal and should not be freed.
+ *
+ * Since: 3.0
  */
 const GList *
 gtk_cell_area_get_focus_siblings (GtkCellArea     *area,
@@ -2647,7 +3174,9 @@ gtk_cell_area_get_focus_siblings (GtkCellArea     *area,
  * then chose to activate the focus cell for which the event
  * cell may have been a sibling.
  *
- * Returns: the #GtkCellRenderer for which @renderer is a sibling, or %NULL.
+ * Return value: the #GtkCellRenderer for which @renderer is a sibling, or %NULL.
+ *
+ * Since: 3.0
  */
 GtkCellRenderer *
 gtk_cell_area_get_focus_from_sibling (GtkCellArea          *area,
@@ -2690,7 +3219,7 @@ static void
 gtk_cell_area_add_editable (GtkCellArea        *area,
                            GtkCellRenderer    *renderer,
                            GtkCellEditable    *editable,
-                           GdkRectangle       *cell_area)
+                           const GdkRectangle *cell_area)
 {
   g_signal_emit (area, cell_area_signals[SIGNAL_ADD_EDITABLE], 0, 
                 renderer, editable, cell_area, area->priv->current_path);
@@ -2788,7 +3317,9 @@ gtk_cell_area_set_edit_widget (GtkCellArea     *area,
  * Gets the #GtkCellRenderer in @area that is currently
  * being edited.
  *
- * Returns: The currently edited #GtkCellRenderer
+ * Return value: The currently edited #GtkCellRenderer
+ *
+ * Since: 3.0
  */
 GtkCellRenderer   *
 gtk_cell_area_get_edited_cell (GtkCellArea *area)
@@ -2809,7 +3340,9 @@ gtk_cell_area_get_edited_cell (GtkCellArea *area)
  * Gets the #GtkCellEditable widget currently used
  * to edit the currently edited cell.
  *
- * Returns: The currently active #GtkCellEditable widget
+ * Return value: The currently active #GtkCellEditable widget
+ *
+ * Since: 3.0
  */
 GtkCellEditable *
 gtk_cell_area_get_edit_widget (GtkCellArea *area)
@@ -2838,7 +3371,9 @@ gtk_cell_area_get_edit_widget (GtkCellArea *area)
  * for keyboard events for free in it's own GtkCellArea->activate()
  * implementation.
  *
- * Returns: whether cell activation was successful
+ * Return value: whether cell activation was successful
+ *
+ * Since: 3.0
  */
 gboolean
 gtk_cell_area_activate_cell (GtkCellArea          *area,
@@ -2849,7 +3384,6 @@ gtk_cell_area_activate_cell (GtkCellArea          *area,
                             GtkCellRendererState  flags)
 {
   GtkCellRendererMode mode;
-  GdkRectangle        inner_area;
   GtkCellAreaPrivate *priv;
   
   g_return_val_if_fail (GTK_IS_CELL_AREA (area), FALSE);
@@ -2859,12 +3393,6 @@ gtk_cell_area_activate_cell (GtkCellArea          *area,
 
   priv = area->priv;
 
-  /* Remove margins from the background area to produce the cell area.
-   *
-   * XXX Maybe have to do some rtl mode treatment here...
-   */
-  gtk_cell_area_inner_cell_area (area, widget, cell_area, &inner_area);
-
   g_object_get (renderer, "mode", &mode, NULL);
 
   if (mode == GTK_CELL_RENDERER_MODE_ACTIVATABLE)
@@ -2873,7 +3401,7 @@ gtk_cell_area_activate_cell (GtkCellArea          *area,
                                      event, widget,
                                      priv->current_path,
                                      cell_area,
-                                     &inner_area,
+                                     cell_area,
                                      flags))
        return TRUE;
     }
@@ -2886,7 +3414,7 @@ gtk_cell_area_activate_cell (GtkCellArea          *area,
                                         event, widget,
                                         priv->current_path,
                                         cell_area,
-                                        &inner_area,
+                                        cell_area,
                                         flags);
       
       if (editable_widget != NULL)
@@ -2898,7 +3426,7 @@ gtk_cell_area_activate_cell (GtkCellArea          *area,
          
          /* Signal that editing started so that callers can get 
           * a handle on the editable_widget */
-         gtk_cell_area_add_editable (area, priv->focus_cell, editable_widget, &inner_area);
+         gtk_cell_area_add_editable (area, priv->focus_cell, editable_widget, cell_area);
 
          /* If the signal was successfully handled start the editing */
          if (gtk_widget_get_parent (GTK_WIDGET (editable_widget)))
@@ -2932,6 +3460,8 @@ gtk_cell_area_activate_cell (GtkCellArea          *area,
  *
  * If @canceled is %TRUE, the cell renderer will emit
  * the ::editing-canceled signal.
+ *
+ * Since: 3.0
  */
 void
 gtk_cell_area_stop_editing (GtkCellArea *area,
@@ -2968,6 +3498,20 @@ gtk_cell_area_stop_editing (GtkCellArea *area,
  *         API: Convenience for area implementations         *
  *************************************************************/
 
+/**
+ * gtk_cell_area_inner_cell_area:
+ * @area: a #GtkCellArea
+ * @widget: the #GtkWidget that @area is rendering onto
+ * @cell_area: the @widget relative coordinates where one of @area's cells 
+ *             is to be placed
+ * @inner_area: (out): the return location for the inner cell area
+ *
+ * This is a convenience function for #GtkCellArea implementations
+ * to get the inner area where a given #GtkCellRenderer will be
+ * rendered. It removes any padding previously added by gtk_cell_area_request_renderer().
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_inner_cell_area (GtkCellArea        *area,
                               GtkWidget          *widget,
@@ -2991,6 +3535,25 @@ gtk_cell_area_inner_cell_area (GtkCellArea        *area,
   inner_area->height -= focus_line_width * 2;
 }
 
+/**
+ * gtk_cell_area_request_renderer:
+ * @area: a #GtkCellArea
+ * @renderer: the #GtkCellRenderer to request size for
+ * @orientation: the #GtkOrientation in which to request size
+ * @widget: the #GtkWidget that @area is rendering onto
+ * @for_size: the allocation contextual size to request for, or -1 if
+ * the base request for the orientation is to be returned.
+ * @minimum_size: (out) (allow-none): location to store the minimum size, or %NULL
+ * @natural_size: (out) (allow-none): location to store the natural size, or %NULL
+ *
+ * This is a convenience function for #GtkCellArea implementations
+ * to request size for cell renderers. It's important to use this
+ * function to request size and then use gtk_cell_area_inner_cell_area()
+ * at render and event time since this function will add padding
+ * around the cell for focus painting.
+ *
+ * Since: 3.0
+ */
 void
 gtk_cell_area_request_renderer (GtkCellArea        *area,
                                GtkCellRenderer    *renderer,