Index: gtk/gtkcellrendererpixbuf.c
===================================================================
--- gtk/gtkcellrendererpixbuf.c	(revision 18015)
+++ gtk/gtkcellrendererpixbuf.c	(working copy)
@@ -104,6 +104,7 @@
   object_class->set_property = gtk_cell_renderer_pixbuf_set_property;
 
   cell_class->get_size = gtk_cell_renderer_pixbuf_get_size;
+  cell_class->get_content_size = gtk_cell_renderer_pixbuf_get_size;
   cell_class->render = gtk_cell_renderer_pixbuf_render;
 
   g_object_class_install_property (object_class,
Index: gtk/gtktreeviewcolumn.c
===================================================================
--- gtk/gtktreeviewcolumn.c	(revision 18015)
+++ gtk/gtktreeviewcolumn.c	(working copy)
@@ -51,7 +51,8 @@
   PROP_ALIGNMENT,
   PROP_REORDERABLE,
   PROP_SORT_INDICATOR,
-  PROP_SORT_ORDER
+  PROP_SORT_ORDER,
+  PROP_INPLACE_TIPS
 };
 
 enum
@@ -321,6 +322,13 @@
                                                       GTK_SORT_ASCENDING,
                                                       GTK_PARAM_READWRITE));
   
+  g_object_class_install_property (object_class,
+                                   PROP_INPLACE_TIPS,
+                                   g_param_spec_boolean ("inplace-tips",
+                                                         P_("Inplace tips"),
+                                                         P_("Whether to show covered and ellipsized cell data"),
+                                                         FALSE,
+                                                         GTK_PARAM_READWRITE));
 }
 
 static void
@@ -355,6 +363,7 @@
   tree_column->dirty = TRUE;
   tree_column->sort_order = GTK_SORT_ASCENDING;
   tree_column->show_sort_indicator = FALSE;
+  tree_column->show_inplace_tips = TRUE; /* XXX: True for testing only */
   tree_column->property_changed_signal = 0;
   tree_column->sort_clicked_signal = 0;
   tree_column->sort_column_changed_signal = 0;
@@ -483,6 +492,11 @@
       gtk_tree_view_column_set_sort_order (tree_column,
                                            g_value_get_enum (value));
       break;
+
+    case PROP_INPLACE_TIPS:
+      gtk_tree_view_column_set_inplace_tips (tree_column,
+                                             g_value_get_boolean (value));
+      break;
       
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -581,6 +595,11 @@
       g_value_set_enum (value,
                         gtk_tree_view_column_get_sort_order (tree_column));
       break;
+
+    case PROP_INPLACE_TIPS:
+      g_value_set_boolean (value,
+                           gtk_tree_view_column_get_inplace_tips (tree_column));
+      break;
       
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2483,6 +2502,49 @@
 }
 
 /**
+ * gtk_tree_view_column_set_inplace_tips:
+ * @tree_column: A #GtkTreeViewColumn.
+ * @setting: %TRUE to display covered or ellipsized cell data on hover
+ *
+ * Call this function with a @setting of %TRUE to display a tooltip style
+ * display of the cell's contents when the mouse hovers over a cell taht cannot
+ * otherwise completely display its contents.
+ *
+ **/
+void
+gtk_tree_view_column_set_inplace_tips (GtkTreeViewColumn *tree_column,
+                                       gboolean           setting)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+
+  setting = setting != FALSE;
+
+  if (setting == tree_column->show_inplace_tips)
+    {
+      return;
+    }
+  
+  tree_column->show_inplace_tips = setting;
+  /* XXX: notify? */
+}
+
+/**
+ * gtk_tree_view_column_get_inplace_tips:
+ * @tree_column: a #GtkTreeViewColumn
+ *
+ * Gets the value set by gtk_tree_view_column_set_inplace_tips().
+ *
+ * Return value: whether covered or ellipsized cell data is shown on hover.
+ **/
+gboolean
+gtk_tree_view_column_get_inplace_tips (GtkTreeViewColumn *tree_column)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
+
+  return tree_column->show_inplace_tips;
+}
+
+/**
  * gtk_tree_view_column_cell_set_cell_data:
  * @tree_column: A #GtkTreeViewColumn.
  * @tree_model: The #GtkTreeModel to to get the cell renderers attributes from.
@@ -2543,25 +2605,32 @@
 
 }
 
+enum {
+  CELL_SIZE_NEGOTIATED,
+  CELL_SIZE_CONTENT
+};
+
 /**
- * gtk_tree_view_column_cell_get_size:
+ * gtk_tree_view_column_cell_get_size_helper:
  * @tree_column: A #GtkTreeViewColumn.
  * @cell_area: The area a cell in the column will be allocated, or %NULL
  * @x_offset: location to return x offset of a cell relative to @cell_area, or %NULL
  * @y_offset: location to return y offset of a cell relative to @cell_area, or %NULL
  * @width: location to return width needed to render a cell, or %NULL
  * @height: location to return height needed to render a cell, or %NULL
+ * @method: sizing to perform: negotiated or content's full size
  * 
  * Obtains the width and height needed to render the column.  This is used
  * primarily by the #GtkTreeView.
  **/
