]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreeview.c
gtk: remove "gboolean homogeneous" from gtk_box_new()
[~andy/gtk] / gtk / gtktreeview.c
index 6bf2dc91290b0c6a0e7383442be1ce6c580320d5..7e50804e5c020c771a7b555b1988fcceaa78d3c6 100644 (file)
@@ -19,6 +19,7 @@
 
 
 #include "config.h"
+#include <math.h>
 #include <string.h>
 #include <gdk/gdkkeysyms.h>
 
@@ -43,8 +44,9 @@
 #include "gtkframe.h"
 #include "gtktreemodelsort.h"
 #include "gtktooltip.h"
-#include "gtksizerequest.h"
+#include "gtkscrollable.h"
 #include "gtkprivate.h"
+#include "gtkwidgetprivate.h"
 
 #define GTK_TREE_VIEW_PRIORITY_VALIDATE (GDK_PRIORITY_REDRAW + 5)
 #define GTK_TREE_VIEW_PRIORITY_SCROLL_SYNC (GTK_TREE_VIEW_PRIORITY_VALIDATE + 2)
@@ -129,6 +131,8 @@ enum {
   PROP_MODEL,
   PROP_HADJUSTMENT,
   PROP_VADJUSTMENT,
+  PROP_HSCROLL_POLICY,
+  PROP_VSCROLL_POLICY,
   PROP_HEADERS_VISIBLE,
   PROP_HEADERS_CLICKABLE,
   PROP_EXPANDER_COLUMN,
@@ -158,19 +162,23 @@ static void     gtk_tree_view_get_property         (GObject         *object,
                                                    GValue          *value,
                                                    GParamSpec      *pspec);
 
-/* gtkobject signals */
-static void     gtk_tree_view_destroy              (GtkObject        *object);
-
 /* gtkwidget signals */
+static void     gtk_tree_view_destroy              (GtkWidget        *widget);
 static void     gtk_tree_view_realize              (GtkWidget        *widget);
 static void     gtk_tree_view_unrealize            (GtkWidget        *widget);
 static void     gtk_tree_view_map                  (GtkWidget        *widget);
+static void     gtk_tree_view_get_preferred_width  (GtkWidget        *widget,
+                                                   gint             *minimum,
+                                                   gint             *natural);
+static void     gtk_tree_view_get_preferred_height (GtkWidget        *widget,
+                                                   gint             *minimum,
+                                                   gint             *natural);
 static void     gtk_tree_view_size_request         (GtkWidget        *widget,
                                                    GtkRequisition   *requisition);
 static void     gtk_tree_view_size_allocate        (GtkWidget        *widget,
                                                    GtkAllocation    *allocation);
-static gboolean gtk_tree_view_expose               (GtkWidget        *widget,
-                                                   GdkEventExpose   *event);
+static gboolean gtk_tree_view_draw                 (GtkWidget        *widget,
+                                                    cairo_t          *cr);
 static gboolean gtk_tree_view_key_press            (GtkWidget        *widget,
                                                    GdkEventKey      *event);
 static gboolean gtk_tree_view_key_release          (GtkWidget        *widget,
@@ -250,9 +258,10 @@ static void     gtk_tree_view_drag_data_received (GtkWidget        *widget,
                                                   guint             time);
 
 /* tree_model signals */
-static void gtk_tree_view_set_adjustments                 (GtkTreeView     *tree_view,
-                                                          GtkAdjustment   *hadj,
-                                                          GtkAdjustment   *vadj);
+static void     gtk_tree_view_set_hadjustment             (GtkTreeView     *tree_view,
+                                                           GtkAdjustment   *adjustment);
+static void     gtk_tree_view_set_vadjustment             (GtkTreeView     *tree_view,
+                                                           GtkAdjustment   *adjustment);
 static gboolean gtk_tree_view_real_move_cursor            (GtkTreeView     *tree_view,
                                                           GtkMovementStep  step,
                                                           gint             count);
@@ -324,9 +333,9 @@ static void     gtk_tree_view_queue_draw_path                (GtkTreeView
                                                              const GdkRectangle *clip_rect);
 static void     gtk_tree_view_queue_draw_arrow               (GtkTreeView        *tree_view,
                                                              GtkRBTree          *tree,
-                                                             GtkRBNode          *node,
-                                                             const GdkRectangle *clip_rect);
+                                                             GtkRBNode          *node);
 static void     gtk_tree_view_draw_arrow                     (GtkTreeView        *tree_view,
+                                                              cairo_t            *cr,
                                                              GtkRBTree          *tree,
                                                              GtkRBNode          *node,
                                                              gint                x,
@@ -489,13 +498,13 @@ static guint tree_view_signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE_WITH_CODE (GtkTreeView, gtk_tree_view, GTK_TYPE_CONTAINER,
                         G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
-                                               gtk_tree_view_buildable_init))
+                                               gtk_tree_view_buildable_init)
+                        G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
 
 static void
 gtk_tree_view_class_init (GtkTreeViewClass *class)
 {
   GObjectClass *o_class;
-  GtkObjectClass *object_class;
   GtkWidgetClass *widget_class;
   GtkContainerClass *container_class;
   GtkBindingSet *binding_set;
@@ -503,7 +512,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   binding_set = gtk_binding_set_by_class (class);
 
   o_class = (GObjectClass *) class;
-  object_class = (GtkObjectClass *) class;
   widget_class = (GtkWidgetClass *) class;
   container_class = (GtkContainerClass *) class;
 
@@ -512,21 +520,20 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   o_class->get_property = gtk_tree_view_get_property;
   o_class->finalize = gtk_tree_view_finalize;
 
-  /* GtkObject signals */
-  object_class->destroy = gtk_tree_view_destroy;
-
   /* GtkWidget signals */
+  widget_class->destroy = gtk_tree_view_destroy;
   widget_class->map = gtk_tree_view_map;
   widget_class->realize = gtk_tree_view_realize;
   widget_class->unrealize = gtk_tree_view_unrealize;
-  widget_class->size_request = gtk_tree_view_size_request;
+  widget_class->get_preferred_width = gtk_tree_view_get_preferred_width;
+  widget_class->get_preferred_height = gtk_tree_view_get_preferred_height;
   widget_class->size_allocate = gtk_tree_view_size_allocate;
   widget_class->button_press_event = gtk_tree_view_button_press;
   widget_class->button_release_event = gtk_tree_view_button_release;
   widget_class->grab_broken_event = gtk_tree_view_grab_broken;
   /*widget_class->configure_event = gtk_tree_view_configure;*/
   widget_class->motion_notify_event = gtk_tree_view_motion;
-  widget_class->expose_event = gtk_tree_view_expose;
+  widget_class->draw = gtk_tree_view_draw;
   widget_class->key_press_event = gtk_tree_view_key_press;
   widget_class->key_release_event = gtk_tree_view_key_release;
   widget_class->enter_notify_event = gtk_tree_view_enter_notify;
@@ -551,7 +558,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   container_class->forall = gtk_tree_view_forall;
   container_class->set_focus_child = gtk_tree_view_set_focus_child;
 
-  class->set_scroll_adjustments = gtk_tree_view_set_adjustments;
   class->move_cursor = gtk_tree_view_real_move_cursor;
   class->select_all = gtk_tree_view_real_select_all;
   class->unselect_all = gtk_tree_view_real_unselect_all;
@@ -571,21 +577,10 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                                                        GTK_TYPE_TREE_MODEL,
                                                        GTK_PARAM_READWRITE));
 
-  g_object_class_install_property (o_class,
-                                   PROP_HADJUSTMENT,
-                                   g_param_spec_object ("hadjustment",
-                                                       P_("Horizontal Adjustment"),
-                                                        P_("Horizontal Adjustment for the widget"),
-                                                        GTK_TYPE_ADJUSTMENT,
-                                                        GTK_PARAM_READWRITE));
-
-  g_object_class_install_property (o_class,
-                                   PROP_VADJUSTMENT,
-                                   g_param_spec_object ("vadjustment",
-                                                       P_("Vertical Adjustment"),
-                                                        P_("Vertical Adjustment for the widget"),
-                                                        GTK_TYPE_ADJUSTMENT,
-                                                        GTK_PARAM_READWRITE));
+  g_object_class_override_property (o_class, PROP_HADJUSTMENT,    "hadjustment");
+  g_object_class_override_property (o_class, PROP_VADJUSTMENT,    "vadjustment");
+  g_object_class_override_property (o_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+  g_object_class_override_property (o_class, PROP_VSCROLL_POLICY, "vscroll-policy");
 
   g_object_class_install_property (o_class,
                                    PROP_HEADERS_VISIBLE,
@@ -861,26 +856,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                                                                GTK_PARAM_READABLE));
 
   /* Signals */