-void
-gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
-				    GdkRectangle      *cell_area,
-				    gint              *x_offset,
-				    gint              *y_offset,
-				    gint              *width,
-				    gint              *height)
+static void
+gtk_tree_view_column_cell_get_size_helper (GtkTreeViewColumn *tree_column,
+				           GdkRectangle      *cell_area,
+				           gint              *x_offset,
+				           gint              *y_offset,
+				           gint              *width,
+				           gint              *height,
+                                           gint               method)
 {
   GList *list;
   gboolean first_cell = TRUE;
@@ -2590,23 +2659,102 @@
       if (first_cell == FALSE && width)
 	*width += tree_column->spacing;
 
-      gtk_cell_renderer_get_size (info->cell,
-				  tree_column->tree_view,
-				  cell_area,
-				  x_offset,
-				  y_offset,
-				  &new_width,
-				  &new_height);
+      if (method == CELL_SIZE_NEGOTIATED)
+        {
+          gtk_cell_renderer_get_size (info->cell,
+                                      tree_column->tree_view,
+                                      cell_area,
+                                      x_offset,
+                                      y_offset,
+                                      &new_width,
+                                      &new_height);
+        }
+      else if (method == CELL_SIZE_CONTENT)
+        {
+          gtk_cell_renderer_get_content_size (info->cell,
+                                              tree_column->tree_view,
+                                              cell_area,
+                                              x_offset,
+                                              y_offset,
+                                              &new_width,
+                                              &new_height);
+        }
 
       if (height)
 	* height = MAX (*height, new_height + focus_line_width * 2);
-      info->requested_width = MAX (info->requested_width, new_width + focus_line_width * 2);
-      if (width)
-	* width += info->requested_width;
+      if (method == CELL_SIZE_NEGOTIATED)
+        {
+          info->requested_width = MAX (info->requested_width, new_width + focus_line_width * 2);
+          if (width)
+            * width += info->requested_width;
+        }
+      else if (method == CELL_SIZE_CONTENT)
+        {
+          if (width)
+            * width += new_width + focus_line_width * 2;
+        }
       first_cell = FALSE;
     }
 }
 
+/**
+ * gtk_tree_view_column_cell_get_size:
+ * @tree_column: A #GtkTreeViewColumn.
+ * @cell_area: The area a cell in the column will be allocated or %NULL
+ * @x_offset: location to return x offset of a cell relative to @cell_area or %NULL
+ * @x_offset: location to return y offset of a cell relative to @cell_area or %NULL
+ * @width: location to return width needed to render a cell, or %NULL
+ * @height: location to return height needed to render a cell, or %NULL
+ *
+ * Obtains the width and height needed to render the column. This is used
+ * primarily by the #GtkTreeView.
+ **/
+void
+gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
+                                    GdkRectangle      *cell_area,
+                                    gint              *x_offset,
+                                    gint              *y_offset,
+                                    gint              *width,
+                                    gint              *height)
+{
+    gtk_tree_view_column_cell_get_size_helper (tree_column,
+                                               cell_area,
+                                               x_offset,
+                                               y_offset,
+                                               width,
+                                               height,
+                                               CELL_SIZE_NEGOTIATED);
+}
+
+/**
+ * gtk_tree_view_column_cell_get_content_size:
+ * @tree_column: A #GtkTreeViewColumn.
+ * @cell_area: The area a cell in the column will be allocated or %NULL
+ * @x_offset: location to return x offset of a cell relative to @cell_area or %NULL
+ * @x_offset: location to return y offset of a cell relative to @cell_area or %NULL
+ * @width: location to return width needed to render a cell, or %NULL
+ * @height: location to return height needed to render a cell, or %NULL
+ *
+ * Obtains the width and height needed to render the column. This is used
+ * primarily by the #GtkTreeView.
+ **/
+void
+gtk_tree_view_column_cell_get_content_size (GtkTreeViewColumn *tree_column,
+                                            GdkRectangle      *cell_area,
+                                            gint              *x_offset,
+                                            gint              *y_offset,
+                                            gint              *width,
+                                            gint              *height)
+{
+    gtk_tree_view_column_cell_get_size_helper (tree_column,
+                                               cell_area,
+                                               x_offset,
+                                               y_offset,
+                                               width,
+                                               height,
+                                               CELL_SIZE_CONTENT);
+}
+
 /* rendering, event handling and rendering focus are somewhat complicated, and
  * quite a bit of code.  Rather than duplicate them, we put them together to
  * keep the code in one place.
Index: gtk/gtktreeviewcolumn.h
===================================================================
--- gtk/gtktreeviewcolumn.h	(revision 18015)
+++ gtk/gtktreeviewcolumn.h	(working copy)
@@ -105,6 +105,7 @@
   guint reorderable         : 1;
   guint use_resized_width   : 1;
   guint expand              : 1;
+  guint show_inplace_tips   : 1;
 };
 
 struct _GtkTreeViewColumnClass
@@ -208,6 +209,9 @@
 void                    gtk_tree_view_column_set_sort_order      (GtkTreeViewColumn       *tree_column,
 								  GtkSortType              order);
 GtkSortType             gtk_tree_view_column_get_sort_order      (GtkTreeViewColumn       *tree_column);
+void                    gtk_tree_view_column_set_inplace_tips    (GtkTreeViewColumn       *tree_column,
+                                                                  gboolean                 setting);
+gboolean                gtk_tree_view_column_get_inplace_tips    (GtkTreeViewColumn       *tree_column);
 
 
 /* These functions are meant primarily for interaction between the GtkTreeView and the column.
@@ -223,6 +227,12 @@
 								  gint                    *y_offset,
 								  gint                    *width,
 								  gint                    *height);
+void                    gtk_tree_view_column_cell_get_content_size (GtkTreeViewColumn       *tree_column,
+								    GdkRectangle            *cell_area,
+								    gint                    *x_offset,
+								    gint                    *y_offset,
+								    gint                    *width,
+								    gint                    *height);
 gboolean                gtk_tree_view_column_cell_is_visible     (GtkTreeViewColumn       *tree_column);
 void                    gtk_tree_view_column_focus_cell          (GtkTreeViewColumn       *tree_column,
 								  GtkCellRenderer         *cell);
Index: gtk/gtktreeview.c
===================================================================
--- gtk/gtktreeview.c	(revision 18015)
+++ gtk/gtktreeview.c	(working copy)
@@ -1320,6 +1320,8 @@
 
   tree_view->priv->grid_lines = GTK_TREE_VIEW_GRID_LINES_NONE;
   tree_view->priv->tree_lines_enabled = FALSE;
+
+  tree_view->priv->inplace_tips = NULL;
 }
 
 
@@ -3015,7 +3017,469 @@
     }
 }
 
+/***************************************/
+/**** gtk_tree_view_inplace_tips class */
+
+enum {
+  PROP_0_,
+  PROP_TREEVIEW,
+  PROP_TREECOLUMN,
+  PROP_TREEPATH
+};
+
+typedef struct _GtkTreeViewInplaceTips GtkTreeViewInplaceTips;
+struct _GtkTreeViewInplaceTips
+{
+  GtkWindow          window;
+  GtkTreeView       *tree_view;
+  GtkTreeViewColumn *column;
+  GtkTreePath       *path;
+  GList             *signal_ids;
+  guint              cell_left;
+  guint              cell_width;
+};
+
+typedef struct _GtkTreeViewInplaceTipsClass GtkTreeViewInplaceTipsClass;
+struct _GtkTreeViewInplaceTipsClass
+{
+  GtkWindowClass parent_class;
+  GdkPixmap         *empty_mask;
+};
+
+#define GTK_TYPE_TREE_VIEW_INPLACE_TIPS                 (gtk_tree_view_inplace_tips_get_type ())
+#define GTK_TREE_VIEW_INPLACE_TIPS(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TREE_VIEW_INPLACE_TIPS, GtkTreeViewInplaceTips))
+#define GTK_TREE_VIEW_INPLACE_TIPS_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_VIEW_INPLACE_TIPS, GtkTreeViewInplaceTipsClass))
+#define GTK_IS_TREE_VIEW_INPLACE_TIPS(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TREE_VIEW_INPLACE_TIPS))
+#define GTK_IS_TREE_VIEW_INPLACE_TIPS_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TREE_VIEW_INPLACE_TIPS))
+#define GTK_TREE_VIEW_INPLACE_TIPS_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TREE_VIEW_INPLACE_TIPS, GtkTreeViewInplaceTipsClass))
+
+static GtkWidget* gtk_tree_view_inplace_tips_new        (GtkTreeView           *tree_view);
+static void gtk_tree_view_inplace_tips_dispose          (GObject               *object);
+static void gtk_tree_view_inplace_tips_finalize         (GObject               *object);
+static gint gtk_tree_view_inplace_tips_expose_event     (GtkWidget             *widget,
+                                                         GdkEventExpose        *event);
+static void gtk_tree_view_inplace_tips_set_property     (GObject               *object,
+                                                         guint                  prop_id,
+                                                         const GValue          *value,
+                                                         GParamSpec            *pspec);
+static void gtk_tree_view_inplace_tips_get_property     (GObject               *object,
+                                                         guint                  prop_id,
+                                                         GValue                *value,
+                                                         GParamSpec            *pspec);
+
+G_DEFINE_TYPE (GtkTreeViewInplaceTips, gtk_tree_view_inplace_tips, GTK_TYPE_WINDOW);
+
+static void gtk_tree_view_inplace_tips_class_init (GtkTreeViewInplaceTipsClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) klass;
+  widget_class = (GtkWidgetClass*) klass;
+
+  gobject_class->dispose = gtk_tree_view_inplace_tips_dispose;
+  gobject_class->finalize = gtk_tree_view_inplace_tips_finalize;
+  gobject_class->set_property = gtk_tree_view_inplace_tips_set_property;
+  gobject_class->get_property = gtk_tree_view_inplace_tips_get_property;
+
+  widget_class->expose_event= gtk_tree_view_inplace_tips_expose_event;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_TREEVIEW,
+                                   g_param_spec_object ("treeview",
+                                                        P_("TreeView"),
+                                                        P_("The associated Tree View"),
+                                                        GTK_TYPE_TREE_VIEW,
+                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_TREECOLUMN,
+                                   g_param_spec_object ("column",
+                                                        P_("TreeViewColumn"),
+                                                        P_("Set which column to show"),
+                                                        GTK_TYPE_TREE_VIEW_COLUMN,
+                                                        GTK_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class,
+                                   PROP_TREEPATH,
+                                   g_param_spec_pointer ("path",
+                                                         P_("TreePath"),
+                                                         P_("Set which path to show"),
+                                                         GTK_PARAM_READWRITE));
+
+  klass->empty_mask = gdk_pixmap_new (NULL, 1, 1, 1);
+}
+
+GtkWidget*
+gtk_tree_view_inplace_tips_new (GtkTreeView *tree_view)
+{
+  GtkTreeViewInplaceTips *tips;
+
+  g_return_val_if_fail (tree_view != NULL, NULL);
+
+  tips = g_object_new (GTK_TYPE_TREE_VIEW_INPLACE_TIPS,
+                       "type", GTK_WINDOW_POPUP,
+                       "treeview", tree_view,
+                       NULL);
+
+  return GTK_WIDGET (tips);
+}
+
 static void