-  /**
-   * GtkTreeView::set-scroll-adjustments
-   * @horizontal: the horizontal #GtkAdjustment
-   * @vertical: the vertical #GtkAdjustment
-   *
-   * Set the scroll adjustments for the tree view. Usually scrolled containers
-   * like #GtkScrolledWindow will emit this signal to connect two instances
-   * of #GtkScrollbar to the scroll directions of the #GtkTreeView.
-   */
-  widget_class->set_scroll_adjustments_signal =
-    g_signal_new (I_("set-scroll-adjustments"),
-                 G_TYPE_FROM_CLASS (o_class),
-                 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-                 G_STRUCT_OFFSET (GtkTreeViewClass, set_scroll_adjustments),
-                 NULL, NULL,
-                 _gtk_marshal_VOID__OBJECT_OBJECT,
-                 G_TYPE_NONE, 2,
-                 GTK_TYPE_ADJUSTMENT,
-                 GTK_TYPE_ADJUSTMENT);
-
   /**
    * GtkTreeView::row-activated:
    * @tree_view: the object on which the signal is emitted
@@ -1021,7 +996,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[MOVE_CURSOR] =
     g_signal_new (I_("move-cursor"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, move_cursor),
                  NULL, NULL,
@@ -1032,7 +1007,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[SELECT_ALL] =
     g_signal_new (I_("select-all"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, select_all),
                  NULL, NULL,
@@ -1041,7 +1016,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[UNSELECT_ALL] =
     g_signal_new (I_("unselect-all"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, unselect_all),
                  NULL, NULL,
@@ -1050,7 +1025,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[SELECT_CURSOR_ROW] =
     g_signal_new (I_("select-cursor-row"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, select_cursor_row),
                  NULL, NULL,
@@ -1060,7 +1035,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[TOGGLE_CURSOR_ROW] =
     g_signal_new (I_("toggle-cursor-row"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, toggle_cursor_row),
                  NULL, NULL,
@@ -1069,7 +1044,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[EXPAND_COLLAPSE_CURSOR_ROW] =
     g_signal_new (I_("expand-collapse-cursor-row"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, expand_collapse_cursor_row),
                  NULL, NULL,
@@ -1081,7 +1056,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[SELECT_CURSOR_PARENT] =
     g_signal_new (I_("select-cursor-parent"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, select_cursor_parent),
                  NULL, NULL,
@@ -1090,7 +1065,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   tree_view_signals[START_INTERACTIVE_SEARCH] =
     g_signal_new (I_("start-interactive-search"),
-                 G_TYPE_FROM_CLASS (object_class),
+                 G_TYPE_FROM_CLASS (o_class),
                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                  G_STRUCT_OFFSET (GtkTreeViewClass, start_interactive_search),
                  NULL, NULL,
@@ -1342,7 +1317,6 @@ gtk_tree_view_init (GtkTreeView *tree_view)
   tree_view->priv->fixed_height = -1;
   tree_view->priv->fixed_height_mode = FALSE;
   tree_view->priv->fixed_height_check = 0;
-  gtk_tree_view_set_adjustments (tree_view, NULL, NULL);
   tree_view->priv->selection = _gtk_tree_selection_new_with_tree_view (tree_view);
   tree_view->priv->enable_search = TRUE;
   tree_view->priv->search_column = -1;
@@ -1372,6 +1346,9 @@ gtk_tree_view_init (GtkTreeView *tree_view)
 
   tree_view->priv->event_last_x = -10000;
   tree_view->priv->event_last_y = -10000;
+
+  gtk_tree_view_set_vadjustment (tree_view, NULL);
+  gtk_tree_view_set_hadjustment (tree_view, NULL);
 }
 
 \f
@@ -1400,6 +1377,14 @@ gtk_tree_view_set_property (GObject         *object,
     case PROP_VADJUSTMENT:
       gtk_tree_view_set_vadjustment (tree_view, g_value_get_object (value));
       break;
+    case PROP_HSCROLL_POLICY:
+      tree_view->priv->hscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+      break;
+    case PROP_VSCROLL_POLICY:
+      tree_view->priv->vscroll_policy = g_value_get_enum (value);
+      gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+      break;
     case PROP_HEADERS_VISIBLE:
       gtk_tree_view_set_headers_visible (tree_view, g_value_get_boolean (value));
       break;
@@ -1475,6 +1460,12 @@ gtk_tree_view_get_property (GObject    *object,
     case PROP_VADJUSTMENT:
       g_value_set_object (value, tree_view->priv->vadjustment);
       break;
+    case PROP_HSCROLL_POLICY:
+      g_value_set_enum (value, tree_view->priv->hscroll_policy);
+      break;
+    case PROP_VSCROLL_POLICY:
+      g_value_set_enum (value, tree_view->priv->vscroll_policy);
+      break;
     case PROP_HEADERS_VISIBLE:
       g_value_set_boolean (value, gtk_tree_view_get_headers_visible (tree_view));
       break;
@@ -1568,7 +1559,7 @@ gtk_tree_view_buildable_get_internal_child (GtkBuildable      *buildable,
                                                       childname);
 }
 
-/* GtkObject Methods
+/* GtkWidget Methods
  */
 
 static void
@@ -1586,9 +1577,9 @@ gtk_tree_view_free_rbtree (GtkTreeView *tree_view)
 }
 
 static void
-gtk_tree_view_destroy (GtkObject *object)
+gtk_tree_view_destroy (GtkWidget *widget)
 {
-  GtkTreeView *tree_view = GTK_TREE_VIEW (object);
+  GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
   GList *list;
 
   gtk_tree_view_stop_editing (tree_view, TRUE);
@@ -1702,14 +1693,9 @@ gtk_tree_view_destroy (GtkObject *object)
       tree_view->priv->vadjustment = NULL;
     }
 
-  GTK_OBJECT_CLASS (gtk_tree_view_parent_class)->destroy (object);
+  GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->destroy (widget);
 }
 
-\f
-
-/* GtkWidget Methods
- */
-
 /* GtkWidget::map helper */
 static void
 gtk_tree_view_map_buttons (GtkTreeView *tree_view)
@@ -1796,10 +1782,9 @@ gtk_tree_view_realize (GtkWidget *widget)
   attributes.height = allocation.height;
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
   attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
   window = gdk_window_new (gtk_widget_get_parent_window (widget),
                            &attributes, attributes_mask);
@@ -1972,8 +1957,7 @@ gtk_tree_view_size_request_columns (GtkTreeView *tree_view)
 
           column = list->data;
 
-          gtk_size_request_get_size (GTK_SIZE_REQUEST (column->button),
-                                     &requisition, NULL);
+          gtk_widget_get_preferred_size (column->button, &requisition, NULL);
          column->button_request = requisition.width;
           tree_view->priv->header_height = MAX (tree_view->priv->header_height, requisition.height);
         }
@@ -2057,18 +2041,30 @@ gtk_tree_view_size_request (GtkWidget      *widget,
   requisition->height = tree_view->priv->height + TREE_VIEW_HEADER_HEIGHT (tree_view);
 
   tmp_list = tree_view->priv->children;
+}
 
-  while (tmp_list)
-    {
-      GtkTreeViewChild *child = tmp_list->data;
-      GtkRequisition child_requisition;
+static void
+gtk_tree_view_get_preferred_width (GtkWidget *widget,
+                                  gint      *minimum,
+                                  gint      *natural)
+{
+  GtkRequisition requisition;
 
-      tmp_list = tmp_list->next;
+  gtk_tree_view_size_request (widget, &requisition);
 
-      if (gtk_widget_get_visible (child->widget))
-        gtk_size_request_get_size (GTK_SIZE_REQUEST (child->widget),
-                                   &child_requisition, NULL);
-    }
+  *minimum = *natural = requisition.width;
+}
+
+static void
+gtk_tree_view_get_preferred_height (GtkWidget *widget,
+                                   gint      *minimum,
+                                   gint      *natural)
+{
+  GtkRequisition requisition;
+
+  gtk_tree_view_size_request (widget, &requisition);
+
+  *minimum = *natural = requisition.height;
 }
 
 static int