+gtk_tree_view_inplace_tips_init (GtkTreeViewInplaceTips *tips)
+{
+  gtk_widget_set_name (GTK_WIDGET (tips), "gtk-tooltips");
+  tips->column = NULL;
+  tips->path = NULL;
+  tips->cell_left = 0;
+  tips->cell_width = 0;
+  tips->signal_ids = NULL;
+}
+
+static void
+gtk_tree_view_inplace_tips_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (gtk_tree_view_inplace_tips_parent_class)->dispose (object);
+}
+
+static void
+gtk_tree_view_inplace_tips_finalize (GObject *object)
+{
+  GtkTreeViewInplaceTips *tips;
+  tips = GTK_TREE_VIEW_INPLACE_TIPS (object);
+
+  gtk_tree_path_free (tips->path);
+  while (tips->signal_ids)
+    {
+      g_signal_handler_disconnect (tips->tree_view,
+                                   GPOINTER_TO_INT (tips->signal_ids->data));
+      tips->signal_ids = g_list_remove (tips->signal_ids, tips->signal_ids->data);
+    }
+
+  G_OBJECT_CLASS (gtk_tree_view_inplace_tips_parent_class)->finalize (object);
+}
+
+static void
+gtk_tree_view_inplace_tips_get_position (GtkTreeViewInplaceTips *tips,
+                                         GdkRectangle *rect)
+{
+  GdkRectangle cell_rect;
+  GdkRectangle vis_rect;
+  gint tree_x, tree_y;
+  gint width = 0, height = 0;
+  GdkScreen *screen;
+  gint screen_width;
+
+  g_return_if_fail (tips != NULL);
+  g_return_if_fail (rect != NULL);
+  g_return_if_fail (tips->tree_view != NULL);
+  g_return_if_fail (tips->column != NULL);
+  g_return_if_fail (tips->path != NULL);
+
+  gtk_tree_view_get_cell_area (tips->tree_view, tips->path, tips->column, &cell_rect);
+  gtk_tree_view_tree_window_to_tree_coords (tips->tree_view,
+                                            cell_rect.x, cell_rect.y,
+                                            &(cell_rect.x), &(cell_rect.y));
+  gtk_tree_view_get_visible_rect (tips->tree_view, &vis_rect);
+  gdk_window_get_origin (tips->tree_view->priv->bin_window, &tree_x, &tree_y);
+
+  gtk_tree_view_column_cell_get_content_size (tips->column, NULL, NULL, NULL, &width, &height);
+
+  rect->x = tree_x + cell_rect.x;
+  rect->y = tree_y + cell_rect.y - vis_rect.y;
+  rect->width = width;
+  rect->height = cell_rect.height;
+
+  if (gtk_widget_get_direction (GTK_WIDGET (tips->tree_view)) != GTK_TEXT_DIR_LTR)
+    {
+      rect->x += cell_rect.width - width;
+    }
+
+  screen = gtk_window_get_screen (GTK_WINDOW (tips));
+  screen_width = gdk_screen_get_width(screen);
+  rect->width = CLAMP (rect->width, 0, screen_width);
+  rect->x = CLAMP (rect->x, 0, screen_width - rect->width);
+}
+
+static gint
+gtk_tree_view_inplace_tips_expose_event (GtkWidget      *widget,
+                                         GdkEventExpose *event)
+{
+  GtkTreeViewInplaceTips *tips;
+  GdkRectangle background;
+  GtkTreeIter iter;
+
+  gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
+                      GTK_SHADOW_OUT, &event->area, widget, "tooltip", 0, 0, -1, -1);
+  tips = GTK_TREE_VIEW_INPLACE_TIPS (widget);
+  gdk_window_get_frame_extents (GTK_WIDGET (tips)->window, &background);
+  background.x = 0;
+  background.y = 0;
+
+  gtk_tree_model_get_iter (tips->tree_view->priv->model, &iter, tips->path);
+  gtk_tree_view_column_cell_set_cell_data (tips->column, tips->tree_view->priv->model, &iter, FALSE, FALSE);
+
+  _gtk_tree_view_column_cell_render (tips->column,
+                                     GTK_WIDGET (tips)->window,
+                                     &background,
+                                     &background,
+                                     &event->area,
+                                     0);
+
+  gtk_widget_input_shape_combine_mask (GTK_WIDGET (tips),
+                                       GTK_TREE_VIEW_INPLACE_TIPS_GET_CLASS (tips)->empty_mask,
+                                       0, 0);
+
+  return FALSE;
+}
+
+static gboolean
+gtk_tree_view_inplace_tips_hide (GtkWidget              *tree_view,
+                                 GtkTreeViewInplaceTips *tips)
+{
+  GValue value = {0,};
+  gtk_widget_hide (GTK_WIDGET (tips));
+
+  g_value_init (&value, G_TYPE_POINTER);
+  g_value_set_pointer (&value, NULL);
+  g_object_set_property (G_OBJECT (tips), "path", &value);
+  g_value_unset (&value);
+
+  g_value_init (&value, G_TYPE_OBJECT);
+  g_value_set_object (&value, NULL);
+  g_object_set_property (G_OBJECT (tips), "column", &value);
+  g_value_unset (&value);
+
+  return FALSE;
+}
+
+static gboolean
+gtk_tree_view_inplace_tips_hide_event (GtkWidget              *tree_view,
+                                       GdkEvent               *event,
+                                       GtkTreeViewInplaceTips *tips)
+{
+  return gtk_tree_view_inplace_tips_hide (tree_view, tips);
+}
+
+static void
+gtk_tree_view_inplace_tips_set_property (GObject      *object,
+                                         guint         prop_id,
+                                         const GValue *value,
+                                         GParamSpec   *pspec)
+{
+  GtkTreeViewInplaceTips *tips;
+  guint id;
+  gboolean reposition = FALSE;
+
+  tips = GTK_TREE_VIEW_INPLACE_TIPS (object);
+
+  switch (prop_id)
+    {
+    case PROP_TREEVIEW:
+      tips->tree_view = GTK_TREE_VIEW (g_value_get_object (value));
+      id = g_signal_connect (tips->tree_view,
+                             "scroll-event",
+                             G_CALLBACK (gtk_tree_view_inplace_tips_hide_event),
+                             tips);
+      tips->signal_ids = g_list_prepend (tips->signal_ids,
+                                         GINT_TO_POINTER (id));
+      id = g_signal_connect (tips->tree_view,
+                             "leave-notify-event",
+                             G_CALLBACK (gtk_tree_view_inplace_tips_hide_event),
+                             tips);
+      tips->signal_ids = g_list_prepend (tips->signal_ids,
+                                         GINT_TO_POINTER (id));
+      id = g_signal_connect (tips->tree_view,
+                             "columns-changed",
+                             G_CALLBACK (gtk_tree_view_inplace_tips_hide),
+                             tips);
+      tips->signal_ids = g_list_prepend (tips->signal_ids,
+                                         GINT_TO_POINTER (id));
+      id = g_signal_connect (tips->tree_view,
+                             "cursor-changed",
+                             G_CALLBACK (gtk_tree_view_inplace_tips_hide),
+                             tips);
+      tips->signal_ids = g_list_prepend (tips->signal_ids,
+                                         GINT_TO_POINTER (id));
+      break;
+
+    case PROP_TREECOLUMN:
+      {
+        GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (g_value_get_object (value));
+        if (tips->column != column)
+          {
+            if (tips->column)
+              {
+                g_object_unref (tips->column);
+                tips->column = NULL;
+              }
+            if (column)
+              {
+                tips->column = g_object_ref (column);
+                reposition = TRUE;
+              }
+          }
+      }
+      break;
+
+    case PROP_TREEPATH:
+      {
+        GtkTreePath *path = (GtkTreePath*) g_value_get_pointer (value);
+        if (tips->path && (!path || gtk_tree_path_compare (tips->path, path)))
+          {
+            gtk_tree_path_free(tips->path);
+            tips->path = NULL;
+          }
+        if (path && !tips->path)
+          {
+            tips->path = gtk_tree_path_copy (path);
+            reposition = TRUE;
+          }
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  if (reposition && tips->column && tips->path)
+    {
+      GdkRectangle rect = { 0, };
+      gtk_tree_view_inplace_tips_get_position (tips, &rect);
+
+      gtk_widget_realize (GTK_WIDGET (tips));
+      gtk_widget_hide (GTK_WIDGET (tips));
+      gtk_window_move (GTK_WINDOW (tips), rect.x, rect.y);
+      gtk_window_resize (GTK_WINDOW (tips), rect.width, rect.height);
+      gtk_widget_show (GTK_WIDGET (tips));
+    }
+}
+
+static void
+gtk_tree_view_inplace_tips_get_property (GObject    *object,
+                                         guint       prop_id,
+                                         GValue     *value,
+                                         GParamSpec *pspec)
+{
+  GtkTreeViewInplaceTips *tips = GTK_TREE_VIEW_INPLACE_TIPS (object);
+
+  switch (prop_id)
+    {
+    case PROP_TREEVIEW:
+      g_value_set_object (value, tips->tree_view);
+      break;
+
+    case PROP_TREECOLUMN:
+      g_value_set_object (value, tips->column);
+      break;
+
+    case PROP_TREEPATH:
+      g_value_set_pointer (value, (gpointer)tips->path);
+      break;
+
+    default:
+      break;
+    }
+}
+/* gtk_tree_view_inplace_tips class ****/
+/***************************************/
+
+static void
+do_inplace_tips (GtkTreeView *tree_view,
+                 GtkRBTree   *tree,
+                 GtkRBNode   *node,
+                 /* these are in tree_window coords */
+                 gint         x,
+                 gint         y)
+{
+  GtkTreePath *path;
+  GtkTreeViewColumn *column;
+  gboolean ltr;
+
+  if (!gtk_tree_view_get_path_at_pos (tree_view, x, y, &path, &column, NULL, NULL))
+    return;
+
+  ltr = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_LTR);
+
+  if (column->show_inplace_tips)
+    {
+      GdkRectangle cell_rect;
+      GdkRectangle vis_rect;
+      GtkTreeIter iter;
+      gint width, height;
+      gboolean contents_too_large;
+      gboolean contents_scrolled_off;
+      gboolean contents_under_pointer;
+
+      gtk_tree_view_get_cell_area (tree_view, path, column, &cell_rect);
+      gtk_tree_view_tree_window_to_tree_coords (tree_view, cell_rect.x, cell_rect.y, &(cell_rect.x), &(cell_rect.y));
+      gtk_tree_view_get_visible_rect (tree_view, &vis_rect);
+
+      gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
+      gtk_tree_view_column_cell_set_cell_data (column, tree_view->priv->model, &iter, FALSE, FALSE);
+      gtk_tree_view_column_cell_get_content_size (column, NULL, NULL, NULL, &width, &height);
+
+      contents_too_large = (width > cell_rect.width) || (height > cell_rect.height);
+      if (ltr)
+        {
+          contents_scrolled_off = (cell_rect.x < vis_rect.x) ||
+            (cell_rect.y < vis_rect.y) ||
+            (cell_rect.x + width > vis_rect.x + vis_rect.width) ||
+            (cell_rect.y + cell_rect.height > vis_rect.y + vis_rect.height);
+          contents_under_pointer = (x >= cell_rect.x) && (x < cell_rect.x + width);
+        }
+      else
+        {
+          contents_scrolled_off = (cell_rect.x + cell_rect.width - width < vis_rect.x) ||
+            (cell_rect.y < vis_rect.y) ||
+            (cell_rect.x + cell_rect.width > vis_rect.x + vis_rect.width) ||
+            (cell_rect.y + cell_rect.height > vis_rect.y + vis_rect.height);
+          contents_under_pointer = (x >= cell_rect.x + cell_rect.width - width) &&
+            (x < cell_rect.x + cell_rect.width);
+        }
+
+      if (contents_under_pointer && (contents_too_large || contents_scrolled_off))
+        {
+          GValue value = { 0, };
+          GtkTreeViewInplaceTips *tips;
+          tips = GTK_TREE_VIEW_INPLACE_TIPS (tree_view->priv->inplace_tips);
+
+          if (!tips)
+            {
+              tree_view->priv->inplace_tips = gtk_tree_view_inplace_tips_new (tree_view);
+              tips = GTK_TREE_VIEW_INPLACE_TIPS (tree_view->priv->inplace_tips);
+            }
+
+          g_value_init (&value, G_TYPE_POINTER);
+          g_value_set_pointer (&value, path);
+          g_object_set_property (G_OBJECT (tips), "path", &value);
+          g_value_unset (&value);
+
+          g_value_init (&value, G_TYPE_OBJECT);
+          g_value_set_object (&value, column);
+          g_object_set_property (G_OBJECT (tips), "column", &value);
+          g_value_unset (&value);
+
+          tips->cell_width = cell_rect.width;
+          tips->cell_left = ltr ? 0 : width - cell_rect.width;
+
+          gtk_window_present (GTK_WINDOW (tips));
+        }
+      else
+        {
+          GtkTreeViewInplaceTips *tips;
+          tips = GTK_TREE_VIEW_INPLACE_TIPS (tree_view->priv->inplace_tips);
+
+          if (tips)
+            {
+              gtk_tree_view_inplace_tips_hide (GTK_WIDGET (tree_view), tips);
+            }
+        }
+    }
+  gtk_tree_path_free (path);
+}
+
+static void
 do_prelight (GtkTreeView *tree_view,
              GtkRBTree   *tree,
              GtkRBNode   *node,
@@ -3051,6 +3515,8 @@
 	    }
 	}
 
+      do_inplace_tips (tree_view, tree, node, x, y);
+
       return;
     }
 
@@ -3109,6 +3575,8 @@
       tree_view->priv->auto_expand_timeout = 
 	gdk_threads_add_timeout (AUTO_EXPAND_TIMEOUT, auto_expand_timeout, tree_view);
     }
+
+  do_inplace_tips (tree_view, tree, node, x, y);
 }
 
 static void
Index: gtk/gtkcellrenderer.c
===================================================================
--- gtk/gtkcellrenderer.c	(revision 18015)
+++ gtk/gtkcellrenderer.c	(working copy)
@@ -102,6 +102,7 @@
 
   class->render = NULL;
   class->get_size = NULL;
+  class->get_content_size = NULL;
 
   /**
    * GtkCellRenderer::editing-canceled:
@@ -462,7 +463,7 @@
 }
 
 /**
- * gtk_cell_renderer_get_size:
+ * gtk_cell_renderer_get_size_helper:
  * @cell: a #GtkCellRenderer
  * @widget: the widget the renderer is rendering to
  * @cell_area: The area a cell will be allocated, or %NULL
@@ -470,6 +471,7 @@
  * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
  * @width: location to return width needed to render a cell, or %NULL
  * @height: location to return height needed to render a cell, or %NULL
+ * @full: true to get content's full size
  *
  * Obtains the width and height needed to render the cell. Used by view widgets
  * to determine the appropriate size for the cell_area passed to
@@ -479,41 +481,127 @@
  * are inclusive of the xpad and ypad properties.
  **/
 void