@@ -2287,11 +2283,11 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget,
       if (column == tree_view->priv->drag_column)
        {
          GtkAllocation drag_allocation;
-         gdk_drawable_get_size (tree_view->priv->drag_window,
-                                &(drag_allocation.width),
-                                &(drag_allocation.height));
+
          drag_allocation.x = 0;
          drag_allocation.y = 0;
+          drag_allocation.width = gdk_window_get_width (tree_view->priv->drag_window);
+          drag_allocation.height = gdk_window_get_height (tree_view->priv->drag_window);
          gtk_widget_size_allocate (tree_view->priv->drag_column->button,
                                    &drag_allocation);
          width += drag_allocation.width;
@@ -2398,11 +2394,18 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
    */
   gtk_tree_view_size_allocate_columns (widget, &width_changed);
 
-  tree_view->priv->hadjustment->page_size = allocation->width;
-  tree_view->priv->hadjustment->page_increment = allocation->width * 0.9;
-  tree_view->priv->hadjustment->step_increment = allocation->width * 0.1;
-  tree_view->priv->hadjustment->lower = 0;
-  tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->page_size, tree_view->priv->width);
+  g_object_freeze_notify (G_OBJECT (tree_view->priv->hadjustment));
+  gtk_adjustment_set_page_size (tree_view->priv->hadjustment,
+                                allocation->width);
+  gtk_adjustment_set_page_increment (tree_view->priv->hadjustment,
+                                     allocation->width * 0.9);
+  gtk_adjustment_set_step_increment (tree_view->priv->hadjustment,
+                                     allocation->width * 0.1);
+  gtk_adjustment_set_lower (tree_view->priv->hadjustment, 0);
+  gtk_adjustment_set_upper (tree_view->priv->hadjustment,
+                            MAX (tree_view->priv->hadjustment->page_size,
+                                 tree_view->priv->width));
+  g_object_thaw_notify (G_OBJECT (tree_view->priv->hadjustment));
 
   if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)   
     {
@@ -2410,35 +2413,49 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
         {
          if (tree_view->priv->init_hadjust_value)
            {
-             tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
+             gtk_adjustment_set_value (tree_view->priv->hadjustment,
+                                        MAX (tree_view->priv->width -
+                                             allocation->width, 0));
              tree_view->priv->init_hadjust_value = FALSE;
            }
          else if (allocation->width != old_width)
            {
-             tree_view->priv->hadjustment->value = CLAMP (tree_view->priv->hadjustment->value - allocation->width + old_width, 0, tree_view->priv->width - allocation->width);
+             gtk_adjustment_set_value (tree_view->priv->hadjustment,
+                                        CLAMP (tree_view->priv->hadjustment->value - allocation->width + old_width,
+                                               0,
+                                               tree_view->priv->width - allocation->width));
            }
          else
-           tree_view->priv->hadjustment->value = CLAMP (tree_view->priv->width - (tree_view->priv->prev_width - tree_view->priv->hadjustment->value), 0, tree_view->priv->width - allocation->width);
+            gtk_adjustment_set_value (tree_view->priv->hadjustment,
+                                      CLAMP (tree_view->priv->width - (tree_view->priv->prev_width - tree_view->priv->hadjustment->value),
+                                             0,
+                                             tree_view->priv->width - allocation->width));
        }
       else
         {
-         tree_view->priv->hadjustment->value = 0;
+          gtk_adjustment_set_value (tree_view->priv->hadjustment, 0);
          tree_view->priv->init_hadjust_value = TRUE;
        }
     }
   else
     if (tree_view->priv->hadjustment->value + allocation->width > tree_view->priv->width)
-      tree_view->priv->hadjustment->value = MAX (tree_view->priv->width - allocation->width, 0);
-
-  gtk_adjustment_changed (tree_view->priv->hadjustment);
-
-  tree_view->priv->vadjustment->page_size = allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view);
-  tree_view->priv->vadjustment->step_increment = tree_view->priv->vadjustment->page_size * 0.1;
-  tree_view->priv->vadjustment->page_increment = tree_view->priv->vadjustment->page_size * 0.9;
-  tree_view->priv->vadjustment->lower = 0;
-  tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->page_size, tree_view->priv->height);
-
-  gtk_adjustment_changed (tree_view->priv->vadjustment);
+      gtk_adjustment_set_value (tree_view->priv->hadjustment,
+                                MAX (tree_view->priv->width -
+                                     allocation->width, 0));
+
+  g_object_freeze_notify (G_OBJECT (tree_view->priv->vadjustment));
+  gtk_adjustment_set_page_size (tree_view->priv->vadjustment,
+                                allocation->height -
+                                TREE_VIEW_HEADER_HEIGHT (tree_view));
+  gtk_adjustment_set_step_increment (tree_view->priv->vadjustment,
+                                     tree_view->priv->vadjustment->page_size * 0.1);
+  gtk_adjustment_set_page_increment (tree_view->priv->vadjustment,
+                                     tree_view->priv->vadjustment->page_size * 0.9);
+  gtk_adjustment_set_lower (tree_view->priv->vadjustment, 0);
+  gtk_adjustment_set_upper (tree_view->priv->vadjustment,
+                            MAX (tree_view->priv->vadjustment->page_size,
+                                 tree_view->priv->height));
+  g_object_thaw_notify (G_OBJECT (tree_view->priv->vadjustment));
 
   /* now the adjustments and window sizes are in sync, we can sync toprow/dy again */
   if (tree_view->priv->height <= tree_view->priv->vadjustment->page_size)
@@ -2613,11 +2630,9 @@ gtk_tree_view_button_press (GtkWidget      *widget,
              gtk_grab_add (widget);
              tree_view->priv->button_pressed_node = tree_view->priv->prelight_node;
              tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree;
-             gtk_tree_view_draw_arrow (GTK_TREE_VIEW (widget),
-                                       tree_view->priv->prelight_tree,
-                                       tree_view->priv->prelight_node,
-                                       event->x,
-                                       event->y);
+             gtk_tree_view_queue_draw_arrow (GTK_TREE_VIEW (widget),
+                                              tree_view->priv->prelight_tree,
+                                              tree_view->priv->prelight_node);
            }
 
          grab_focus_and_unset_draw_keyfocus (tree_view);
@@ -3037,7 +3052,7 @@ gtk_tree_view_button_release_column_resize (GtkWidget      *widget,
 
   GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_IN_COLUMN_RESIZE);
   gtk_grab_remove (widget);
-  gdk_display_pointer_ungrab (gdk_drawable_get_display (event->window),
+  gdk_display_pointer_ungrab (gdk_window_get_display (event->window),
                              event->time);
   return TRUE;
 }
@@ -3224,7 +3239,7 @@ do_prelight (GtkTreeView *tree_view,
                GTK_TREE_VIEW_UNSET_FLAG (tree_view,
                                          GTK_TREE_VIEW_ARROW_PRELIT);
 
-             gtk_tree_view_draw_arrow (tree_view, tree, node, x, y);
+             gtk_tree_view_queue_draw_arrow (tree_view, tree, node);
            }
        }
 
@@ -3243,11 +3258,9 @@ do_prelight (GtkTreeView *tree_view,
        {
          GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_ARROW_PRELIT);
          
-         gtk_tree_view_draw_arrow (tree_view,
-                                   tree_view->priv->prelight_tree,
-                                   tree_view->priv->prelight_node,
-                                   x,
-                                   y);
+         gtk_tree_view_queue_draw_arrow (tree_view,
+                                          tree_view->priv->prelight_tree,
+                                          tree_view->priv->prelight_node);
        }
 
       _gtk_tree_view_queue_draw_node (tree_view,
@@ -3274,7 +3287,7 @@ do_prelight (GtkTreeView *tree_view,
     {
       GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_ARROW_PRELIT);
 
-      gtk_tree_view_draw_arrow (tree_view, tree, node, x, y);
+      gtk_tree_view_queue_draw_arrow (tree_view, tree, node);
     }
 
   GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_PRELIT);
@@ -3459,9 +3472,8 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
          width = attributes.width = drag_allocation.width;
          height = attributes.height = drag_allocation.height;
          attributes.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
-         attributes.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view));
          attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
-         attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+         attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
          tree_view->priv->drag_highlight_window = gdk_window_new (tree_view->priv->header_window, &attributes, attributes_mask);
          gdk_window_set_user_data (tree_view->priv->drag_highlight_window, GTK_WIDGET (tree_view));
 
@@ -3518,9 +3530,8 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
          attributes.window_type = GDK_WINDOW_TEMP;
          attributes.wclass = GDK_INPUT_OUTPUT;
          attributes.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
-         attributes.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view));
          attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
-         attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+         attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
           attributes.x = x;
           attributes.y = y;
          attributes.width = width;