-gtk_cell_renderer_get_size (GtkCellRenderer *cell,
-			    GtkWidget       *widget,
-			    GdkRectangle    *cell_area,
-			    gint            *x_offset,
-			    gint            *y_offset,
-			    gint            *width,
-			    gint            *height)
+gtk_cell_renderer_get_size_helper (GtkCellRenderer *cell,
+			           GtkWidget       *widget,
+			           GdkRectangle    *cell_area,
+			           gint            *x_offset,
+			           gint            *y_offset,
+			           gint            *width,
+			           gint            *height,
+                                   gboolean         full)
 {
   gint *real_width = width;
   gint *real_height = height;
 
   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
-  g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
-
-  if (width && cell->width != -1)
+  if (full)
     {
-      real_width = NULL;
-      *width = cell->width;
+      g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_content_size != NULL);
+      GTK_CELL_RENDERER_GET_CLASS (cell)->get_content_size (cell,
+                                                            widget,
+                                                            cell_area,
+                                                            x_offset,
+                                                            y_offset,
+                                                            real_width,
+                                                            real_height);
     }
-  if (height && cell->height != -1)
+  else
     {
-      real_height = NULL;
-      *height = cell->height;
+      g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
+      if (width && cell->width != -1)
+        {
+          real_width = NULL;
+          *width = cell->width;
+        }
+      if (height && cell->height != -1)
+        {
+          real_height = NULL;
+          *height = cell->height;
+        }
+
+      GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell,
+                                                    widget,
+                                                    cell_area,
+                                                    x_offset,
+                                                    y_offset,
+                                                    real_width,
+                                                    real_height);
     }
+}
 
-  GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell,
-						widget,
-						cell_area,
-						x_offset,
-						y_offset,
-						real_width,
-						real_height);
+/**
+ * gtk_cell_renderer_get_size:
+ * @cell: a #GtkCellRenderer
+ * @widget: the widget the renderer is rendering to
+ * @cell_area: The area a cell will be allocated, or %NULL
+ * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
+ * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
+ * @width: location to return width needed to render a cell, or %NULL
+ * @height: location to return height needed to render a cell, or %NULL
+ *
+ * Obtains the width and height needed to render the cell. Used by view widgets
+ * to determine the appropriate size for the cell_area passed to
+ * gtk_cell_renderer_render().  If @cell_area is not %NULL, fills in the x and y
+ * offsets (if set) of the cell relative to this location.  Please note that the
+ * values set in @width and @height, as well as those in @x_offset and @y_offset
+ * are inclusive of the xpad and ypad properties.
+ **/
+void
+gtk_cell_renderer_get_size (GtkCellRenderer *cell,
+			    GtkWidget       *widget,
+			    GdkRectangle    *cell_area,
+			    gint            *x_offset,
+			    gint            *y_offset,
+			    gint            *width,
+			    gint            *height)
+{
+    gtk_cell_renderer_get_size_helper(cell,
+                                      widget,
+                                      cell_area,
+                                      x_offset,
+                                      y_offset,
+                                      width,
+                                      height,
+                                      FALSE);
 }
 
 /**
+ * gtk_cell_renderer_get_content_size:
+ * @cell: a #GtkCellRenderer
+ * @widget: the widget the renderer is rendering to
+ * @cell_area: The area a cell will be allocated, or %NULL
+ * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
+ * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
+ * @width: location to return width needed to render a cell, or %NULL
+ * @height: location to return height needed to render a cell, or %NULL
+ *
+ * Obtains the width and height needed to render the cell. Used by view widgets
+ * to determine the appropriate size for the cell_area passed to
+ * gtk_cell_renderer_render().  If @cell_area is not %NULL, fills in the x and y
+ * offsets (if set) of the cell relative to this location.  Please note that the
+ * values set in @width and @height, as well as those in @x_offset and @y_offset
+ * are inclusive of the xpad and ypad properties.
+ **/
+void
+gtk_cell_renderer_get_content_size (GtkCellRenderer *cell,
+			            GtkWidget       *widget,
+			            GdkRectangle    *cell_area,
+			            gint            *x_offset,
+			            gint            *y_offset,
+			            gint            *width,
+			            gint            *height)
+{
+    gtk_cell_renderer_get_size_helper(cell,
+                                      widget,
+                                      cell_area,
+                                      x_offset,
+                                      y_offset,
+                                      width,
+                                      height,
+                                      TRUE);
+}
+
+/**
  * gtk_cell_renderer_render:
  * @cell: a #GtkCellRenderer
  * @window: a #GdkDrawable to draw to
Index: gtk/gtkcellrenderer.h
===================================================================
--- gtk/gtkcellrenderer.h	(revision 18015)
+++ gtk/gtkcellrenderer.h	(working copy)
@@ -116,7 +116,13 @@
 			     const gchar     *path);
 
   /* Padding for future expansion */
-  void (*_gtk_reserved1) (void);
+  void (* get_content_size) (GtkCellRenderer *cell,
+                             GtkWidget       *widget,
+                             GdkRectangle    *cell_area,
+                             gint            *x_offset,
+                             gint            *y_offset,
+                             gint            *width,
+                             gint            *height);
   void (*_gtk_reserved2) (void);
 };
 
@@ -129,6 +135,13 @@
 						   gint                 *y_offset,
 						   gint                 *width,
 						   gint                 *height);