@@ -3597,9 +3608,8 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
          attributes.window_type = GDK_WINDOW_TEMP;
          attributes.wclass = GDK_INPUT_OUTPUT;
          attributes.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
-         attributes.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view));
          attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
-         attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+         attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
           attributes.x = x;
           attributes.y = y;
          attributes.width = width;
@@ -4094,47 +4104,34 @@ gtk_tree_view_update_rubber_band (GtkTreeView *tree_view)
 
 static void
 gtk_tree_view_paint_rubber_band (GtkTreeView  *tree_view,
-                               GdkRectangle *area)
+                                 cairo_t      *cr)
 {
-  GtkStyle *style;
-  cairo_t *cr;
   GdkRectangle rect;
-  GdkRectangle rubber_rect;
+  GtkStyle *style;
 
-  rubber_rect.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x);
-  rubber_rect.y = MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y) - tree_view->priv->dy;
-  rubber_rect.width = ABS (tree_view->priv->press_start_x - tree_view->priv->rubber_band_x) + 1;
-  rubber_rect.height = ABS (tree_view->priv->press_start_y - tree_view->priv->rubber_band_y) + 1;
+  cairo_save (cr);
 
-  if (!gdk_rectangle_intersect (&rubber_rect, area, &rect))
-    return;
+  rect.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x);
+  rect.y = MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y) - tree_view->priv->dy;
+  rect.width = ABS (tree_view->priv->press_start_x - tree_view->priv->rubber_band_x) + 1;
+  rect.height = ABS (tree_view->priv->press_start_y - tree_view->priv->rubber_band_y) + 1;
 
-  cr = gdk_cairo_create (tree_view->priv->bin_window);
   cairo_set_line_width (cr, 1.0);
 
   style = gtk_widget_get_style (GTK_WIDGET (tree_view));
 
-  cairo_set_source_rgba (cr,
-                         style->fg[GTK_STATE_NORMAL].red / 65535.,
-                         style->fg[GTK_STATE_NORMAL].green / 65535.,
-                         style->fg[GTK_STATE_NORMAL].blue / 65535.,
-                        .25);
+  gdk_cairo_set_source_color (cr, &style->fg[GTK_STATE_NORMAL]);
 
   gdk_cairo_rectangle (cr, &rect);
   cairo_clip (cr);
-  cairo_paint (cr);
-
-  cairo_set_source_rgb (cr,
-                        style->fg[GTK_STATE_NORMAL].red / 65535.,
-                        style->fg[GTK_STATE_NORMAL].green / 65535.,
-                        style->fg[GTK_STATE_NORMAL].blue / 65535.);
+  cairo_paint_with_alpha (cr, 0.25);
 
   cairo_rectangle (cr,
-                  rubber_rect.x + 0.5, rubber_rect.y + 0.5,
-                  rubber_rect.width - 1, rubber_rect.height - 1);
+                  rect.x + 0.5, rect.y + 0.5,
+                  rect.width - 1, rect.height - 1);
   cairo_stroke (cr);
 
-  cairo_destroy (cr);
+  cairo_restore (cr);
 }
 
 static gboolean
@@ -4225,7 +4222,8 @@ invalidate_empty_focus (GtkTreeView *tree_view)
 
   area.x = 0;
   area.y = 0;
-  gdk_drawable_get_size (tree_view->priv->bin_window, &area.width, &area.height);
+  area.width = gdk_window_get_width (tree_view->priv->bin_window);
+  area.height = gdk_window_get_height (tree_view->priv->bin_window);
   gdk_window_invalidate_rect (tree_view->priv->bin_window, &area, FALSE);
 }
 
@@ -4233,7 +4231,7 @@ invalidate_empty_focus (GtkTreeView *tree_view)
  * is empty.
  */
 static void