+void             gtk_cell_renderer_get_content_size (GtkCellRenderer      *cell,
+						     GtkWidget            *widget,
+						     GdkRectangle         *cell_area,
+						     gint                 *x_offset,
+						     gint                 *y_offset,
+						     gint                 *width,
+						     gint                 *height);
 void             gtk_cell_renderer_render         (GtkCellRenderer      *cell,
 						   GdkWindow            *window,
 						   GtkWidget            *widget,
Index: gtk/gtktreeprivate.h
===================================================================
--- gtk/gtktreeprivate.h	(revision 18015)
+++ gtk/gtktreeprivate.h	(working copy)
@@ -264,6 +264,8 @@
 
   gboolean tree_lines_enabled;
   GdkGC *tree_line_gc;
+
+  GtkWidget *inplace_tips;
 };
 
 #ifdef __GNUC__
Index: gtk/gtkcellrendererprogress.c
===================================================================
--- gtk/gtkcellrendererprogress.c	(revision 18015)
+++ gtk/gtkcellrendererprogress.c	(working copy)
@@ -105,6 +105,7 @@
   object_class->set_property = gtk_cell_renderer_progress_set_property;
   
   cell_class->get_size = gtk_cell_renderer_progress_get_size;
+  cell_class->get_content_size = gtk_cell_renderer_progress_get_size;
   cell_class->render = gtk_cell_renderer_progress_render;
   
   /**
Index: gtk/gtkcellrendereraccel.c
===================================================================
--- gtk/gtkcellrendereraccel.c	(revision 18015)
+++ gtk/gtkcellrendereraccel.c	(working copy)
@@ -88,8 +88,9 @@
   object_class->set_property = gtk_cell_renderer_accel_set_property;
   object_class->get_property = gtk_cell_renderer_accel_get_property;
 
-  cell_renderer_class->get_size      = gtk_cell_renderer_accel_get_size;
-  cell_renderer_class->start_editing = gtk_cell_renderer_accel_start_editing;
+  cell_renderer_class->get_size         = gtk_cell_renderer_accel_get_size;
+  cell_renderer_class->get_content_size = gtk_cell_renderer_accel_get_size;
+  cell_renderer_class->start_editing    = gtk_cell_renderer_accel_start_editing;
 
   /**
    * GtkCellRendererAccel:accel-key:
Index: gtk/gtkcellrenderertext.c
===================================================================
--- gtk/gtkcellrenderertext.c	(revision 18015)
+++ gtk/gtkcellrenderertext.c	(working copy)
@@ -45,6 +45,13 @@
 					       gint                     *y_offset,
 					       gint                     *width,
 					       gint                     *height);
+static void gtk_cell_renderer_text_get_content_size   (GtkCellRenderer          *cell,
+					               GtkWidget                *widget,
+					               GdkRectangle             *cell_area,
+					               gint                     *x_offset,
+					               gint                     *y_offset,
+					               gint                     *width,
+					               gint                     *height);
 static void gtk_cell_renderer_text_render     (GtkCellRenderer          *cell,
 					       GdkWindow                *window,
 					       GtkWidget                *widget,
@@ -184,6 +191,7 @@
   object_class->set_property = gtk_cell_renderer_text_set_property;
 
   cell_class->get_size = gtk_cell_renderer_text_get_size;
+  cell_class->get_content_size = gtk_cell_renderer_text_get_content_size;
   cell_class->render = gtk_cell_renderer_text_render;
   cell_class->start_editing = gtk_cell_renderer_text_start_editing;
 
@@ -1482,7 +1490,8 @@
 	  gint            *x_offset,
 	  gint            *y_offset,
 	  gint            *width,
-	  gint            *height)
+	  gint            *height,
+          gboolean         sizing_content)
 {
   GtkCellRendererText *celltext = (GtkCellRendererText *) cell;
   PangoRectangle rect;
@@ -1543,7 +1552,7 @@
   /* The minimum size for ellipsized labels is ~ 3 chars */
   if (width)
     {
-      if (priv->ellipsize || priv->width_chars > 0)
+      if ((priv->ellipsize || priv->width_chars > 0) && !sizing_content)
 	{
 	  PangoContext *context;
 	  PangoFontMetrics *metrics;
@@ -1601,10 +1610,23 @@
 				 gint            *height)
 {
   get_size (cell, widget, cell_area, NULL,
-	    x_offset, y_offset, width, height);
+	    x_offset, y_offset, width, height, FALSE);
 }
 
 static void
+gtk_cell_renderer_text_get_content_size (GtkCellRenderer *cell,
+				         GtkWidget       *widget,
+				         GdkRectangle    *cell_area,
+				         gint            *x_offset,
+				         gint            *y_offset,
+				         gint            *width,
+				         gint            *height)
+{
+  get_size (cell, widget, cell_area, NULL,
+	    x_offset, y_offset, width, height, TRUE);
+}
+
+static void
 gtk_cell_renderer_text_render (GtkCellRenderer      *cell,
 			       GdkDrawable          *window,
 			       GtkWidget            *widget,
@@ -1624,7 +1646,7 @@
   priv = GTK_CELL_RENDERER_TEXT_GET_PRIVATE (cell);
 
   layout = get_layout (celltext, widget, TRUE, flags);
-  get_size (cell, widget, cell_area, layout, &x_offset, &y_offset, NULL, NULL);
+  get_size (cell, widget, cell_area, layout, &x_offset, &y_offset, NULL, NULL, FALSE);
 
   if (!cell->sensitive) 
     {