-draw_empty_focus (GtkTreeView *tree_view, GdkRectangle *clip_area)
+draw_empty_focus (GtkTreeView *tree_view, cairo_t *cr)
 {
   GtkWidget *widget = GTK_WIDGET (tree_view);
   gint w, h;
@@ -4241,16 +4239,13 @@ draw_empty_focus (GtkTreeView *tree_view, GdkRectangle *clip_area)
   if (!gtk_widget_has_focus (widget))
     return;
 
-  gdk_drawable_get_size (tree_view->priv->bin_window, &w, &h);
-
-  w -= 2;
-  h -= 2;
+  w = gdk_window_get_width (tree_view->priv->bin_window) - 2;
+  h = gdk_window_get_height (tree_view->priv->bin_window) - 2;
 
   if (w > 0 && h > 0)
     gtk_paint_focus (gtk_widget_get_style (widget),
-                    tree_view->priv->bin_window,
+                     cr,
                     gtk_widget_get_state (widget),
-                    clip_area,
                     widget,
                     NULL,
                     1, 1, w, h);
@@ -4264,16 +4259,14 @@ typedef enum {
 
 static void
 gtk_tree_view_draw_line (GtkTreeView         *tree_view,
-                         GdkWindow           *window,
+                         cairo_t             *cr,
                          GtkTreeViewLineType  type,
                          int                  x1,
                          int                  y1,
                          int                  x2,
                          int                  y2)
 {
-  cairo_t *cr;
-
-  cr = gdk_cairo_create (window);
+  cairo_save (cr);
 
   switch (type)
     {
@@ -4307,12 +4300,12 @@ gtk_tree_view_draw_line (GtkTreeView         *tree_view,
   cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
   cairo_stroke (cr);
 
-  cairo_destroy (cr);
+  cairo_restore (cr);
 }
                          
 static void
 gtk_tree_view_draw_grid_lines (GtkTreeView    *tree_view,
-                              GdkEventExpose *event,
+                              cairo_t        *cr,
                               gint            n_visible_columns)
 {
   GList *list = tree_view->priv->columns;
@@ -4337,7 +4330,7 @@ gtk_tree_view_draw_grid_lines (GtkTreeView    *tree_view,
 
       current_x += column->width;
 
-      gtk_tree_view_draw_line (tree_view, event->window,
+      gtk_tree_view_draw_line (tree_view, cr,
                                GTK_TREE_VIEW_GRID_LINE,
                                current_x - 1, 0,
                                current_x - 1, tree_view->priv->height);
@@ -4351,8 +4344,8 @@ gtk_tree_view_draw_grid_lines (GtkTreeView    *tree_view,
  * FIXME: It's not...
  */
 static gboolean
-gtk_tree_view_bin_expose (GtkWidget      *widget,
-                         GdkEventExpose *event)
+gtk_tree_view_bin_draw (GtkWidget      *widget,
+                       cairo_t        *cr)
 {
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
   GtkTreePath *path;
@@ -4371,6 +4364,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   gint depth;
   GdkRectangle background_area;
   GdkRectangle cell_area;
+  GdkRectangle clip;
   guint flags;
   gint highlight_x;
   gint expander_cell_width;
@@ -4402,33 +4396,31 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
 
   if (tree_view->priv->tree == NULL)
     {
-      draw_empty_focus (tree_view, &event->area);
+      draw_empty_focus (tree_view, cr);
       return TRUE;
     }
 
-  /* clip event->area to the visible area */
-  if (event->area.height < 0)
-    return TRUE;
-
-  validate_visible_area (tree_view);
-
   style = gtk_widget_get_style (widget);
 
-  new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, event->area.y);
+  bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
+  bin_window_height = gdk_window_get_height (tree_view->priv->bin_window);
+  cairo_rectangle (cr, 0, 0, bin_window_width, bin_window_height);
+  cairo_clip (cr);
+  if (!gdk_cairo_get_clip_rectangle (cr, &clip))
+    return TRUE;
+
+  new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, clip.y);
 
   if (new_y < 0)
     new_y = 0;
   y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node);
-  gdk_drawable_get_size (tree_view->priv->bin_window,
-                         &bin_window_width, &bin_window_height);
 
   if (tree_view->priv->height < bin_window_height)
     {
       gtk_paint_flat_box (style,
-                          event->window,
+                          cr,
                           gtk_widget_get_state (widget),
                           GTK_SHADOW_NONE,
-                          &event->area,
                           widget,
                           "cell_even",
                           0, tree_view->priv->height,
@@ -4516,7 +4508,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
       highlight_x = 0; /* should match x coord of first cell */
       expander_cell_width = 0;
 
-      background_area.y = y_offset + event->area.y;
+      background_area.y = y_offset + clip.y;
       background_area.height = max_height;
 
       flags = 0;
@@ -4559,8 +4551,8 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
          if (!column->visible)
             continue;
 
-         if (cell_offset > event->area.x + event->area.width ||
-             cell_offset + column->width < event->area.x)
+         if (cell_offset > clip.x + clip.width ||
+             cell_offset + column->width < clip.x)
            {
              cell_offset += column->width;
              continue;
@@ -4609,7 +4601,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
              cell_area.height -= grid_line_width;
            }
 
-         if (cairo_region_contains_rectangle (event->region, &background_area) == CAIRO_REGION_OVERLAP_OUT)
+         if (!gdk_rectangle_intersect (&clip, &background_area, NULL))
            {
              cell_offset += column->width;
              continue;
@@ -4688,10 +4680,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
            g_snprintf (new_detail, 127, "%s_middle", detail);
 
          gtk_paint_flat_box (style,
-                             event->window,
+                             cr,
                              state,
                              GTK_SHADOW_NONE,
-                             &event->area,
                              widget,
                              new_detail,
                              background_area.x,
@@ -4720,10 +4711,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
              expander_cell_width = cell_area.width;
 
              if (is_separator)
-                gtk_paint_hline (style,
-                                event->window,
+               gtk_paint_hline (style,
+                                cr,
                                 state,
-                                &cell_area,
                                 widget,
                                 NULL,
                                 cell_area.x,
@@ -4731,10 +4721,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                                 cell_area.y + cell_area.height / 2);
              else
                _gtk_tree_view_column_cell_render (column,
-                                                  event->window,
+                                                  cr,
                                                   &background_area,
                                                   &cell_area,
-                                                  &event->area,
                                                   flags);
              if (TREE_VIEW_DRAW_EXPANDERS(tree_view)
                  && (node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT)
@@ -4747,6 +4736,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                    }
 
                  gtk_tree_view_draw_arrow (GTK_TREE_VIEW (widget),
+                                            cr,
                                            tree,
                                            node,
                                            pointer_x, pointer_y);
@@ -4755,10 +4745,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
          else
            {
              if (is_separator)
-                gtk_paint_hline (style,
-                                event->window,
+               gtk_paint_hline (style,
+                                cr,
                                 state,
-                                &cell_area,
                                 widget,
                                 NULL,
                                 cell_area.x,
@@ -4766,24 +4755,23 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                                 cell_area.y + cell_area.height / 2);
              else
                _gtk_tree_view_column_cell_render (column,
-                                                  event->window,
+                                                  cr,
                                                   &background_area,
                                                   &cell_area,
-                                                  &event->area,
                                                   flags);
            }
 
          if (draw_hgrid_lines)
            {
              if (background_area.y > 0)
-                gtk_tree_view_draw_line (tree_view, event->window,
+                gtk_tree_view_draw_line (tree_view, cr,
                                          GTK_TREE_VIEW_GRID_LINE,
                                          background_area.x, background_area.y,
                                          background_area.x + background_area.width,
                                         background_area.y);
 
-             if (y_offset + max_height >= event->area.height)
-                gtk_tree_view_draw_line (tree_view, event->window,
+             if (y_offset + max_height >= clip.height)
+                gtk_tree_view_draw_line (tree_view, cr,
                                          GTK_TREE_VIEW_GRID_LINE,
                                          background_area.x, background_area.y + max_height,
                                          background_area.x + background_area.width,
@@ -4805,7 +4793,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
              if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT
                  && depth > 1)
                {
-                  gtk_tree_view_draw_line (tree_view, event->window,
+                  gtk_tree_view_draw_line (tree_view, cr,
                                            GTK_TREE_VIEW_TREE_LINE,
                                            x + tree_view->priv->expander_size * (depth - 1.5) * mult,
                                            y1,
@@ -4814,7 +4802,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                }
              else if (depth > 1)
                {
-                  gtk_tree_view_draw_line (tree_view, event->window,
+                  gtk_tree_view_draw_line (tree_view, cr,
                                            GTK_TREE_VIEW_TREE_LINE,
                                            x + tree_view->priv->expander_size * (depth - 1.5) * mult,
                                            y1,
@@ -4829,14 +4817,14 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                  GtkRBTree *tmp_tree;
 
                  if (!_gtk_rbtree_next (tree, node))
-                    gtk_tree_view_draw_line (tree_view, event->window,
+                    gtk_tree_view_draw_line (tree_view, cr,
                                              GTK_TREE_VIEW_TREE_LINE,
                                              x + tree_view->priv->expander_size * (depth - 1.5) * mult,
                                              y0,
                                              x + tree_view->priv->expander_size * (depth - 1.5) * mult,
                                              y1);
                  else
-                    gtk_tree_view_draw_line (tree_view, event->window,
+                    gtk_tree_view_draw_line (tree_view, cr,
                                              GTK_TREE_VIEW_TREE_LINE,
                                              x + tree_view->priv->expander_size * (depth - 1.5) * mult,
                                              y0,
@@ -4849,7 +4837,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                  for (i = depth - 2; i > 0; i--)
                    {
                      if (_gtk_rbtree_next (tmp_tree, tmp_node))
-                        gtk_tree_view_draw_line (tree_view, event->window,
+                        gtk_tree_view_draw_line (tree_view, cr,
                                                  GTK_TREE_VIEW_TREE_LINE,
                                                  x + tree_view->priv->expander_size * (i - 0.5) * mult,
                                                  y0,
@@ -4869,10 +4857,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
               (column == tree_view->priv->edited_column)))
            {
              _gtk_tree_view_column_cell_draw_focus (column,
-                                                    event->window,
+                                                    cr,
                                                     &background_area,
                                                     &cell_area,
-                                                    &event->area,
                                                     flags);
            }
 
@@ -4886,7 +4873,6 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
           gint highlight_y = -1;
          GtkRBTree *tree = NULL;
          GtkRBNode *node = NULL;
-         gint width;
 
           switch (tree_view->priv->drag_dest_pos)
             {
@@ -4906,27 +4892,25 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
 
              if (tree == NULL)
                break;
-             gdk_drawable_get_size (tree_view->priv->bin_window,
-                                    &width, NULL);
 
              gtk_paint_focus (style,
-                              tree_view->priv->bin_window,
+                              cr,
                               gtk_widget_get_state (widget),
-                              &event->area,
                               widget,
                               (is_first
                                ? (is_last ? "treeview-drop-indicator" : "treeview-drop-indicator-left" )
                                : (is_last ? "treeview-drop-indicator-right" : "tree-view-drop-indicator-middle" )),
                                0, BACKGROUND_FIRST_PIXEL (tree_view, tree, node)
                                   - focus_line_width / 2,
-                               width, ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node))
-                                      - focus_line_width + 1);
+                               gdk_window_get_width (tree_view->priv->bin_window),
+                                ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node))
+                                  - focus_line_width + 1);
               break;
             }
 
           if (highlight_y >= 0)
             {
-              gtk_tree_view_draw_line (tree_view, event->window,
+              gtk_tree_view_draw_line (tree_view, cr,
                                        GTK_TREE_VIEW_FOREGROUND_LINE,
                                        rtl ? highlight_x + expander_cell_width : highlight_x,
                                        highlight_y,
@@ -4941,7 +4925,6 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
          gtk_widget_has_focus (widget))
         {
          gint tmp_y, tmp_height;
-         gint width;
          GtkStateType focus_rect_state;
 
          focus_rect_state =
@@ -4950,9 +4933,6 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
             (flags & GTK_CELL_RENDERER_INSENSITIVE ? GTK_STATE_INSENSITIVE :
              GTK_STATE_NORMAL));
 
-         gdk_drawable_get_size (tree_view->priv->bin_window,
-                                &width, NULL);
-         
          if (draw_hgrid_lines)
            {
              tmp_y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node) + grid_line_width / 2;
@@ -4965,15 +4945,15 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
            }
 
          gtk_paint_focus (style,
-                          tree_view->priv->bin_window,
+                          cr,
                           focus_rect_state,
-                          &event->area,
                           widget,
                           (is_first
                            ? (is_last ? "treeview" : "treeview-left" )
                            : (is_last ? "treeview-right" : "treeview-middle" )),
                           0, tmp_y,
-                          width, tmp_height);
+                          gdk_window_get_width (tree_view->priv->bin_window),
+                           tmp_height);
         }
 
       y_offset += max_height;
@@ -5034,24 +5014,13 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
          while (!done);
        }
     }
-  while (y_offset < event->area.height);
+  while (y_offset < clip.height);
 
 done:
-  gtk_tree_view_draw_grid_lines (tree_view, event, n_visible_columns);
+  gtk_tree_view_draw_grid_lines (tree_view, cr, n_visible_columns);
 
   if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE)
-    {
-      GdkRectangle rectangle;
-      gint n_rectangles;
-      n_rectangles = cairo_region_num_rectangles (event->region);
-      while (n_rectangles--)
-        {
-          cairo_region_get_rectangle (event->region, n_rectangles, &rectangle);
-          gtk_tree_view_paint_rubber_band (tree_view, &rectangle);
-        }
-    }
+    gtk_tree_view_paint_rubber_band (tree_view, cr);
 
   if (cursor_path)
     gtk_tree_path_free (cursor_path);
@@ -5063,19 +5032,24 @@ done:
 }
 
 static gboolean
-gtk_tree_view_expose (GtkWidget      *widget,
-                     GdkEventExpose *event)
+gtk_tree_view_draw (GtkWidget *widget,
+                    cairo_t   *cr)
 {
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
 
-  if (event->window == tree_view->priv->bin_window)
+  if (gtk_cairo_should_draw_window (cr, tree_view->priv->bin_window))
     {
-      gboolean retval;
       GList *tmp_list;
 
-      retval = gtk_tree_view_bin_expose (widget, event);
+      cairo_save (cr);
+
+      gtk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window);
 
-      /* We can't just chain up to Container::expose as it will try to send the
+      gtk_tree_view_bin_draw (widget, cr);
+
+      cairo_restore (cr);
+
+      /* We can't just chain up to Container::draw as it will try to send the
        * event to the headers, so we handle propagating it to our children
        * (eg. widgets being edited) ourselves.
        */
@@ -5085,13 +5059,11 @@ gtk_tree_view_expose (GtkWidget      *widget,
          GtkTreeViewChild *child = tmp_list->data;
          tmp_list = tmp_list->next;
 
-         gtk_container_propagate_expose (GTK_CONTAINER (tree_view), child->widget, event);
+         gtk_container_propagate_draw (GTK_CONTAINER (tree_view), child->widget, cr);
        }
-
-      return retval;
     }
 
-  else if (event->window == tree_view->priv->header_window)
+  if (gtk_cairo_should_draw_window (cr, tree_view->priv->header_window))
     {
       GList *list;
       
@@ -5103,17 +5075,20 @@ gtk_tree_view_expose (GtkWidget      *widget,
            continue;
 
          if (column->visible)
-           gtk_container_propagate_expose (GTK_CONTAINER (tree_view),
-                                           column->button,
-                                           event);
+           gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
+                                         column->button,
+                                         cr);
        }
     }
-  else if (event->window == tree_view->priv->drag_window)
+  
+  if (tree_view->priv->drag_window &&
+      gtk_cairo_should_draw_window (cr, tree_view->priv->drag_window))
     {
-      gtk_container_propagate_expose (GTK_CONTAINER (tree_view),
-                                     tree_view->priv->drag_column->button,
-                                     event);
+      gtk_container_propagate_draw (GTK_CONTAINER (tree_view),
+                                    tree_view->priv->drag_column->button,
+                                    cr);
     }
+
   return TRUE;
 }
 
@@ -5387,7 +5362,7 @@ gtk_tree_view_key_press (GtkWidget   *widget,
              GtkRequisition button_req;
               gint old_width = column->resized_width;
 
-             gtk_size_request_get_size (GTK_SIZE_REQUEST (column->button), &button_req, NULL);
+             gtk_widget_get_preferred_size (column->button, &button_req, NULL);
 
               column->resized_width = MAX (column->resized_width,
                                            column->width);
@@ -6192,8 +6167,8 @@ validate_visible_area (GtkTreeView *tree_view)
        * same when we get our next size_allocate.  If we don't do this, we'll be
        * in an inconsistent state if we call top_row_to_dy. */
 
-      gtk_size_request_get_size (GTK_SIZE_REQUEST (tree_view),
-                                 &requisition, NULL);
+      gtk_widget_get_preferred_size (GTK_WIDGET (tree_view),
+                                     &requisition, NULL);
       tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
       tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
       gtk_adjustment_changed (tree_view->priv->hadjustment);
@@ -6377,12 +6352,23 @@ do_validate_rows (GtkTreeView *tree_view, gboolean queue_resize)
   if (validated_area)
     {
       GtkRequisition requisition;
+
       /* We temporarily guess a size, under the assumption that it will be the
        * same when we get our next size_allocate.  If we don't do this, we'll be
        * in an inconsistent state when we call top_row_to_dy. */
 
-      gtk_size_request_get_size (GTK_SIZE_REQUEST (tree_view),
-                                 &requisition, NULL);
+      /* FIXME: This is called from size_request, for some reason it is not infinitely
+       * recursing, we cannot call gtk_widget_get_preferred_size() here because that's
+       * not allowed (from inside ->get_preferred_width/height() implementations, one
+       * should call the vfuncs directly). However what is desired here is the full
+       * size including any margins and limited by any alignment (i.e. after 
+       * GtkWidget:adjust_size_request() is called).
+       *
+       * Currently bypassing this but the real solution is to not update the scroll adjustments
+       * untill we've recieved an allocation (never update scroll adjustments from size-requests).
+       */
+      gtk_tree_view_size_request (GTK_WIDGET (tree_view), &requisition);
+
       tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
       tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
       gtk_adjustment_changed (tree_view->priv->hadjustment);
@@ -6445,8 +6431,8 @@ do_presize_handler (GtkTreeView *tree_view)
     {
       GtkRequisition requisition;
 
-      gtk_size_request_get_size (GTK_SIZE_REQUEST (tree_view),
-                                 &requisition, NULL);
+      gtk_widget_get_preferred_size (GTK_WIDGET (tree_view),
+                                     &requisition, NULL);
 
       tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
       tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
@@ -6484,6 +6470,21 @@ install_presize_handler (GtkTreeView *tree_view)
     }
 }
 
+static void
+gtk_tree_view_bin_process_updates (GtkTreeView *tree_view)
+{
+  /* Prior to drawing, we make sure the visible area is validated. */
+  if (tree_view->priv->presize_handler_timer)
+    {
+      g_source_remove (tree_view->priv->presize_handler_timer);
+      tree_view->priv->presize_handler_timer = 0;
+
+      do_presize_handler (tree_view);
+    }
+
+  gdk_window_process_updates (tree_view->priv->bin_window, TRUE);
+}
+
 static gboolean
 scroll_sync_handler (GtkTreeView *tree_view)
 {
@@ -7232,7 +7233,7 @@ gtk_tree_view_drag_begin (GtkWidget      *widget,
   GtkTreeView *tree_view;
   GtkTreePath *path = NULL;
   gint cell_x, cell_y;
-  GdkPixmap *row_pix;
+  cairo_surface_t *row_pix;
   TreeViewDragInfo *di;
 
   tree_view = GTK_TREE_VIEW (widget);
@@ -7255,16 +7256,14 @@ gtk_tree_view_drag_begin (GtkWidget      *widget,
 
   row_pix = gtk_tree_view_create_row_drag_icon (tree_view,
                                                 path);
+  cairo_surface_set_device_offset (row_pix,
+                                   /* the + 1 is for the black border in the icon */
+                                   - (tree_view->priv->press_start_x + 1),
+                                   - (cell_y + 1));
 
-  gtk_drag_set_icon_pixmap (context,
-                            gdk_drawable_get_colormap (row_pix),
-                            row_pix,
-                            NULL,
-                            /* the + 1 is for the black border in the icon */
-                            tree_view->priv->press_start_x + 1,
-                            cell_y + 1);
+  gtk_drag_set_icon_surface (context, row_pix);
 
-  g_object_unref (row_pix);
+  cairo_surface_destroy (row_pix);
   gtk_tree_path_free (path);
 }
 
@@ -8053,8 +8052,7 @@ gtk_tree_view_focus (GtkWidget        *widget,
   /* Case 2. We don't have focus at all. */
   if (!gtk_widget_has_focus (widget))
     {
-      if (!gtk_tree_view_header_focus (tree_view, direction, FALSE))
-       gtk_widget_grab_focus (widget);
+      gtk_widget_grab_focus (widget);
       return TRUE;
     }
 
@@ -8134,67 +8132,6 @@ gtk_tree_view_set_focus_child (GtkContainer *container,
   GTK_CONTAINER_CLASS (gtk_tree_view_parent_class)->set_focus_child (container, child);
 }
 
-static void
-gtk_tree_view_set_adjustments (GtkTreeView   *tree_view,
-                              GtkAdjustment *hadj,
-                              GtkAdjustment *vadj)
-{
-  gboolean need_adjust = FALSE;
-
-  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
-
-  if (hadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
-  else
-    hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
-  if (vadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
-  else
-    vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
-
-  if (tree_view->priv->hadjustment && (tree_view->priv->hadjustment != hadj))
-    {
-      g_signal_handlers_disconnect_by_func (tree_view->priv->hadjustment,
-                                           gtk_tree_view_adjustment_changed,
-                                           tree_view);
-      g_object_unref (tree_view->priv->hadjustment);
-    }
-
-  if (tree_view->priv->vadjustment && (tree_view->priv->vadjustment != vadj))
-    {
-      g_signal_handlers_disconnect_by_func (tree_view->priv->vadjustment,
-                                           gtk_tree_view_adjustment_changed,
-                                           tree_view);
-      g_object_unref (tree_view->priv->vadjustment);
-    }
-
-  if (tree_view->priv->hadjustment != hadj)
-    {
-      tree_view->priv->hadjustment = hadj;
-      g_object_ref_sink (tree_view->priv->hadjustment);
-
-      g_signal_connect (tree_view->priv->hadjustment, "value-changed",
-                       G_CALLBACK (gtk_tree_view_adjustment_changed),
-                       tree_view);
-      need_adjust = TRUE;
-    }
-
-  if (tree_view->priv->vadjustment != vadj)
-    {
-      tree_view->priv->vadjustment = vadj;
-      g_object_ref_sink (tree_view->priv->vadjustment);
-
-      g_signal_connect (tree_view->priv->vadjustment, "value-changed",
-                       G_CALLBACK (gtk_tree_view_adjustment_changed),
-                       tree_view);
-      need_adjust = TRUE;
-    }
-
-  if (need_adjust)
-    gtk_tree_view_adjustment_changed (NULL, tree_view);
-}
-
-
 static gboolean
 gtk_tree_view_real_move_cursor (GtkTreeView       *tree_view,
                                GtkMovementStep    step,
@@ -8943,7 +8880,8 @@ gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view,
     {
       /* We process updates because we want to clear old selected items when we scroll.
        * if this is removed, we get a "selection streak" at the bottom. */
-      gdk_window_process_updates (tree_view->priv->bin_window, TRUE);
+      gtk_tree_view_bin_process_updates (tree_view);
+
       gtk_tree_view_scroll_to_cell (tree_view, path, NULL, FALSE, 0.0, 0.0);
       gtk_tree_path_free (path);
     }
@@ -9333,10 +9271,8 @@ gtk_tree_view_set_column_drag_info (GtkTreeView       *tree_view,
        }
       else
        {
-         gint width;
-
-         gdk_drawable_get_size (tree_view->priv->header_window, &width, NULL);
-         reorder->right_align = width + TREE_VIEW_COLUMN_DRAG_DEAD_MULTIPLIER (tree_view);
+         reorder->right_align = gdk_window_get_width (tree_view->priv->header_window)
+                                 + TREE_VIEW_COLUMN_DRAG_DEAD_MULTIPLIER (tree_view);
        }
     }
 }
@@ -9349,7 +9285,6 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
   GdkEvent *send_event;
   GtkAllocation allocation;
   GtkAllocation button_allocation;
-  gint x, y, width, height;
   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (tree_view));
   GdkDisplay *display = gdk_screen_get_display (screen);
 
@@ -9375,9 +9310,8 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
       attributes.width = button_allocation.width;
       attributes.height = button_allocation.height;
       attributes.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
-      attributes.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view));
       attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK;
-      attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+      attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
       tree_view->priv->drag_window = gdk_window_new (tree_view->priv->bin_window,
                                                     &attributes,
@@ -9392,7 +9326,7 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
 
   send_event = gdk_event_new (GDK_LEAVE_NOTIFY);
   send_event->crossing.send_event = TRUE;
-  send_event->crossing.window = g_object_ref (GTK_BUTTON (column->button)->event_window);
+  send_event->crossing.window = g_object_ref (gtk_button_get_event_window (GTK_BUTTON (column->button)));
   send_event->crossing.subwindow = NULL;
   send_event->crossing.detail = GDK_NOTIFY_ANCESTOR;
   send_event->crossing.time = GDK_CURRENT_TIME;
@@ -9434,9 +9368,6 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
   tree_view->priv->drag_column = column;
   gdk_window_show (tree_view->priv->drag_window);
 
-  gdk_window_get_origin (tree_view->priv->header_window, &x, &y);
-  gdk_drawable_get_size (tree_view->priv->header_window, &width, &height);
-
   gtk_widget_grab_focus (GTK_WIDGET (tree_view));
   while (gtk_events_pending ())
     gtk_main_iteration ();
@@ -9454,8 +9385,7 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
 static void
 gtk_tree_view_queue_draw_arrow (GtkTreeView        *tree_view,
                                GtkRBTree          *tree,
-                               GtkRBNode          *node,
-                               const GdkRectangle *clip_rect)
+                               GtkRBNode          *node)
 {
   GtkAllocation allocation;
   GdkRectangle rect;
@@ -9470,18 +9400,7 @@ gtk_tree_view_queue_draw_arrow (GtkTreeView        *tree_view,
   rect.y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
   rect.height = ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node));
 
-  if (clip_rect)
-    {
-      GdkRectangle new_rect;
-
-      gdk_rectangle_intersect (clip_rect, &rect, &new_rect);
-
-      gdk_window_invalidate_rect (tree_view->priv->bin_window, &new_rect, TRUE);
-    }
-  else
-    {
-      gdk_window_invalidate_rect (tree_view->priv->bin_window, &rect, TRUE);
-    }
+  gdk_window_invalidate_rect (tree_view->priv->bin_window, &rect, TRUE);
 }
 
 void
@@ -9535,6 +9454,7 @@ gtk_tree_view_queue_draw_path (GtkTreeView        *tree_view,
  */
 static void
 gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
+                          cairo_t     *cr,
                           GtkRBTree   *tree,
                          GtkRBNode   *node,
                          /* in bin_window coordinates */
@@ -9598,9 +9518,8 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
     expander_style = GTK_EXPANDER_COLLAPSED;
 
   gtk_paint_expander (gtk_widget_get_style (widget),
-                      tree_view->priv->bin_window,
+                      cr,
                       state,
-                      &area,
                       widget,
                       "treeview",
                      area.x + area.width / 2,
@@ -10449,7 +10368,7 @@ gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view)
   gtk_widget_show (frame);
   gtk_container_add (GTK_CONTAINER (tree_view->priv->search_window), frame);
 
-  vbox = gtk_vbox_new (FALSE, 0);
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
   gtk_widget_show (vbox);
   gtk_container_add (GTK_CONTAINER (frame), vbox);
   gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
@@ -10593,7 +10512,7 @@ gtk_tree_view_new_column_width (GtkTreeView *tree_view,
   /* Clamp down the value */
   if (column->min_width == -1)
     {
-      gtk_size_request_get_size (GTK_SIZE_REQUEST (column->button), &button_req, NULL);
+      gtk_widget_get_preferred_size (column->button, &button_req, NULL);
       width = MAX (button_req.width, width);
     }
   else
@@ -10737,7 +10656,7 @@ gtk_tree_view_adjustment_changed (GtkAdjustment *adjustment,
        }
 
       gdk_window_process_updates (tree_view->priv->header_window, TRUE);
-      gdk_window_process_updates (tree_view->priv->bin_window, TRUE);
+      gtk_tree_view_bin_process_updates (tree_view);
     }
 }
 
@@ -10969,15 +10888,14 @@ gtk_tree_view_get_selection (GtkTreeView *tree_view)
  *
  * Return value: (transfer none): A #GtkAdjustment object, or %NULL
  *     if none is currently being used.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
  **/
 GtkAdjustment *
 gtk_tree_view_get_hadjustment (GtkTreeView *tree_view)
 {
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
 
-  if (tree_view->priv->hadjustment == NULL)
-    gtk_tree_view_set_hadjustment (tree_view, NULL);
-
   return tree_view->priv->hadjustment;
 }
 
@@ -10987,16 +10905,40 @@ gtk_tree_view_get_hadjustment (GtkTreeView *tree_view)
  * @adjustment: (allow-none): The #GtkAdjustment to set, or %NULL
  *
  * Sets the #GtkAdjustment for the current horizontal aspect.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_hadjustment()
  **/
 void
 gtk_tree_view_set_hadjustment (GtkTreeView   *tree_view,
-                              GtkAdjustment *adjustment)
+                               GtkAdjustment *adjustment)
 {
+  GtkTreeViewPrivate *priv = tree_view->priv;
+
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
+
+  if (adjustment && priv->hadjustment == adjustment)
+    return;
+
+  if (priv->hadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->hadjustment,
+                                            gtk_tree_view_adjustment_changed,
+                                            tree_view);
+      g_object_unref (priv->hadjustment);
+    }
 
-  gtk_tree_view_set_adjustments (tree_view,
-                                adjustment,
-                                tree_view->priv->vadjustment);
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_tree_view_adjustment_changed), tree_view);
+  priv->hadjustment = g_object_ref_sink (adjustment);
+  /* FIXME: Adjustment should probably be populated here with fresh values, but
+   * internal details are too complicated for me to decipher right now.
+   */
+  gtk_tree_view_adjustment_changed (NULL, tree_view);
 
   g_object_notify (G_OBJECT (tree_view), "hadjustment");
 }
@@ -11009,15 +10951,14 @@ gtk_tree_view_set_hadjustment (GtkTreeView   *tree_view,
  *
  * Return value: (transfer none): A #GtkAdjustment object, or %NULL
  *     if none is currently being used.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment()
  **/
 GtkAdjustment *
 gtk_tree_view_get_vadjustment (GtkTreeView *tree_view)
 {
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
 
-  if (tree_view->priv->vadjustment == NULL)
-    gtk_tree_view_set_vadjustment (tree_view, NULL);
-
   return tree_view->priv->vadjustment;
 }
 
@@ -11027,17 +10968,40 @@ gtk_tree_view_get_vadjustment (GtkTreeView *tree_view)
  * @adjustment: (allow-none): The #GtkAdjustment to set, or %NULL
  *
  * Sets the #GtkAdjustment for the current vertical aspect.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment()
  **/
 void
 gtk_tree_view_set_vadjustment (GtkTreeView   *tree_view,
-                              GtkAdjustment *adjustment)
+                               GtkAdjustment *adjustment)
 {
+  GtkTreeViewPrivate *priv = tree_view->priv;
+
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
+
+  if (adjustment && priv->vadjustment == adjustment)
+    return;
+
+  if (priv->vadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->vadjustment,
+                                            gtk_tree_view_adjustment_changed,
+                                            tree_view);
+      g_object_unref (priv->vadjustment);
+    }
 
-  gtk_tree_view_set_adjustments (tree_view,
-                                tree_view->priv->hadjustment,
-                                adjustment);
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
 
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_tree_view_adjustment_changed), tree_view);
+  priv->vadjustment = g_object_ref_sink (adjustment);
+  /* FIXME: Adjustment should probably be populated here with fresh values, but
+   * internal details are too complicated for me to decipher right now.
+   */
+  gtk_tree_view_adjustment_changed (NULL, tree_view);
   g_object_notify (G_OBJECT (tree_view), "vadjustment");
 }
 
@@ -11790,7 +11754,7 @@ gtk_tree_view_scroll_to_cell (GtkTreeView       *tree_view,
    */
   if (!gtk_widget_get_visible (GTK_WIDGET (tree_view)) ||
       !gtk_widget_get_realized (GTK_WIDGET (tree_view)) ||
-      GTK_WIDGET_ALLOC_NEEDED (tree_view) || 
+      _gtk_widget_get_alloc_needed (GTK_WIDGET (tree_view)) ||
       GTK_RBNODE_FLAG_SET (tree_view->priv->tree->root, GTK_RBNODE_DESCENDANTS_INVALID))
     {
       if (tree_view->priv->scroll_to_path)
@@ -12047,7 +12011,7 @@ do_expand_collapse (GtkTreeView *tree_view)
 
   if (redraw)
     {
-      gtk_tree_view_queue_draw_arrow (tree_view, tree, node, NULL);
+      gtk_tree_view_queue_draw_arrow (tree_view, tree, node);
 
       return TRUE;
     }
@@ -13761,12 +13725,12 @@ gtk_tree_view_get_dest_row_at_pos (GtkTreeView             *tree_view,
  * @tree_view: a #GtkTreeView
  * @path: a #GtkTreePath in @tree_view
  *
- * Creates a #GdkPixmap representation of the row at @path.
+ * Creates a #cairo_surface_t representation of the row at @path.  
  * This image is used for a drag icon.
  *
- * Return value: (transfer full): a newly-allocated pixmap of the drag icon.
+ * Return value: (transfer full): a newly-allocated surface of the drag icon.
  **/
-GdkPixmap *
+cairo_surface_t *
 gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
                                     GtkTreePath  *path)
 {
@@ -13777,12 +13741,11 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
   gint cell_offset;
   GList *list;
   GdkRectangle background_area;
-  GdkRectangle expose_area;
   GtkWidget *widget;
   gint depth;
   /* start drawing inside the black outline */
   gint x = 1, y = 1;
-  GdkDrawable *drawable;
+  cairo_surface_t *surface;
   gint bin_window_width;
   gboolean is_separator = FALSE;
   gboolean rtl;
@@ -13820,20 +13783,14 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
   background_area.y = y;
   background_area.height = ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node));
 
-  gdk_drawable_get_size (tree_view->priv->bin_window,
-                         &bin_window_width, NULL);
-
-  drawable = gdk_pixmap_new (tree_view->priv->bin_window,
-                             bin_window_width + 2,
-                             background_area.height + 2,
-                             -1);
+  bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
 
-  expose_area.x = 0;
-  expose_area.y = 0;
-  expose_area.width = bin_window_width + 2;
-  expose_area.height = background_area.height + 2;
+  surface = gdk_window_create_similar_surface (tree_view->priv->bin_window,
+                                               CAIRO_CONTENT_COLOR,
+                                               bin_window_width + 2,
+                                               background_area.height + 2);
 
-  cr = gdk_cairo_create (drawable);
+  cr = cairo_create (surface);
   gdk_cairo_set_source_color (cr, &style->base [gtk_widget_get_state (widget)]);
   cairo_paint (cr);
 
@@ -13884,20 +13841,18 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
        {
          if (is_separator)
            gtk_paint_hline (style,
-                            drawable,
-                            GTK_STATE_NORMAL,
-                            &cell_area,
-                            widget,
-                            NULL,
-                            cell_area.x,
-                            cell_area.x + cell_area.width,
-                            cell_area.y + cell_area.height / 2);
+                                   cr,
+                                   GTK_STATE_NORMAL,
+                                   widget,
+                                   NULL,
+                                   cell_area.x,
+                                   cell_area.x + cell_area.width,
+                                   cell_area.y + cell_area.height / 2);
          else
            _gtk_tree_view_column_cell_render (column,
-                                              drawable,
+                                               cr,
                                               &background_area,
                                               &cell_area,
-                                              &expose_area,
                                               0);
        }
       cell_offset += column->width;
@@ -13913,7 +13868,9 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
 
   cairo_destroy (cr);
 
-  return drawable;
+  cairo_surface_set_device_offset (surface, 2, 2);
+
+  return surface;
 }
 
 
@@ -14263,7 +14220,7 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view,
   gint tree_x, tree_y;
   gint tree_width, tree_height;
   GdkWindow *tree_window = gtk_widget_get_window (GTK_WIDGET (tree_view));
-  GdkScreen *screen = gdk_drawable_get_screen (tree_window);
+  GdkScreen *screen = gdk_window_get_screen (tree_window);
   GtkRequisition requisition;
   gint monitor_num;
   GdkRectangle monitor;
@@ -14274,11 +14231,9 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view,
   gtk_widget_realize (search_dialog);
 
   gdk_window_get_origin (tree_window, &tree_x, &tree_y);
-  gdk_drawable_get_size (tree_window,
-                        &tree_width,
-                        &tree_height);
-  gtk_size_request_get_size (GTK_SIZE_REQUEST (search_dialog),
-                             &requisition, NULL);
+  tree_width = gdk_window_get_width (tree_window);
+  tree_height = gdk_window_get_height (tree_window);
+  gtk_widget_get_preferred_size (search_dialog, &requisition, NULL);
 
   if (tree_x + tree_width > gdk_screen_get_width (screen))
     x = gdk_screen_get_width (screen) - requisition.width;
@@ -14895,8 +14850,8 @@ gtk_tree_view_real_start_editing (GtkTreeView       *tree_view,
   gtk_tree_view_real_set_cursor (tree_view, path, FALSE, TRUE);
   cell_area->y += pre_val - (int)tree_view->priv->vadjustment->value;
 
-  gtk_size_request_get_size (GTK_SIZE_REQUEST (cell_editable),
-                             &requisition, NULL);
+  gtk_widget_get_preferred_size (GTK_WIDGET (cell_editable),
+                                 &requisition, NULL);
 
   GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);