]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktreeview.c
gtk: remove "gboolean homogeneous" from gtk_box_new()
[~andy/gtk] / gtk / gtktreeview.c
index ef5b94832006a69a45f787bee4177fa5a026ef37..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 "gtkscrollable.h"
 #include "gtkprivate.h"
-#include "gtkalias.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,
@@ -396,8 +405,9 @@ static void     update_prelight                              (GtkTreeView
 
 /* interactive search */
 static void     gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view);
-static void     gtk_tree_view_search_dialog_hide     (GtkWidget        *search_dialog,
-                                                        GtkTreeView      *tree_view);
+static void     gtk_tree_view_search_dialog_hide        (GtkWidget        *search_dialog,
+                                                         GtkTreeView      *tree_view,
+                                                         GdkDevice        *device);
 static void     gtk_tree_view_search_position_func      (GtkTreeView      *tree_view,
                                                         GtkWidget        *search_dialog,
                                                         gpointer          user_data);
@@ -457,6 +467,7 @@ static void gtk_tree_view_real_start_editing (GtkTreeView       *tree_view,
 static void gtk_tree_view_stop_editing                  (GtkTreeView *tree_view,
                                                         gboolean     cancel_editing);
 static gboolean gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view,
+                                                             GdkDevice   *device,
                                                             gboolean     keybinding);
 static gboolean gtk_tree_view_start_interactive_search      (GtkTreeView *tree_view);
 static GtkTreeViewColumn *gtk_tree_view_get_drop_column (GtkTreeView       *tree_view,
@@ -464,11 +475,14 @@ static GtkTreeViewColumn *gtk_tree_view_get_drop_column (GtkTreeView       *tree
                                                         gint               drop_position);
 
 /* GtkBuildable */
-static void gtk_tree_view_buildable_add_child (GtkBuildable *tree_view,
-                                              GtkBuilder  *builder,
-                                              GObject     *child,
-                                              const gchar *type);
-static void gtk_tree_view_buildable_init      (GtkBuildableIface *iface);
+static void     gtk_tree_view_buildable_add_child          (GtkBuildable      *tree_view,
+                                                           GtkBuilder        *builder,
+                                                           GObject           *child,
+                                                           const gchar       *type);
+static GObject *gtk_tree_view_buildable_get_internal_child (GtkBuildable      *buildable,
+                                                           GtkBuilder        *builder,
+                                                           const gchar       *childname);
+static void     gtk_tree_view_buildable_init               (GtkBuildableIface *iface);
 
 
 static gboolean scroll_row_timeout                   (gpointer     data);
@@ -484,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;
@@ -498,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;
 
@@ -507,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;
@@ -546,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;
@@ -566,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,
@@ -662,7 +662,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
     /**
      * GtkTreeView:hover-selection:
      * 
-     * Enables of disables the hover selection mode of @tree_view.
+     * Enables or disables the hover selection mode of @tree_view.
      * Hover selection makes the selected row follow the pointer.
      * Currently, this works only for the selection modes 
      * %GTK_SELECTION_SINGLE and %GTK_SELECTION_BROWSE.
@@ -683,7 +683,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
     /**
      * GtkTreeView:hover-expand:
      * 
-     * Enables of disables the hover expansion mode of @tree_view.
+     * Enables or disables the hover expansion mode of @tree_view.
      * Hover expansion makes rows expand or collapse if the pointer moves 
      * over them.
      *
@@ -827,13 +827,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                                                               GDK_TYPE_COLOR,
                                                               GTK_PARAM_READABLE));
 
-  gtk_widget_class_install_style_property (widget_class,
-                                          g_param_spec_boolean ("row-ending-details",
-                                                                P_("Row Ending details"),
-                                                                P_("Enable extended row background theming"),
-                                                                FALSE,
-                                                                GTK_PARAM_READABLE));
-
   gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("grid-line-width",
                                                             P_("Grid line width"),
@@ -863,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
@@ -1023,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,
@@ -1034,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,
@@ -1043,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,
@@ -1052,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,
@@ -1062,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,
@@ -1071,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,
@@ -1083,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,
@@ -1092,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,
@@ -1100,227 +1073,221 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                  G_TYPE_BOOLEAN, 0);
 
   /* Key bindings */
-  gtk_tree_view_add_move_binding (binding_set, GDK_Up, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_Up, 0, TRUE,
                                  GTK_MOVEMENT_DISPLAY_LINES, -1);
-  gtk_tree_view_add_move_binding (binding_set, GDK_KP_Up, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_KP_Up, 0, TRUE,
                                  GTK_MOVEMENT_DISPLAY_LINES, -1);
 
-  gtk_tree_view_add_move_binding (binding_set, GDK_Down, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_Down, 0, TRUE,
                                  GTK_MOVEMENT_DISPLAY_LINES, 1);
-  gtk_tree_view_add_move_binding (binding_set, GDK_KP_Down, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_KP_Down, 0, TRUE,
                                  GTK_MOVEMENT_DISPLAY_LINES, 1);
 
-  gtk_tree_view_add_move_binding (binding_set, GDK_p, GDK_CONTROL_MASK, FALSE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_p, GDK_CONTROL_MASK, FALSE,
                                  GTK_MOVEMENT_DISPLAY_LINES, -1);
 
-  gtk_tree_view_add_move_binding (binding_set, GDK_n, GDK_CONTROL_MASK, FALSE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_n, GDK_CONTROL_MASK, FALSE,
                                  GTK_MOVEMENT_DISPLAY_LINES, 1);
 
-  gtk_tree_view_add_move_binding (binding_set, GDK_Home, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_Home, 0, TRUE,
                                  GTK_MOVEMENT_BUFFER_ENDS, -1);
-  gtk_tree_view_add_move_binding (binding_set, GDK_KP_Home, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_KP_Home, 0, TRUE,
                                  GTK_MOVEMENT_BUFFER_ENDS, -1);
 
-  gtk_tree_view_add_move_binding (binding_set, GDK_End, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_End, 0, TRUE,
                                  GTK_MOVEMENT_BUFFER_ENDS, 1);
-  gtk_tree_view_add_move_binding (binding_set, GDK_KP_End, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_KP_End, 0, TRUE,
                                  GTK_MOVEMENT_BUFFER_ENDS, 1);
 
-  gtk_tree_view_add_move_binding (binding_set, GDK_Page_Up, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_Page_Up, 0, TRUE,
                                  GTK_MOVEMENT_PAGES, -1);
-  gtk_tree_view_add_move_binding (binding_set, GDK_KP_Page_Up, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_KP_Page_Up, 0, TRUE,
                                  GTK_MOVEMENT_PAGES, -1);
 
-  gtk_tree_view_add_move_binding (binding_set, GDK_Page_Down, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_Page_Down, 0, TRUE,
                                  GTK_MOVEMENT_PAGES, 1);
-  gtk_tree_view_add_move_binding (binding_set, GDK_KP_Page_Down, 0, TRUE,
+  gtk_tree_view_add_move_binding (binding_set, GDK_KEY_KP_Page_Down, 0, TRUE,
                                  GTK_MOVEMENT_PAGES, 1);
 
 
-  gtk_binding_entry_add_signal (binding_set, GDK_Right, 0, "move-cursor", 2,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, 0, "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, 1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_Left, 0, "move-cursor", 2,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, 0, "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, -1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, 0, "move-cursor", 2,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right, 0, "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, 1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, 0, "move-cursor", 2,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left, 0, "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, -1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_Right, GDK_CONTROL_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, GDK_CONTROL_MASK,
                                 "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, 1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_Left, GDK_CONTROL_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, GDK_CONTROL_MASK,
                                 "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, -1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, GDK_CONTROL_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right, GDK_CONTROL_MASK,
                                 "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, 1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, GDK_CONTROL_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left, GDK_CONTROL_MASK,
                                 "move-cursor", 2,
                                G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
                                G_TYPE_INT, -1);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_CONTROL_MASK, "toggle-cursor-row", 0);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, GDK_CONTROL_MASK, "toggle-cursor-row", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, GDK_CONTROL_MASK, "toggle-cursor-row", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, GDK_CONTROL_MASK, "toggle-cursor-row", 0);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK, "select-all", 0);
-  gtk_binding_entry_add_signal (binding_set, GDK_slash, GDK_CONTROL_MASK, "select-all", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_a, GDK_CONTROL_MASK, "select-all", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_slash, GDK_CONTROL_MASK, "select-all", 0);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_A, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "unselect-all", 0);
-  gtk_binding_entry_add_signal (binding_set, GDK_backslash, GDK_CONTROL_MASK, "unselect-all", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_A, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "unselect-all", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_backslash, GDK_CONTROL_MASK, "unselect-all", 0);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_SHIFT_MASK, "select-cursor-row", 1,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, GDK_SHIFT_MASK, "select-cursor-row", 1,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, GDK_SHIFT_MASK, "select-cursor-row", 1,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, GDK_SHIFT_MASK, "select-cursor-row", 1,
                                G_TYPE_BOOLEAN, TRUE);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_space, 0, "select-cursor-row", 1,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0, "select-cursor-row", 1,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0, "select-cursor-row", 1,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0, "select-cursor-row", 1,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "select-cursor-row", 1,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "select-cursor-row", 1,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0, "select-cursor-row", 1,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0, "select-cursor-row", 1,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "select-cursor-row", 1,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "select-cursor-row", 1,
                                G_TYPE_BOOLEAN, TRUE);
 
   /* expand and collapse rows */
-  gtk_binding_entry_add_signal (binding_set, GDK_plus, 0, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, 0, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, FALSE);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_asterisk, 0,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_asterisk, 0,
                                 "expand-collapse-cursor-row", 3,
                                 G_TYPE_BOOLEAN, TRUE,
                                 G_TYPE_BOOLEAN, TRUE,
                                 G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Multiply, 0,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Multiply, 0,
                                 "expand-collapse-cursor-row", 3,
                                 G_TYPE_BOOLEAN, TRUE,
                                 G_TYPE_BOOLEAN, TRUE,
                                 G_TYPE_BOOLEAN, TRUE);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_slash, 0,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_slash, 0,
                                 "expand-collapse-cursor-row", 3,
                                 G_TYPE_BOOLEAN, TRUE,
                                 G_TYPE_BOOLEAN, FALSE,
                                 G_TYPE_BOOLEAN, FALSE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Divide, 0,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Divide, 0,
                                 "expand-collapse-cursor-row", 3,
                                 G_TYPE_BOOLEAN, TRUE,
                                 G_TYPE_BOOLEAN, FALSE,
                                 G_TYPE_BOOLEAN, FALSE);
 
   /* Not doable on US keyboards */
-  gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Add, 0, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Add, 0, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, FALSE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Add, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Add, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Add, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Add, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_Right, GDK_SHIFT_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, GDK_SHIFT_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right, GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_Right,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right,
                                 GDK_CONTROL_MASK | GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Right,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right,
                                 GDK_CONTROL_MASK | GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, TRUE);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_minus, 0, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, 0, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, FALSE);
-  gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Subtract, 0, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Subtract, 0, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, FALSE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Subtract, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Subtract, GDK_SHIFT_MASK, "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, TRUE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_Left, GDK_SHIFT_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, GDK_SHIFT_MASK,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left, GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_Left,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left,
                                 GDK_CONTROL_MASK | GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE);
-  gtk_binding_entry_add_signal (binding_set, GDK_KP_Left,
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left,
                                 GDK_CONTROL_MASK | GDK_SHIFT_MASK,
                                 "expand-collapse-cursor-row", 3,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, FALSE,
                                G_TYPE_BOOLEAN, TRUE);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0, "select-cursor-parent", 0);
-  gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_CONTROL_MASK, "select-cursor-parent", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_BackSpace, 0, "select-cursor-parent", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_BackSpace, GDK_CONTROL_MASK, "select-cursor-parent", 0);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_f, GDK_CONTROL_MASK, "start-interactive-search", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_f, GDK_CONTROL_MASK, "start-interactive-search", 0);
 
-  gtk_binding_entry_add_signal (binding_set, GDK_F, GDK_CONTROL_MASK, "start-interactive-search", 0);
+  gtk_binding_entry_add_signal (binding_set, GDK_KEY_F, GDK_CONTROL_MASK, "start-interactive-search", 0);
 
   g_type_class_add_private (o_class, sizeof (GtkTreeViewPrivate));
 }
 
-static void
-gtk_tree_view_buildable_init (GtkBuildableIface *iface)
-{
-  iface->add_child = gtk_tree_view_buildable_add_child;
-}
-
 static void
 gtk_tree_view_init (GtkTreeView *tree_view)
 {
@@ -1350,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;
@@ -1380,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
@@ -1408,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;
@@ -1483,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;
@@ -1543,7 +1526,16 @@ gtk_tree_view_finalize (GObject *object)
   G_OBJECT_CLASS (gtk_tree_view_parent_class)->finalize (object);
 }
 
-\f
+
+static GtkBuildableIface *parent_buildable_iface;
+
+static void
+gtk_tree_view_buildable_init (GtkBuildableIface *iface)
+{
+  parent_buildable_iface = g_type_interface_peek_parent (iface);
+  iface->add_child = gtk_tree_view_buildable_add_child;
+  iface->get_internal_child = gtk_tree_view_buildable_get_internal_child;
+}
 
 static void
 gtk_tree_view_buildable_add_child (GtkBuildable *tree_view,
@@ -1554,7 +1546,20 @@ gtk_tree_view_buildable_add_child (GtkBuildable *tree_view,
   gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (child));
 }
 
-/* GtkObject Methods
+static GObject *
+gtk_tree_view_buildable_get_internal_child (GtkBuildable      *buildable,
+                                           GtkBuilder        *builder,
+                                           const gchar       *childname)
+{
+    if (strcmp (childname, "selection") == 0)
+      return G_OBJECT (GTK_TREE_VIEW (buildable)->priv->selection);
+    
+    return parent_buildable_iface->get_internal_child (buildable,
+                                                      builder,
+                                                      childname);
+}
+
+/* GtkWidget Methods
  */
 
 static void
@@ -1572,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);
@@ -1688,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)
@@ -1756,41 +1756,48 @@ gtk_tree_view_map (GtkWidget *widget)
 
   gtk_tree_view_map_buttons (tree_view);
 
-  gdk_window_show (widget->window);
+  gdk_window_show (gtk_widget_get_window (widget));
 }
 
 static void
 gtk_tree_view_realize (GtkWidget *widget)
 {
+  GtkAllocation allocation;
+  GtkStyle *style;
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
-  GList *tmp_list;
+  GdkWindow *window;
   GdkWindowAttr attributes;
+  GList *tmp_list;
   gint attributes_mask;
 
   gtk_widget_set_realized (widget, TRUE);
 
+  gtk_widget_get_allocation (widget, &allocation);
+
   /* Make the main, clipping window */
   attributes.window_type = GDK_WINDOW_CHILD;
-  attributes.x = widget->allocation.x;
-  attributes.y = widget->allocation.y;
-  attributes.width = widget->allocation.width;
-  attributes.height = widget->allocation.height;
+  attributes.x = allocation.x;
+  attributes.y = allocation.y;
+  attributes.width = allocation.width;
+  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);
+  gtk_widget_set_window (widget, window);
+  gdk_window_set_user_data (window, widget);
 
-  widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
-                                  &attributes, attributes_mask);
-  gdk_window_set_user_data (widget->window, widget);
+  gtk_widget_get_allocation (widget, &allocation);
 
   /* Make the window for the tree */
   attributes.x = 0;
   attributes.y = TREE_VIEW_HEADER_HEIGHT (tree_view);
-  attributes.width = MAX (tree_view->priv->width, widget->allocation.width);
-  attributes.height = widget->allocation.height;
+  attributes.width = MAX (tree_view->priv->width, allocation.width);
+  attributes.height = allocation.height;
   attributes.event_mask = (GDK_EXPOSURE_MASK |
                            GDK_SCROLL_MASK |
                            GDK_POINTER_MOTION_MASK |
@@ -1800,32 +1807,37 @@ gtk_tree_view_realize (GtkWidget *widget)
                            GDK_BUTTON_RELEASE_MASK |
                            gtk_widget_get_events (widget));
 
-  tree_view->priv->bin_window = gdk_window_new (widget->window,
+  tree_view->priv->bin_window = gdk_window_new (window,
                                                &attributes, attributes_mask);
   gdk_window_set_user_data (tree_view->priv->bin_window, widget);
 
+  gtk_widget_get_allocation (widget, &allocation);
+
   /* Make the column header window */
   attributes.x = 0;
   attributes.y = 0;
-  attributes.width = MAX (tree_view->priv->width, widget->allocation.width);
+  attributes.width = MAX (tree_view->priv->width, allocation.width);
   attributes.height = tree_view->priv->header_height;
   attributes.event_mask = (GDK_EXPOSURE_MASK |
                            GDK_SCROLL_MASK |
+                           GDK_ENTER_NOTIFY_MASK |
+                           GDK_LEAVE_NOTIFY_MASK |
                            GDK_BUTTON_PRESS_MASK |
                            GDK_BUTTON_RELEASE_MASK |
                            GDK_KEY_PRESS_MASK |
                            GDK_KEY_RELEASE_MASK |
                            gtk_widget_get_events (widget));
 
-  tree_view->priv->header_window = gdk_window_new (widget->window,
+  tree_view->priv->header_window = gdk_window_new (window,
                                                   &attributes, attributes_mask);
   gdk_window_set_user_data (tree_view->priv->header_window, widget);
 
   /* Add them all up. */
-  widget->style = gtk_style_attach (widget->style, widget->window);
-  gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
-  gdk_window_set_background (tree_view->priv->bin_window, &widget->style->base[widget->state]);
-  gtk_style_set_background (widget->style, tree_view->priv->header_window, GTK_STATE_NORMAL);
+  gtk_widget_style_attach (widget);
+  style = gtk_widget_get_style (widget);
+  gdk_window_set_background (tree_view->priv->bin_window,
+                             &style->base[gtk_widget_get_state (widget)]);
+  gtk_style_set_background (style, tree_view->priv->header_window, GTK_STATE_NORMAL);
 
   tmp_list = tree_view->priv->children;
   while (tmp_list)
@@ -1922,18 +1934,6 @@ gtk_tree_view_unrealize (GtkWidget *widget)
       priv->drag_highlight_window = NULL;
     }
 
-  if (priv->tree_line_gc)
-    {
-      g_object_unref (priv->tree_line_gc);
-      priv->tree_line_gc = NULL;
-    }
-
-  if (priv->grid_line_gc)
-    {
-      g_object_unref (priv->grid_line_gc);
-      priv->grid_line_gc = NULL;
-    }
-
   GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->unrealize (widget);
 }
 
@@ -1956,8 +1956,8 @@ gtk_tree_view_size_request_columns (GtkTreeView *tree_view)
            continue;
 
           column = list->data;
-         
-          gtk_widget_size_request (column->button, &requisition);
+
+          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);
         }
@@ -2041,17 +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_widget_size_request (child->widget, &child_requisition);
-    }
+  *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
@@ -2094,14 +2107,16 @@ invalidate_column (GtkTreeView       *tree_view,
       GtkTreeViewColumn *tmpcolumn = list->data;
       if (tmpcolumn == column)
        {
+          GtkAllocation allocation;
          GdkRectangle invalid_rect;
-         
+
+          gtk_widget_get_allocation (widget, &allocation);
          invalid_rect.x = column_offset;
          invalid_rect.y = 0;
          invalid_rect.width = column->width;
-         invalid_rect.height = widget->allocation.height;
-         
-         gdk_window_invalidate_rect (widget->window, &invalid_rect, TRUE);
+         invalid_rect.height = allocation.height;
+
+         gdk_window_invalidate_rect (gtk_widget_get_window (widget), &invalid_rect, TRUE);
          break;
        }
       
@@ -2171,6 +2186,7 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget,
   GList *list, *first_column, *last_column;
   GtkTreeViewColumn *column;
   GtkAllocation allocation;
+  GtkAllocation widget_allocation;
   gint width = 0;
   gint extra, extra_per_column, extra_for_last;
   gint full_requested_width = 0;
@@ -2224,14 +2240,15 @@ gtk_tree_view_size_allocate_columns (GtkWidget *widget,
 
   tree_view->priv->post_validation_flag = FALSE;
 
+  gtk_widget_get_allocation (widget, &widget_allocation);
   if (!update_expand)
     {
       extra = tree_view->priv->last_extra_space;
-      extra_for_last = MAX (widget->allocation.width - full_requested_width - extra, 0);
+      extra_for_last = MAX (widget_allocation.width - full_requested_width - extra, 0);
     }
   else
     {
-      extra = MAX (widget->allocation.width - full_requested_width, 0);
+      extra = MAX (widget_allocation.width - full_requested_width, 0);
       extra_for_last = 0;
 
       tree_view->priv->last_extra_space = extra;
@@ -2266,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;
@@ -2342,15 +2359,18 @@ static void
 gtk_tree_view_size_allocate (GtkWidget     *widget,
                             GtkAllocation *allocation)
 {
+  GtkAllocation widget_allocation;
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
   GList *tmp_list;
   gboolean width_changed = FALSE;
-  gint old_width = widget->allocation.width;
+  gint old_width;
 
-  if (allocation->width != widget->allocation.width)
+  gtk_widget_get_allocation (widget, &widget_allocation);
+  old_width = widget_allocation.width;
+  if (allocation->width != widget_allocation.width)
     width_changed = TRUE;
 
-  widget->allocation = *allocation;
+  gtk_widget_set_allocation (widget, allocation);
 
   tmp_list = tree_view->priv->children;
 
@@ -2374,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)   
     {
@@ -2386,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)
@@ -2429,7 +2470,7 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
   
   if (gtk_widget_get_realized (widget))
     {
-      gdk_window_move_resize (widget->window,
+      gdk_window_move_resize (gtk_widget_get_window (widget),
                              allocation->x, allocation->y,
                              allocation->width, allocation->height);
       gdk_window_move_resize (tree_view->priv->header_window,
@@ -2589,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);
@@ -2883,6 +2922,7 @@ gtk_tree_view_button_press (GtkWidget      *widget,
          column->resizable &&
          column->window)
        {
+          GtkAllocation button_allocation;
          gpointer drag_data;
 
          if (event->type == GDK_2BUTTON_PRESS &&
@@ -2912,8 +2952,9 @@ gtk_tree_view_button_press (GtkWidget      *widget,
                                             0, 0, NULL, NULL,
                                             drag_data);
 
+          gtk_widget_get_allocation (column->button, &button_allocation);
          tree_view->priv->drag_pos = i;
-         tree_view->priv->x_drag = column->button->allocation.x + (rtl ? 0 : column->button->allocation.width);
+         tree_view->priv->x_drag = button_allocation.x + (rtl ? 0 : button_allocation.width);
 
          if (!gtk_widget_has_focus (widget))
            gtk_widget_grab_focus (widget);
@@ -3011,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;
 }
@@ -3198,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);
            }
        }
 
@@ -3217,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,
@@ -3248,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);
@@ -3371,7 +3410,8 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
 {
   GtkTreeViewColumnReorder *reorder = tree_view->priv->cur_reorder;
   GtkWidget *widget = GTK_WIDGET (tree_view);
-  GdkBitmap *mask = NULL;
+  cairo_surface_t *mask_image;
+  cairo_region_t *mask_region;
   gint x;
   gint y;
   gint width;
@@ -3379,6 +3419,7 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
   gint arrow_type = DRAG_COLUMN_WINDOW_STATE_UNSET;
   GdkWindowAttr attributes;
   guint attributes_mask;
+  cairo_t *cr;
 
   if (!reorder ||
       reorder->left_column == tree_view->priv->drag_column ||
@@ -3386,12 +3427,20 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
     arrow_type = DRAG_COLUMN_WINDOW_STATE_ORIGINAL;
   else if (reorder->left_column || reorder->right_column)
     {
+      GtkAllocation left_allocation, right_allocation;
       GdkRectangle visible_rect;
+
       gtk_tree_view_get_visible_rect (tree_view, &visible_rect);
       if (reorder->left_column)
-       x = reorder->left_column->button->allocation.x + reorder->left_column->button->allocation.width;
+        {
+          gtk_widget_get_allocation (reorder->left_column->button, &left_allocation);
+          x = left_allocation.x + left_allocation.width;
+        }
       else
-       x = reorder->right_column->button->allocation.x;
+        {
+          gtk_widget_get_allocation (reorder->right_column->button, &right_allocation);
+          x = right_allocation.x;
+        }
 
       if (x < visible_rect.x)
        arrow_type = DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT;
@@ -3404,11 +3453,10 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
   /* We want to draw the rectangle over the initial location. */
   if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ORIGINAL)
     {
-      GdkGC *gc;
-      GdkColor col;
-
       if (tree_view->priv->drag_column_window_state != DRAG_COLUMN_WINDOW_STATE_ORIGINAL)
        {
+          GtkAllocation drag_allocation;
+
          if (tree_view->priv->drag_highlight_window)
            {
              gdk_window_set_user_data (tree_view->priv->drag_highlight_window,
@@ -3420,36 +3468,35 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
          attributes.wclass = GDK_INPUT_OUTPUT;
           attributes.x = tree_view->priv->drag_column_x;
           attributes.y = 0;
-         width = attributes.width = tree_view->priv->drag_column->button->allocation.width;
-         height = attributes.height = tree_view->priv->drag_column->button->allocation.height;
+          gtk_widget_get_allocation (tree_view->priv->drag_column->button, &drag_allocation);
+         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));
 
-         mask = gdk_pixmap_new (tree_view->priv->drag_highlight_window, width, height, 1);
-         gc = gdk_gc_new (mask);
-         col.pixel = 1;
-         gdk_gc_set_foreground (gc, &col);
-         gdk_draw_rectangle (mask, gc, TRUE, 0, 0, width, height);
-         col.pixel = 0;
-         gdk_gc_set_foreground(gc, &col);
-         gdk_draw_rectangle (mask, gc, TRUE, 2, 2, width - 4, height - 4);
-         g_object_unref (gc);
-
-         gdk_window_shape_combine_mask (tree_view->priv->drag_highlight_window,
-                                        mask, 0, 0);
-         if (mask) g_object_unref (mask);
+         mask_image = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height);
+          cr = cairo_create (mask_image);
+
+          cairo_rectangle (cr, 1, 1, width - 2, height - 2);
+          cairo_stroke (cr);
+          cairo_destroy (cr);
+
+          mask_region = gdk_cairo_region_create_from_surface (mask_image);
+         gdk_window_shape_combine_region (tree_view->priv->drag_highlight_window,
+                                          mask_region, 0, 0);
+
+          cairo_region_destroy (mask_region);
+          cairo_surface_destroy (mask_image);
+
          tree_view->priv->drag_column_window_state = DRAG_COLUMN_WINDOW_STATE_ORIGINAL;
        }
     }
   else if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW)
     {
-      gint i, j = 1;
-      GdkGC *gc;
-      GdkColor col;
+      GtkAllocation button_allocation;
 
       width = tree_view->priv->expander_size;
 
@@ -3457,13 +3504,15 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
       gdk_window_get_origin (tree_view->priv->header_window, &x, &y);
       if (reorder->left_column)
        {
-         x += reorder->left_column->button->allocation.x + reorder->left_column->button->allocation.width - width/2;
-         height = reorder->left_column->button->allocation.height;
+          gtk_widget_get_allocation (reorder->left_column->button, &button_allocation);
+         x += button_allocation.x + button_allocation.width - width/2;
+         height = button_allocation.height;
        }
       else
        {
-         x += reorder->right_column->button->allocation.x - width/2;
-         height = reorder->right_column->button->allocation.height;
+          gtk_widget_get_allocation (reorder->right_column->button, &button_allocation);
+         x += button_allocation.x - width/2;
+         height = button_allocation.height;
        }
       y -= tree_view->priv->expander_size/2; /* The arrow takes up only half the space */
       height += tree_view->priv->expander_size;
@@ -3481,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;
@@ -3492,29 +3540,24 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
                                                                   &attributes, attributes_mask);
          gdk_window_set_user_data (tree_view->priv->drag_highlight_window, GTK_WIDGET (tree_view));
 
-         mask = gdk_pixmap_new (tree_view->priv->drag_highlight_window, width, height, 1);
-         gc = gdk_gc_new (mask);
-         col.pixel = 1;
-         gdk_gc_set_foreground (gc, &col);
-         gdk_draw_rectangle (mask, gc, TRUE, 0, 0, width, height);
+         mask_image = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height);
 
-         /* Draw the 2 arrows as per above */
-         col.pixel = 0;
-         gdk_gc_set_foreground (gc, &col);
-         for (i = 0; i < width; i ++)
-           {
-             if (i == (width/2 - 1))
-               continue;
-             gdk_draw_line (mask, gc, i, j, i, height - j);
-             if (i < (width/2 - 1))
-               j++;
-             else
-               j--;
-           }
-         g_object_unref (gc);
-         gdk_window_shape_combine_mask (tree_view->priv->drag_highlight_window,
-                                        mask, 0, 0);
-         if (mask) g_object_unref (mask);
+          cr = cairo_create (mask_image);
+          cairo_move_to (cr, 0, 0);
+          cairo_line_to (cr, width, 0);
+          cairo_line_to (cr, width / 2., width / 2);
+          cairo_move_to (cr, 0, height);
+          cairo_line_to (cr, width, height);
+          cairo_line_to (cr, width / 2., height - width / 2.);
+          cairo_fill (cr);
+          cairo_destroy (cr);
+
+          mask_region = gdk_cairo_region_create_from_surface (mask_image);
+         gdk_window_shape_combine_region (tree_view->priv->drag_highlight_window,
+                                          mask_region, 0, 0);
+
+          cairo_region_destroy (mask_region);
+          cairo_surface_destroy (mask_image);
        }
 
       tree_view->priv->drag_column_window_state = DRAG_COLUMN_WINDOW_STATE_ARROW;
@@ -3523,22 +3566,30 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
   else if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT ||
           arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT)
     {
-      gint i, j = 1;
-      GdkGC *gc;
-      GdkColor col;
+      GtkAllocation allocation;
 
       width = tree_view->priv->expander_size;
 
       /* Get x, y, width, height of arrow */
       width = width/2; /* remember, the arrow only takes half the available width */
-      gdk_window_get_origin (widget->window, &x, &y);
+      gdk_window_get_origin (gtk_widget_get_window (widget),
+                             &x, &y);
       if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT)
-       x += widget->allocation.width - width;
+        {
+          gtk_widget_get_allocation (widget, &allocation);
+          x += allocation.width - width;
+        }
 
       if (reorder->left_column)
-       height = reorder->left_column->button->allocation.height;
+        {
+          gtk_widget_get_allocation (reorder->left_column->button, &allocation);
+          height = allocation.height;
+        }
       else
-       height = reorder->right_column->button->allocation.height;
+        {
+          gtk_widget_get_allocation (reorder->right_column->button, &allocation);
+          height = allocation.height;
+        }
 
       y -= tree_view->priv->expander_size;
       height += 2*tree_view->priv->expander_size;
@@ -3557,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;
@@ -3567,32 +3617,30 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
          tree_view->priv->drag_highlight_window = gdk_window_new (NULL, &attributes, attributes_mask);
          gdk_window_set_user_data (tree_view->priv->drag_highlight_window, GTK_WIDGET (tree_view));
 
-         mask = gdk_pixmap_new (tree_view->priv->drag_highlight_window, width, height, 1);
-         gc = gdk_gc_new (mask);
-         col.pixel = 1;
-         gdk_gc_set_foreground (gc, &col);
-         gdk_draw_rectangle (mask, gc, TRUE, 0, 0, width, height);
-
-         /* Draw the 2 arrows as per above */
-         col.pixel = 0;
-         gdk_gc_set_foreground (gc, &col);
-         j = tree_view->priv->expander_size;
-         for (i = 0; i < width; i ++)
-           {
-             gint k;
-             if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT)
-               k = width - i - 1;
-             else
-               k = i;
-             gdk_draw_line (mask, gc, k, j, k, height - j);
-             gdk_draw_line (mask, gc, k, 0, k, tree_view->priv->expander_size - j);
-             gdk_draw_line (mask, gc, k, height, k, height - tree_view->priv->expander_size + j);
-             j--;
-           }
-         g_object_unref (gc);
-         gdk_window_shape_combine_mask (tree_view->priv->drag_highlight_window,
-                                        mask, 0, 0);
-         if (mask) g_object_unref (mask);
+         mask_image = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height);
+
+          cr = cairo_create (mask_image);
+          /* mirror if we're on the left */
+          if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT)
+            {
+              cairo_translate (cr, width, 0);
+              cairo_scale (cr, -1, 1);
+            }
+          cairo_move_to (cr, 0, 0);
+          cairo_line_to (cr, width, width);
+          cairo_line_to (cr, 0, tree_view->priv->expander_size);
+          cairo_move_to (cr, 0, height);
+          cairo_line_to (cr, width, height - width);
+          cairo_line_to (cr, 0, height - tree_view->priv->expander_size);
+          cairo_fill (cr);
+          cairo_destroy (cr);
+
+          mask_region = gdk_cairo_region_create_from_surface (mask_image);
+         gdk_window_shape_combine_region (tree_view->priv->drag_highlight_window,
+                                          mask_region, 0, 0);
+
+          cairo_region_destroy (mask_region);
+          cairo_surface_destroy (mask_image);
        }
 
       tree_view->priv->drag_column_window_state = arrow_type;
@@ -3620,7 +3668,7 @@ gtk_tree_view_motion_resize_column (GtkWidget      *widget,
 
   column = gtk_tree_view_get_column (tree_view, tree_view->priv->drag_pos);
 
-  if (event->is_hint || event->window != widget->window)
+  if (event->is_hint || event->window != gtk_widget_get_window (widget))
     gtk_widget_get_pointer (widget, &x, NULL);
   else
     x = event->x;
@@ -3673,7 +3721,6 @@ gtk_tree_view_vertical_autoscroll (GtkTreeView *tree_view)
   GdkRectangle visible_rect;
   gint y;
   gint offset;
-  gfloat value;
 
   gdk_window_get_pointer (tree_view->priv->bin_window, NULL, &y, NULL);
   y += tree_view->priv->dy;
@@ -3689,9 +3736,8 @@ gtk_tree_view_vertical_autoscroll (GtkTreeView *tree_view)
        return;
     }
 
-  value = CLAMP (tree_view->priv->vadjustment->value + offset, 0.0,
-                tree_view->priv->vadjustment->upper - tree_view->priv->vadjustment->page_size);
-  gtk_adjustment_set_value (tree_view->priv->vadjustment, value);
+  gtk_adjustment_set_value (tree_view->priv->vadjustment,
+                            MAX (tree_view->priv->vadjustment->value + offset, 0.0));
 }
 
 static gboolean
@@ -3700,7 +3746,6 @@ gtk_tree_view_horizontal_autoscroll (GtkTreeView *tree_view)
   GdkRectangle visible_rect;
   gint x;
   gint offset;
-  gfloat value;
 
   gdk_window_get_pointer (tree_view->priv->bin_window, &x, NULL, NULL);
 
@@ -3716,9 +3761,8 @@ gtk_tree_view_horizontal_autoscroll (GtkTreeView *tree_view)
     }
   offset = offset/3;
 
-  value = CLAMP (tree_view->priv->hadjustment->value + offset,
-                0.0, tree_view->priv->hadjustment->upper - tree_view->priv->hadjustment->page_size);
-  gtk_adjustment_set_value (tree_view->priv->hadjustment, value);
+  gtk_adjustment_set_value (tree_view->priv->hadjustment,
+                            MAX (tree_view->priv->hadjustment->value + offset, 0.0));
 
   return TRUE;
 
@@ -3728,6 +3772,7 @@ static gboolean
 gtk_tree_view_motion_drag_column (GtkWidget      *widget,
                                  GdkEventMotion *event)
 {
+  GtkAllocation allocation, button_allocation;
   GtkTreeView *tree_view = (GtkTreeView *) widget;
   GtkTreeViewColumn *column = tree_view->priv->drag_column;
   gint x, y;
@@ -3739,8 +3784,10 @@ gtk_tree_view_motion_drag_column (GtkWidget      *widget,
 
   /* Handle moving the header */
   gdk_window_get_position (tree_view->priv->drag_window, &x, &y);
+  gtk_widget_get_allocation (widget, &allocation);
+  gtk_widget_get_allocation (column->button, &button_allocation);
   x = CLAMP (x + (gint)event->x - column->drag_x, 0,
-            MAX (tree_view->priv->width, GTK_WIDGET (tree_view)->allocation.width) - column->button->allocation.width);
+            MAX (tree_view->priv->width, allocation.width) - button_allocation.width);
   gdk_window_move (tree_view->priv->drag_window, x, y);
   
   /* autoscroll, if needed */
@@ -4008,7 +4055,7 @@ gtk_tree_view_update_rubber_band (GtkTreeView *tree_view)
   GdkRectangle old_area;
   GdkRectangle new_area;
   GdkRectangle common;
-  GdkRegion *invalid_region;
+  cairo_region_t *invalid_region;
 
   old_area.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x);
   old_area.y = MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y) - tree_view->priv->dy;
@@ -4025,13 +4072,13 @@ gtk_tree_view_update_rubber_band (GtkTreeView *tree_view)
   new_area.width = ABS (x - tree_view->priv->press_start_x) + 1;
   new_area.height = ABS (y - tree_view->priv->press_start_y) + 1;
 
-  invalid_region = gdk_region_rectangle (&old_area);
-  gdk_region_union_with_rect (invalid_region, &new_area);
+  invalid_region = cairo_region_create_rectangle (&old_area);
+  cairo_region_union_rectangle (invalid_region, &new_area);
 
   gdk_rectangle_intersect (&old_area, &new_area, &common);
   if (common.width > 2 && common.height > 2)
     {
-      GdkRegion *common_region;
+      cairo_region_t *common_region;
 
       /* make sure the border is invalidated */
       common.x += 1;
@@ -4039,15 +4086,15 @@ gtk_tree_view_update_rubber_band (GtkTreeView *tree_view)
       common.width -= 2;
       common.height -= 2;
 
-      common_region = gdk_region_rectangle (&common);
+      common_region = cairo_region_create_rectangle (&common);
 
-      gdk_region_subtract (invalid_region, common_region);
-      gdk_region_destroy (common_region);
+      cairo_region_subtract (invalid_region, common_region);
+      cairo_region_destroy (common_region);
     }
 
   gdk_window_invalidate_region (tree_view->priv->bin_window, invalid_region, TRUE);
 
-  gdk_region_destroy (invalid_region);
+  cairo_region_destroy (invalid_region);
 
   tree_view->priv->rubber_band_x = x;
   tree_view->priv->rubber_band_y = y;
@@ -4057,44 +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)
 {
-  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);
 
-  cairo_set_source_rgba (cr,
-                        GTK_WIDGET (tree_view)->style->fg[GTK_STATE_NORMAL].red / 65535.,
-                        GTK_WIDGET (tree_view)->style->fg[GTK_STATE_NORMAL].green / 65535.,
-                        GTK_WIDGET (tree_view)->style->fg[GTK_STATE_NORMAL].blue / 65535.,
-                        .25);
+  style = gtk_widget_get_style (GTK_WIDGET (tree_view));
+
+  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,
-                       GTK_WIDGET (tree_view)->style->fg[GTK_STATE_NORMAL].red / 65535.,
-                       GTK_WIDGET (tree_view)->style->fg[GTK_STATE_NORMAL].green / 65535.,
-                       GTK_WIDGET (tree_view)->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
@@ -4185,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);
 }
 
@@ -4193,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;
@@ -4201,24 +4239,73 @@ 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);
 }
 
+typedef enum {
+  GTK_TREE_VIEW_GRID_LINE,
+  GTK_TREE_VIEW_TREE_LINE,
+  GTK_TREE_VIEW_FOREGROUND_LINE
+} GtkTreeViewLineType;
+
+static void
+gtk_tree_view_draw_line (GtkTreeView         *tree_view,
+                         cairo_t             *cr,
+                         GtkTreeViewLineType  type,
+                         int                  x1,
+                         int                  y1,
+                         int                  x2,
+                         int                  y2)
+{
+  cairo_save (cr);
+
+  switch (type)
+    {
+    case GTK_TREE_VIEW_TREE_LINE:
+      cairo_set_source_rgb (cr, 0, 0, 0);
+      cairo_set_line_width (cr, tree_view->priv->tree_line_width);
+      if (tree_view->priv->tree_line_dashes[0])
+        cairo_set_dash (cr, 
+                        tree_view->priv->tree_line_dashes,
+                        2, 0.5);
+      break;
+    case GTK_TREE_VIEW_GRID_LINE:
+      cairo_set_source_rgb (cr, 0, 0, 0);
+      cairo_set_line_width (cr, tree_view->priv->grid_line_width);
+      if (tree_view->priv->grid_line_dashes[0])
+        cairo_set_dash (cr, 
+                        tree_view->priv->grid_line_dashes,
+                        2, 0.5);
+      break;
+    default:
+      g_assert_not_reached ();
+      /* fall through */
+    case GTK_TREE_VIEW_FOREGROUND_LINE:
+      cairo_set_line_width (cr, 1.0);
+      gdk_cairo_set_source_color (cr,
+                                  &gtk_widget_get_style (GTK_WIDGET (tree_view))->fg[gtk_widget_get_state (GTK_WIDGET (tree_view))]);
+      break;
+    }
+
+  cairo_move_to (cr, x1 + 0.5, y1 + 0.5);
+  cairo_line_to (cr, x2 + 0.5, y2 + 0.5);
+  cairo_stroke (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;
@@ -4243,10 +4330,10 @@ gtk_tree_view_draw_grid_lines (GtkTreeView    *tree_view,
 
       current_x += column->width;
 
-      gdk_draw_line (event->window,
-                    tree_view->priv->grid_line_gc,
-                    current_x - 1, 0,
-                    current_x - 1, tree_view->priv->height);
+      gtk_tree_view_draw_line (tree_view, cr,
+                               GTK_TREE_VIEW_GRID_LINE,
+                               current_x - 1, 0,
+                               current_x - 1, tree_view->priv->height);
     }
 }
 
@@ -4257,11 +4344,12 @@ 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;
+  GtkStyle *style;
   GtkRBTree *tree;
   GList *list;
   GtkRBNode *node;
@@ -4276,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;
@@ -4294,7 +4383,6 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   gint pointer_x, pointer_y;
   gint grid_line_width;
   gboolean got_pointer = FALSE;
-  gboolean row_ending_details;
   gboolean draw_vgrid_lines, draw_hgrid_lines;
 
   rtl = (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL);
@@ -4304,36 +4392,35 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                        "vertical-separator", &vertical_separator,
                        "allow-rules", &allow_rules,
                        "focus-line-width", &focus_line_width,
-                       "row-ending-details", &row_ending_details,
                        NULL);
 
   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;
+  style = gtk_widget_get_style (widget);
 
-  validate_visible_area (tree_view);
+  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, event->area.y);
+  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 (widget->style,
-                          event->window,
-                          widget->state,
+      gtk_paint_flat_box (style,
+                          cr,
+                          gtk_widget_get_state (widget),
                           GTK_SHADOW_NONE,
-                          &event->area,
                           widget,
                           "cell_even",
                           0, tree_view->priv->height,
@@ -4421,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;
@@ -4458,13 +4545,14 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
        {
          GtkTreeViewColumn *column = list->data;
          const gchar *detail = NULL;
+         gchar new_detail[128];
          GtkStateType state;
 
          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;
@@ -4513,7 +4601,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
              cell_area.height -= grid_line_width;
            }
 
-         if (gdk_region_rect_in (event->region, &background_area) == GDK_OVERLAP_RECTANGLE_OUT)
+         if (!gdk_rectangle_intersect (&clip, &background_area, NULL))
            {
              cell_offset += column->width;
              continue;
@@ -4568,7 +4656,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
 
           g_assert (detail);
 
-         if (widget->state == GTK_STATE_INSENSITIVE)
+         if (gtk_widget_get_state (widget) == GTK_STATE_INSENSITIVE)
            state = GTK_STATE_INSENSITIVE;          
          else if (flags & GTK_CELL_RENDERER_SELECTED)
            state = GTK_STATE_SELECTED;
@@ -4576,68 +4664,31 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
            state = GTK_STATE_NORMAL;
 
          /* Draw background */
-         if (row_ending_details)
-           {
-             char new_detail[128];
-
-             is_first = (rtl ? !list->next : !list->prev);
-             is_last = (rtl ? !list->prev : !list->next);
+         is_first = (rtl ? !list->next : !list->prev);
+         is_last = (rtl ? !list->prev : !list->next);
 
-             /* (I don't like the snprintfs either, but couldn't find a
-              * less messy way).
-              */
-             if (is_first && is_last)
-               g_snprintf (new_detail, 127, "%s", detail);
-             else if (is_first)
-               g_snprintf (new_detail, 127, "%s_start", detail);
-             else if (is_last)
-               g_snprintf (new_detail, 127, "%s_end", detail);
-             else
-               g_snprintf (new_detail, 128, "%s_middle", detail);
-
-             gtk_paint_flat_box (widget->style,
-                                 event->window,
-                                 state,
-                                 GTK_SHADOW_NONE,
-                                 &event->area,
-                                 widget,
-                                 new_detail,
-                                 background_area.x,
-                                 background_area.y,
-                                 background_area.width,
-                                 background_area.height);
-           }
+         /* (I don't like the snprintfs either, but couldn't find a
+          * less messy way).
+          */
+         if (is_first && is_last)
+           g_snprintf (new_detail, 127, "%s", detail);
+         else if (is_first)
+           g_snprintf (new_detail, 127, "%s_start", detail);
+         else if (is_last)
+           g_snprintf (new_detail, 127, "%s_end", detail);
          else
-           {
-             gtk_paint_flat_box (widget->style,
-                                 event->window,
-                                 state,
-                                 GTK_SHADOW_NONE,
-                                 &event->area,
-                                 widget,
-                                 detail,
-                                 background_area.x,
-                                 background_area.y,
-                                 background_area.width,
-                                 background_area.height);
-           }
-
-         if (draw_hgrid_lines)
-           {
-             if (background_area.y > 0)
-               gdk_draw_line (event->window,
-                              tree_view->priv->grid_line_gc,
-                              background_area.x, background_area.y,
-                              background_area.x + background_area.width,
-                              background_area.y);
-
-             if (y_offset + max_height >= event->area.height)
-               gdk_draw_line (event->window,
-                              tree_view->priv->grid_line_gc,
-                              background_area.x, background_area.y + max_height,
-                              background_area.x + background_area.width,
-                              background_area.y + max_height);
-           }
+           g_snprintf (new_detail, 127, "%s_middle", detail);
+
+         gtk_paint_flat_box (style,
+                             cr,
+                             state,
+                             GTK_SHADOW_NONE,
+                             widget,
+                             new_detail,
+                             background_area.x,
+                             background_area.y,
+                             background_area.width,
+                             background_area.height);
 
          if (gtk_tree_view_is_expander_column (tree_view, column))
            {
@@ -4660,10 +4711,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
              expander_cell_width = cell_area.width;
 
              if (is_separator)
-               gtk_paint_hline (widget->style,
-                                event->window,
+               gtk_paint_hline (style,
+                                cr,
                                 state,
-                                &cell_area,
                                 widget,
                                 NULL,
                                 cell_area.x,
@@ -4671,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)
@@ -4687,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);
@@ -4695,10 +4745,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
          else
            {
              if (is_separator)
-               gtk_paint_hline (widget->style,
-                                event->window,
+               gtk_paint_hline (style,
+                                cr,
                                 state,
-                                &cell_area,
                                 widget,
                                 NULL,
                                 cell_area.x,
@@ -4706,13 +4755,29 @@ 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, 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 >= 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,
+                                        background_area.y + max_height);
+           }
+
          if (gtk_tree_view_is_expander_column (tree_view, column) &&
              tree_view->priv->tree_lines_enabled)
            {
@@ -4728,21 +4793,21 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
              if ((node->flags & GTK_RBNODE_IS_PARENT) == GTK_RBNODE_IS_PARENT
                  && depth > 1)
                {
-                 gdk_draw_line (event->window,
-                                tree_view->priv->tree_line_gc,
-                                x + tree_view->priv->expander_size * (depth - 1.5) * mult,
-                                y1,
-                                x + tree_view->priv->expander_size * (depth - 1.1) * mult,
-                                y1);
+                  gtk_tree_view_draw_line (tree_view, cr,
+                                           GTK_TREE_VIEW_TREE_LINE,
+                                           x + tree_view->priv->expander_size * (depth - 1.5) * mult,
+                                           y1,
+                                           x + tree_view->priv->expander_size * (depth - 1.1) * mult,
+                                           y1);
                }
              else if (depth > 1)
                {
-                 gdk_draw_line (event->window,
-                                tree_view->priv->tree_line_gc,
-                                x + tree_view->priv->expander_size * (depth - 1.5) * mult,
-                                y1,
-                                x + tree_view->priv->expander_size * (depth - 0.5) * mult,
-                                y1);
+                  gtk_tree_view_draw_line (tree_view, cr,
+                                           GTK_TREE_VIEW_TREE_LINE,
+                                           x + tree_view->priv->expander_size * (depth - 1.5) * mult,
+                                           y1,
+                                           x + tree_view->priv->expander_size * (depth - 0.5) * mult,
+                                           y1);
                }
 
              if (depth > 1)
@@ -4752,19 +4817,19 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                  GtkRBTree *tmp_tree;
 
                  if (!_gtk_rbtree_next (tree, node))
-                   gdk_draw_line (event->window,
-                                  tree_view->priv->tree_line_gc,
-                                  x + tree_view->priv->expander_size * (depth - 1.5) * mult,
-                                  y0,
-                                  x + tree_view->priv->expander_size * (depth - 1.5) * mult,
-                                  y1);
+                    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
-                   gdk_draw_line (event->window,
-                                  tree_view->priv->tree_line_gc,
-                                  x + tree_view->priv->expander_size * (depth - 1.5) * mult,
-                                  y0,
-                                  x + tree_view->priv->expander_size * (depth - 1.5) * mult,
-                                  y2);
+                    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,
+                                             y2);
 
                  tmp_node = tree->parent_node;
                  tmp_tree = tree->parent_tree;
@@ -4772,12 +4837,12 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                  for (i = depth - 2; i > 0; i--)
                    {
                      if (_gtk_rbtree_next (tmp_tree, tmp_node))
-                       gdk_draw_line (event->window,
-                                      tree_view->priv->tree_line_gc,
-                                      x + tree_view->priv->expander_size * (i - 0.5) * mult,
-                                      y0,
-                                      x + tree_view->priv->expander_size * (i - 0.5) * mult,
-                                      y2);
+                        gtk_tree_view_draw_line (tree_view, cr,
+                                                 GTK_TREE_VIEW_TREE_LINE,
+                                                 x + tree_view->priv->expander_size * (i - 0.5) * mult,
+                                                 y0,
+                                                 x + tree_view->priv->expander_size * (i - 0.5) * mult,
+                                                 y2);
 
                      tmp_node = tmp_tree->parent_node;
                      tmp_tree = tmp_tree->parent_tree;
@@ -4792,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);
            }
 
@@ -4809,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)
             {
@@ -4829,44 +4892,30 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
 
              if (tree == NULL)
                break;
-             gdk_drawable_get_size (tree_view->priv->bin_window,
-                                    &width, NULL);
-
-             if (row_ending_details)
-               gtk_paint_focus (widget->style,
-                                tree_view->priv->bin_window,
-                                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);
-             else
-               gtk_paint_focus (widget->style,
-                                tree_view->priv->bin_window,
-                                gtk_widget_get_state (widget),
-                                &event->area,
-                                widget,
-                                "treeview-drop-indicator",
-                                0, BACKGROUND_FIRST_PIXEL (tree_view, tree, node)
-                                - focus_line_width / 2,
-                                width, ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node))
-                                - focus_line_width + 1);
+
+             gtk_paint_focus (style,
+                              cr,
+                              gtk_widget_get_state (widget),
+                              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,
+                               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)
             {
-              gdk_draw_line (event->window,
-                             widget->style->fg_gc[gtk_widget_get_state (widget)],
-                             rtl ? highlight_x + expander_cell_width : highlight_x,
-                             highlight_y,
-                             rtl ? 0 : bin_window_width,
-                             highlight_y);
+              gtk_tree_view_draw_line (tree_view, cr,
+                                       GTK_TREE_VIEW_FOREGROUND_LINE,
+                                       rtl ? highlight_x + expander_cell_width : highlight_x,
+                                       highlight_y,
+                                       rtl ? 0 : bin_window_width,
+                                       highlight_y);
             }
         }
 
@@ -4876,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 =
@@ -4885,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;
@@ -4899,27 +4944,17 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
              tmp_height = ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node));
            }
 
-         if (row_ending_details)
-           gtk_paint_focus (widget->style,
-                            tree_view->priv->bin_window,
-                            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);
-         else
-           gtk_paint_focus (widget->style,
-                            tree_view->priv->bin_window,
-                            focus_rect_state,
-                            &event->area,
-                            widget,
-                            "treeview",
-                            0, tmp_y,
-                            width, tmp_height);
-       }
+         gtk_paint_focus (style,
+                          cr,
+                          focus_rect_state,
+                          widget,
+                          (is_first
+                           ? (is_last ? "treeview" : "treeview-left" )
+                           : (is_last ? "treeview-right" : "treeview-middle" )),
+                          0, tmp_y,
+                          gdk_window_get_width (tree_view->priv->bin_window),
+                           tmp_height);
+        }
 
       y_offset += max_height;
       if (node->children)
@@ -4979,25 +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);
-
- if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE)
-   {
-     GdkRectangle *rectangles;
-     gint n_rectangles;
-
-     gdk_region_get_rectangles (event->region,
-                               &rectangles,
-                               &n_rectangles);
+  gtk_tree_view_draw_grid_lines (tree_view, cr, n_visible_columns);
 
-     while (n_rectangles--)
-       gtk_tree_view_paint_rubber_band (tree_view, &rectangles[n_rectangles]);
-
-     g_free (rectangles);
-   }
+  if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE)
+    gtk_tree_view_paint_rubber_band (tree_view, cr);
 
   if (cursor_path)
     gtk_tree_path_free (cursor_path);
@@ -5009,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.
        */
@@ -5031,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;
       
@@ -5049,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;
 }
 
@@ -5281,7 +5310,7 @@ gtk_tree_view_key_press (GtkWidget   *widget,
 
   if (tree_view->priv->rubber_band_status)
     {
-      if (event->keyval == GDK_Escape)
+      if (event->keyval == GDK_KEY_Escape)
        gtk_tree_view_stop_rubber_band (tree_view);
 
       return TRUE;
@@ -5289,7 +5318,7 @@ gtk_tree_view_key_press (GtkWidget   *widget,
 
   if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG))
     {
-      if (event->keyval == GDK_Escape)
+      if (event->keyval == GDK_KEY_Escape)
        {
          tree_view->priv->cur_reorder = NULL;
          gtk_tree_view_button_release_drag_column (widget, NULL);
@@ -5316,8 +5345,8 @@ gtk_tree_view_key_press (GtkWidget   *widget,
 
       if (focus_column &&
           (event->state & GDK_SHIFT_MASK) && (event->state & GDK_MOD1_MASK) &&
-          (event->keyval == GDK_Left || event->keyval == GDK_KP_Left
-           || event->keyval == GDK_Right || event->keyval == GDK_KP_Right))
+          (event->keyval == GDK_KEY_Left || event->keyval == GDK_KEY_KP_Left
+           || event->keyval == GDK_KEY_Right || event->keyval == GDK_KEY_KP_Right))
         {
           GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (focus_column->data);
 
@@ -5327,11 +5356,14 @@ gtk_tree_view_key_press (GtkWidget   *widget,
               return TRUE;
             }
 
-          if (event->keyval == (rtl ? GDK_Right : GDK_Left)
-              || event->keyval == (rtl ? GDK_KP_Right : GDK_KP_Left))
+          if (event->keyval == (rtl ? GDK_KEY_Right : GDK_KEY_Left)
+              || event->keyval == (rtl ? GDK_KEY_KP_Right : GDK_KEY_KP_Left))
             {
+             GtkRequisition button_req;
               gint old_width = column->resized_width;
 
+             gtk_widget_get_preferred_size (column->button, &button_req, NULL);
+
               column->resized_width = MAX (column->resized_width,
                                            column->width);
               column->resized_width -= 2;
@@ -5339,11 +5371,13 @@ gtk_tree_view_key_press (GtkWidget   *widget,
                 column->resized_width = 0;
 
               if (column->min_width == -1)
-                column->resized_width = MAX (column->button->requisition.width,
+                column->resized_width = MAX (button_req.width,
                                              column->resized_width);
               else
-                column->resized_width = MAX (column->min_width,
-                                             column->resized_width);
+                {
+                  column->resized_width = MAX (column->min_width,
+                                               column->resized_width);
+                }
 
               if (column->max_width != -1)
                 column->resized_width = MIN (column->resized_width,
@@ -5356,8 +5390,8 @@ gtk_tree_view_key_press (GtkWidget   *widget,
               else
                 gtk_widget_error_bell (widget);
             }
-          else if (event->keyval == (rtl ? GDK_Left : GDK_Right)
-                   || event->keyval == (rtl ? GDK_KP_Left : GDK_KP_Right))
+          else if (event->keyval == (rtl ? GDK_KEY_Left : GDK_KEY_Right)
+                   || event->keyval == (rtl ? GDK_KEY_KP_Left : GDK_KEY_KP_Right))
             {
               gint old_width = column->resized_width;
 
@@ -5382,15 +5416,15 @@ gtk_tree_view_key_press (GtkWidget   *widget,
 
       if (focus_column &&
           (event->state & GDK_MOD1_MASK) &&
-          (event->keyval == GDK_Left || event->keyval == GDK_KP_Left
-           || event->keyval == GDK_Right || event->keyval == GDK_KP_Right
-           || event->keyval == GDK_Home || event->keyval == GDK_KP_Home
-           || event->keyval == GDK_End || event->keyval == GDK_KP_End))
+          (event->keyval == GDK_KEY_Left || event->keyval == GDK_KEY_KP_Left
+           || event->keyval == GDK_KEY_Right || event->keyval == GDK_KEY_KP_Right
+           || event->keyval == GDK_KEY_Home || event->keyval == GDK_KEY_KP_Home
+           || event->keyval == GDK_KEY_End || event->keyval == GDK_KEY_KP_End))
         {
           GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN (focus_column->data);
 
-          if (event->keyval == (rtl ? GDK_Right : GDK_Left)
-              || event->keyval == (rtl ? GDK_KP_Right : GDK_KP_Left))
+          if (event->keyval == (rtl ? GDK_KEY_Right : GDK_KEY_Left)
+              || event->keyval == (rtl ? GDK_KEY_KP_Right : GDK_KEY_KP_Left))
             {
               GtkTreeViewColumn *col;
               col = gtk_tree_view_get_drop_column (tree_view, column, DROP_LEFT);
@@ -5399,8 +5433,8 @@ gtk_tree_view_key_press (GtkWidget   *widget,
               else
                 gtk_widget_error_bell (widget);
             }
-          else if (event->keyval == (rtl ? GDK_Left : GDK_Right)
-                   || event->keyval == (rtl ? GDK_KP_Left : GDK_KP_Right))
+          else if (event->keyval == (rtl ? GDK_KEY_Left : GDK_KEY_Right)
+                   || event->keyval == (rtl ? GDK_KEY_KP_Left : GDK_KEY_KP_Right))
             {
               GtkTreeViewColumn *col;
               col = gtk_tree_view_get_drop_column (tree_view, column, DROP_RIGHT);
@@ -5409,7 +5443,7 @@ gtk_tree_view_key_press (GtkWidget   *widget,
               else
                 gtk_widget_error_bell (widget);
             }
-          else if (event->keyval == GDK_Home || event->keyval == GDK_KP_Home)
+          else if (event->keyval == GDK_KEY_Home || event->keyval == GDK_KEY_KP_Home)
             {
               GtkTreeViewColumn *col;
               col = gtk_tree_view_get_drop_column (tree_view, column, DROP_HOME);
@@ -5418,7 +5452,7 @@ gtk_tree_view_key_press (GtkWidget   *widget,
               else
                 gtk_widget_error_bell (widget);
             }
-          else if (event->keyval == GDK_End || event->keyval == GDK_KP_End)
+          else if (event->keyval == GDK_KEY_End || event->keyval == GDK_KEY_KP_End)
             {
               GtkTreeViewColumn *col;
               col = gtk_tree_view_get_drop_column (tree_view, column, DROP_END);
@@ -5462,7 +5496,7 @@ gtk_tree_view_key_press (GtkWidget   *widget,
       old_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (tree_view->priv->search_entry)));
       new_event = gdk_event_copy ((GdkEvent *) event);
       g_object_unref (((GdkEventKey *) new_event)->window);
-      ((GdkEventKey *) new_event)->window = g_object_ref (tree_view->priv->search_window->window);
+      ((GdkEventKey *) new_event)->window = g_object_ref (gtk_widget_get_window (tree_view->priv->search_window));
       gtk_widget_realize (tree_view->priv->search_window);
 
       popup_menu_id = g_signal_connect (tree_view->priv->search_entry, 
@@ -5495,7 +5529,9 @@ gtk_tree_view_key_press (GtkWidget   *widget,
       if (tree_view->priv->imcontext_changed ||    /* we're in a preedit */
          (retval && text_modified))               /* ...or the text was modified */
        {
-         if (gtk_tree_view_real_start_interactive_search (tree_view, FALSE))
+         if (gtk_tree_view_real_start_interactive_search (tree_view,
+                                                           gdk_event_get_device ((GdkEvent *) event),
+                                                           FALSE))
            {
              gtk_widget_grab_focus (GTK_WIDGET (tree_view));
              return TRUE;
@@ -5604,7 +5640,8 @@ gtk_tree_view_focus_out (GtkWidget     *widget,
 
   /* destroy interactive search dialog */
   if (tree_view->priv->search_window)
-    gtk_tree_view_search_dialog_hide (tree_view->priv->search_window, tree_view);
+    gtk_tree_view_search_dialog_hide (tree_view->priv->search_window, tree_view,
+                                      gdk_event_get_device ((GdkEvent *) event));
 
   return FALSE;
 }
@@ -5618,15 +5655,17 @@ gtk_tree_view_node_queue_redraw (GtkTreeView *tree_view,
                                 GtkRBTree   *tree,
                                 GtkRBNode   *node)
 {
+  GtkAllocation allocation;
   gint y;
 
   y = _gtk_rbtree_node_find_offset (tree, node)
     - tree_view->priv->vadjustment->value
     + TREE_VIEW_HEADER_HEIGHT (tree_view);
 
+  gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
   gtk_widget_queue_draw_area (GTK_WIDGET (tree_view),
                              0, y,
-                             GTK_WIDGET (tree_view)->allocation.width,
+                              allocation.width,
                              GTK_RBNODE_GET_HEIGHT (node));
 }
 
@@ -5784,6 +5823,7 @@ validate_row (GtkTreeView *tree_view,
 static void
 validate_visible_area (GtkTreeView *tree_view)
 {
+  GtkAllocation allocation;
   GtkTreePath *path = NULL;
   GtkTreePath *above_path = NULL;
   GtkTreeIter iter;
@@ -5802,7 +5842,8 @@ validate_visible_area (GtkTreeView *tree_view)
       tree_view->priv->scroll_to_path == NULL)
     return;
 
-  total_height = GTK_WIDGET (tree_view)->allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view);
+  gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
+  total_height = allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view);
 
   if (total_height == 0)
     return;
@@ -6126,7 +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_widget_size_request (GTK_WIDGET (tree_view), &requisition);
+      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);
@@ -6310,11 +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_widget_size_request (GTK_WIDGET (tree_view), &requisition);
+      /* 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);
@@ -6377,7 +6431,8 @@ do_presize_handler (GtkTreeView *tree_view)
     {
       GtkRequisition requisition;
 
-      gtk_widget_size_request (GTK_WIDGET (tree_view), &requisition);
+      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);
@@ -6415,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)
 {
@@ -7163,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);
@@ -7186,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);
 }
 
@@ -7764,7 +7832,7 @@ gtk_tree_view_header_focus (GtkTreeView      *tree_view,
   if (! GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_HEADERS_VISIBLE))
     return FALSE;
 
-  focus_child = GTK_CONTAINER (tree_view)->focus_child;
+  focus_child = gtk_container_get_focus_child (GTK_CONTAINER (tree_view));
 
   first_column = tree_view->priv->columns;
   while (first_column)
@@ -7956,7 +8024,7 @@ gtk_tree_view_focus (GtkWidget        *widget,
   if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_can_focus (widget))
     return FALSE;
 
-  focus_child = container->focus_child;
+  focus_child = gtk_container_get_focus_child (container);
 
   gtk_tree_view_stop_editing (GTK_TREE_VIEW (widget), FALSE);
   /* Case 1.  Headers currently have focus. */
@@ -7984,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;
     }
 
@@ -8013,14 +8080,16 @@ gtk_tree_view_style_set (GtkWidget *widget,
                         GtkStyle *previous_style)
 {
   GtkTreeView *tree_view = GTK_TREE_VIEW (widget);
+  GtkStyle *style;
   GList *list;
   GtkTreeViewColumn *column;
 
   if (gtk_widget_get_realized (widget))
     {
-      gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
-      gdk_window_set_background (tree_view->priv->bin_window, &widget->style->base[widget->state]);
-      gtk_style_set_background (widget->style, tree_view->priv->header_window, GTK_STATE_NORMAL);
+      style = gtk_widget_get_style (widget);
+      gdk_window_set_background (tree_view->priv->bin_window,
+                                 &style->base[gtk_widget_get_state (widget)]);
+      gtk_style_set_background (style, tree_view->priv->header_window, GTK_STATE_NORMAL);
 
       gtk_tree_view_set_grid_lines (tree_view, tree_view->priv->grid_lines);
       gtk_tree_view_set_enable_tree_lines (tree_view, tree_view->priv->tree_lines_enabled);
@@ -8063,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,
@@ -8872,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);
     }
@@ -8883,13 +8892,15 @@ gtk_tree_view_clamp_column_visible (GtkTreeView       *tree_view,
                                    GtkTreeViewColumn *column,
                                    gboolean           focus_to_cell)
 {
+  GtkAllocation allocation;
   gint x, width;
 
   if (column == NULL)
     return;
 
-  x = column->button->allocation.x;
-  width = column->button->allocation.width;
+  gtk_widget_get_allocation (column->button, &allocation);
+  x = allocation.x;
+  width = allocation.width;
 
   if (width > tree_view->priv->hadjustment->page_size)
     {
@@ -8936,11 +8947,7 @@ gtk_tree_view_clamp_column_visible (GtkTreeView       *tree_view,
            }
        }
 
-      gtk_adjustment_set_value (tree_view->priv->hadjustment,
-                               CLAMP (x,
-                                      tree_view->priv->hadjustment->lower,
-                                      tree_view->priv->hadjustment->upper
-                                      - tree_view->priv->hadjustment->page_size));
+      gtk_adjustment_set_value (tree_view->priv->hadjustment, x);
     }
   else
     {
@@ -9254,28 +9261,30 @@ gtk_tree_view_set_column_drag_info (GtkTreeView       *tree_view,
       reorder->left_align = left;
       if (tmp_list->next != NULL)
        {
+          GtkAllocation right_allocation, left_allocation;
+
          g_assert (tmp_list->next->data);
-         left = reorder->right_align = (reorder->right_column->button->allocation.x +
-                                        reorder->right_column->button->allocation.width +
-                                        ((GtkTreeViewColumnReorder *)tmp_list->next->data)->left_column->button->allocation.x)/2;
+
+          gtk_widget_get_allocation (reorder->right_column->button, &right_allocation);
+          gtk_widget_get_allocation (((GtkTreeViewColumnReorder *)tmp_list->next->data)->left_column->button, &left_allocation);
+         left = reorder->right_align = (right_allocation.x + right_allocation.width + left_allocation.x) / 2;
        }
       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);
        }
     }
 }
 
 void
 _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
-                                 GtkTreeViewColumn *column)
+                                 GtkTreeViewColumn *column,
+                                  GdkDevice         *device)
 {
   GdkEvent *send_event;
   GtkAllocation allocation;
-  gint x, y, width, height;
+  GtkAllocation button_allocation;
   GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (tree_view));
   GdkDisplay *display = gdk_screen_get_display (screen);
 
@@ -9292,16 +9301,17 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
       GdkWindowAttr attributes;
       guint attributes_mask;
 
+      gtk_widget_get_allocation (column->button, &button_allocation);
+
       attributes.window_type = GDK_WINDOW_CHILD;
       attributes.wclass = GDK_INPUT_OUTPUT;
-      attributes.x = column->button->allocation.x;
+      attributes.x = button_allocation.x;
       attributes.y = 0;
-      attributes.width = column->button->allocation.width;
-      attributes.height = column->button->allocation.height;
+      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,
@@ -9316,10 +9326,11 @@ _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;
+  gdk_event_set_device (send_event, device);
 
   gtk_propagate_event (column->button, send_event);
   gdk_event_free (send_event);
@@ -9333,9 +9344,9 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
   send_event->button.axes = NULL;
   send_event->button.state = 0;
   send_event->button.button = 1;
-  send_event->button.device = gdk_display_get_core_pointer (display);
   send_event->button.x_root = 0;
   send_event->button.y_root = 0;
+  gdk_event_set_device (send_event, device);
 
   gtk_propagate_event (column->button, send_event);
   gdk_event_free (send_event);
@@ -9347,8 +9358,9 @@ _gtk_tree_view_column_start_drag (GtkTreeView       *tree_view,
   gtk_widget_set_parent (column->button, GTK_WIDGET (tree_view));
   g_object_unref (column->button);
 
-  tree_view->priv->drag_column_x = column->button->allocation.x;
-  allocation = column->button->allocation;
+  gtk_widget_get_allocation (column->button, &button_allocation);
+  tree_view->priv->drag_column_x = button_allocation.x;
+  allocation = button_allocation;
   allocation.x = 0;
   gtk_widget_size_allocate (column->button, &allocation);
   gtk_widget_set_parent_window (column->button, tree_view->priv->drag_window);
@@ -9356,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 ();
@@ -9376,32 +9385,22 @@ _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;
 
   if (!gtk_widget_get_realized (GTK_WIDGET (tree_view)))
     return;
 
+  gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
   rect.x = 0;
-  rect.width = MAX (tree_view->priv->expander_size, MAX (tree_view->priv->width, GTK_WIDGET (tree_view)->allocation.width));
+  rect.width = MAX (tree_view->priv->expander_size, MAX (tree_view->priv->width, allocation.width));
 
   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
@@ -9410,13 +9409,15 @@ _gtk_tree_view_queue_draw_node (GtkTreeView        *tree_view,
                                GtkRBNode          *node,
                                const GdkRectangle *clip_rect)
 {
+  GtkAllocation allocation;
   GdkRectangle rect;
 
   if (!gtk_widget_get_realized (GTK_WIDGET (tree_view)))
     return;
 
+  gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
   rect.x = 0;
-  rect.width = MAX (tree_view->priv->width, GTK_WIDGET (tree_view)->allocation.width);
+  rect.width = MAX (tree_view->priv->width, allocation.width);
 
   rect.y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
   rect.height = ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node));
@@ -9453,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 */
@@ -9515,10 +9517,9 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
   else
     expander_style = GTK_EXPANDER_COLLAPSED;
 
-  gtk_paint_expander (widget->style,
-                      tree_view->priv->bin_window,
+  gtk_paint_expander (gtk_widget_get_style (widget),
+                      cr,
                       state,
-                      &area,
                       widget,
                       "treeview",
                      area.x + area.width / 2,
@@ -9779,6 +9780,13 @@ gtk_tree_view_move_cursor_page_up_down (GtkTreeView *tree_view,
     _gtk_rbtree_find_offset (tree_view->priv->tree, y,
                             &cursor_tree, &cursor_node);
 
+  if (cursor_tree == NULL)
+    {
+      /* FIXME: we lost the cursor.  Should we try to get one? */
+      gtk_tree_path_free (old_cursor_path);
+      return;
+    }
+
   if (tree_view->priv->cursor_offset > BACKGROUND_HEIGHT (cursor_node))
     {
       _gtk_rbtree_next_full (cursor_tree, cursor_node,
@@ -10255,7 +10263,7 @@ gtk_tree_view_real_select_cursor_parent (GtkTreeView *tree_view)
 static gboolean
 gtk_tree_view_search_entry_flush_timeout (GtkTreeView *tree_view)
 {
-  gtk_tree_view_search_dialog_hide (tree_view->priv->search_window, tree_view);
+  gtk_tree_view_search_dialog_hide (tree_view->priv->search_window, tree_view, NULL);
   tree_view->priv->typeselect_flush_timeout = 0;
 
   return FALSE;
@@ -10264,17 +10272,46 @@ gtk_tree_view_search_entry_flush_timeout (GtkTreeView *tree_view)
 /* Cut and paste from gtkwindow.c */
 static void
 send_focus_change (GtkWidget *widget,
+                   GdkDevice *device,
                   gboolean   in)
 {
-  GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
+  GdkDeviceManager *device_manager;
+  GList *devices, *d;
+
+  device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
+  devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
+  devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
+  devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
 
-  fevent->focus_change.type = GDK_FOCUS_CHANGE;
-  fevent->focus_change.window = g_object_ref (gtk_widget_get_window (widget));
-  fevent->focus_change.in = in;
+  for (d = devices; d; d = d->next)
+    {
+      GdkDevice *dev = d->data;
+      GdkEvent *fevent;
+      GdkWindow *window;
+
+      if (dev->source != GDK_SOURCE_KEYBOARD)
+        continue;
 
-  gtk_widget_send_focus_change (widget, fevent);
+      window = gtk_widget_get_window (widget);
 
-  gdk_event_free (fevent);
+      /* Skip non-master keyboards that haven't
+       * selected for events from this window
+       */
+      if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
+          !gdk_window_get_device_events (window, dev))
+        continue;
+
+      fevent = gdk_event_new (GDK_FOCUS_CHANGE);
+
+      fevent->focus_change.type = GDK_FOCUS_CHANGE;
+      fevent->focus_change.window = g_object_ref (window);
+      fevent->focus_change.in = in;
+      gdk_event_set_device (fevent, device);
+
+      gtk_widget_send_focus_change (widget, fevent);
+
+      gdk_event_free (fevent);
+    }
 }
 
 static void
@@ -10291,21 +10328,23 @@ gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view)
 
    if (tree_view->priv->search_window != NULL)
      {
-       if (GTK_WINDOW (toplevel)->group)
-        gtk_window_group_add_window (GTK_WINDOW (toplevel)->group,
-                                     GTK_WINDOW (tree_view->priv->search_window));
-       else if (GTK_WINDOW (tree_view->priv->search_window)->group)
-        gtk_window_group_remove_window (GTK_WINDOW (tree_view->priv->search_window)->group,
-                                        GTK_WINDOW (tree_view->priv->search_window));
+       if (gtk_window_has_group (GTK_WINDOW (toplevel)))
+         gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
+                                      GTK_WINDOW (tree_view->priv->search_window));
+       else if (gtk_window_has_group (GTK_WINDOW (tree_view->priv->search_window)))
+         gtk_window_group_remove_window (gtk_window_get_group (GTK_WINDOW (tree_view->priv->search_window)),
+                                         GTK_WINDOW (tree_view->priv->search_window));
+
        gtk_window_set_screen (GTK_WINDOW (tree_view->priv->search_window), screen);
+
        return;
      }
    
   tree_view->priv->search_window = gtk_window_new (GTK_WINDOW_POPUP);
   gtk_window_set_screen (GTK_WINDOW (tree_view->priv->search_window), screen);
 
-  if (GTK_WINDOW (toplevel)->group)
-    gtk_window_group_add_window (GTK_WINDOW (toplevel)->group,
+  if (gtk_window_has_group (GTK_WINDOW (toplevel)))
+    gtk_window_group_add_window (gtk_window_get_group (GTK_WINDOW (toplevel)),
                                 GTK_WINDOW (tree_view->priv->search_window));
 
   gtk_window_set_type_hint (GTK_WINDOW (tree_view->priv->search_window),
@@ -10329,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);
@@ -10358,6 +10397,7 @@ gtk_tree_view_ensure_interactive_directory (GtkTreeView *tree_view)
  */
 static gboolean
 gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view,
+                                             GdkDevice   *device,
                                             gboolean     keybinding)
 {
   /* We only start interactive search if we have focus or the columns
@@ -10430,7 +10470,7 @@ gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view,
   (entry_parent_class->grab_focus) (tree_view->priv->search_entry);
 
   /* send focus-in event */
-  send_focus_change (tree_view->priv->search_entry, TRUE);
+  send_focus_change (tree_view->priv->search_entry, device, TRUE);
 
   /* search first matching iter */
   gtk_tree_view_search_init (tree_view->priv->search_entry, tree_view);
@@ -10441,7 +10481,9 @@ gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view,
 static gboolean
 gtk_tree_view_start_interactive_search (GtkTreeView *tree_view)
 {
-  return gtk_tree_view_real_start_interactive_search (tree_view, TRUE);
+  return gtk_tree_view_real_start_interactive_search (tree_view,
+                                                      gtk_get_current_event_device (),
+                                                      TRUE);
 }
 
 /* this function returns the new width of the column being resized given
@@ -10453,7 +10495,9 @@ gtk_tree_view_new_column_width (GtkTreeView *tree_view,
                                gint       i,
                                gint      *x)
 {
+  GtkAllocation allocation;
   GtkTreeViewColumn *column;
+  GtkRequisition button_req;
   gint width;
   gboolean rtl;
 
@@ -10462,20 +10506,23 @@ gtk_tree_view_new_column_width (GtkTreeView *tree_view,
    */
   rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
   column = g_list_nth (tree_view->priv->columns, i)->data;
-  width = rtl ? (column->button->allocation.x + column->button->allocation.width - *x) : (*x - column->button->allocation.x);
+  gtk_widget_get_allocation (column->button, &allocation);
+  width = rtl ? (allocation.x + allocation.width - *x) : (*x - allocation.x);
+
   /* Clamp down the value */
   if (column->min_width == -1)
-    width = MAX (column->button->requisition.width,
-                width);
+    {
+      gtk_widget_get_preferred_size (column->button, &button_req, NULL);
+      width = MAX (button_req.width, width);
+    }
   else
     width = MAX (column->min_width,
                 width);
   if (column->max_width != -1)
     width = MIN (width, column->max_width);
 
-  *x = rtl ? (column->button->allocation.x + column->button->allocation.width - width) : (column->button->allocation.x + width);
+  *x = rtl ? (allocation.x + allocation.width - width) : (allocation.x + width);
+
   return width;
 }
 
@@ -10493,25 +10540,27 @@ typedef struct
 
 /* The window to which widget->window is relative */
 #define ALLOCATION_WINDOW(widget)              \
-   (!gtk_widget_get_has_window (widget) ?              \
-    (widget)->window :                          \
-     gdk_window_get_parent ((widget)->window))
+   (!gtk_widget_get_has_window (widget) ?                  \
+    gtk_widget_get_window (widget) :                        \
+    gdk_window_get_parent (gtk_widget_get_window (widget)))
 
 static void
 adjust_allocation_recurse (GtkWidget *widget,
                           gpointer   data)
 {
+  GtkAllocation allocation;
   ScrollData *scroll_data = data;
 
   /* Need to really size allocate instead of just poking
    * into widget->allocation if the widget is not realized.
    * FIXME someone figure out why this was.
    */
+  gtk_widget_get_allocation (widget, &allocation);
   if (!gtk_widget_get_realized (widget))
     {
       if (gtk_widget_get_visible (widget))
        {
-         GdkRectangle tmp_rectangle = widget->allocation;
+         GdkRectangle tmp_rectangle = allocation;
          tmp_rectangle.x += scroll_data->dx;
           tmp_rectangle.y += scroll_data->dy;
           
@@ -10522,9 +10571,10 @@ adjust_allocation_recurse (GtkWidget *widget,
     {
       if (ALLOCATION_WINDOW (widget) == scroll_data->window)
        {
-         widget->allocation.x += scroll_data->dx;
-          widget->allocation.y += scroll_data->dy;
-          
+         allocation.x += scroll_data->dx;
+          allocation.y += scroll_data->dy;
+          gtk_widget_set_allocation (widget, &allocation);
+
          if (GTK_IS_CONTAINER (widget))
            gtk_container_forall (GTK_CONTAINER (widget),
                                  adjust_allocation_recurse,
@@ -10606,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);
     }
 }
 
@@ -10652,7 +10702,7 @@ gtk_tree_view_new_with_model (GtkTreeModel *model)
  * Returns the model the #GtkTreeView is based on.  Returns %NULL if the
  * model is unset.
  *
- * Return value: A #GtkTreeModel, or %NULL if none is currently being used.
+ * Return value: (transfer none): A #GtkTreeModel, or %NULL if none is currently being used.
  **/
 GtkTreeModel *
 gtk_tree_view_get_model (GtkTreeView *tree_view)
@@ -10820,7 +10870,7 @@ gtk_tree_view_set_model (GtkTreeView  *tree_view,
  *
  * Gets the #GtkTreeSelection associated with @tree_view.
  *
- * Return value: A #GtkTreeSelection object.
+ * Return value: (transfer none): A #GtkTreeSelection object.
  **/
 GtkTreeSelection *
 gtk_tree_view_get_selection (GtkTreeView *tree_view)
@@ -10836,17 +10886,16 @@ gtk_tree_view_get_selection (GtkTreeView *tree_view)
  *
  * Gets the #GtkAdjustment currently being used for the horizontal aspect.
  *
- * Return value: A #GtkAdjustment object, or %NULL if none is currently being
- * used.
+ * 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;
 }
 
@@ -10856,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));
 
-  gtk_tree_view_set_adjustments (tree_view,
-                                adjustment,
-                                tree_view->priv->vadjustment);
+  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);
+    }
+
+  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");
 }
@@ -10876,17 +10949,16 @@ gtk_tree_view_set_hadjustment (GtkTreeView   *tree_view,
  *
  * Gets the #GtkAdjustment currently being used for the vertical aspect.
  *
- * Return value: A #GtkAdjustment object, or %NULL if none is currently being
- * used.
+ * 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;
 }
 
@@ -10896,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");
 }
 
@@ -10942,6 +11037,7 @@ gtk_tree_view_set_headers_visible (GtkTreeView *tree_view,
   gint x, y;
   GList *list;
   GtkTreeViewColumn *column;
+  GtkAllocation allocation;
 
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
@@ -10960,7 +11056,10 @@ gtk_tree_view_set_headers_visible (GtkTreeView *tree_view,
       gdk_window_get_position (tree_view->priv->bin_window, &x, &y);
       if (headers_visible)
        {
-         gdk_window_move_resize (tree_view->priv->bin_window, x, y  + TREE_VIEW_HEADER_HEIGHT (tree_view), tree_view->priv->width, GTK_WIDGET (tree_view)->allocation.height -  + TREE_VIEW_HEADER_HEIGHT (tree_view));
+          gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
+         gdk_window_move_resize (tree_view->priv->bin_window,
+                                  x, y  + TREE_VIEW_HEADER_HEIGHT (tree_view),
+                                  tree_view->priv->width, allocation.height -  + TREE_VIEW_HEADER_HEIGHT (tree_view));
 
           if (gtk_widget_get_mapped (GTK_WIDGET (tree_view)))
             gtk_tree_view_map_buttons (tree_view);
@@ -10978,8 +11077,9 @@ gtk_tree_view_set_headers_visible (GtkTreeView *tree_view,
        }
     }
 
-  tree_view->priv->vadjustment->page_size = GTK_WIDGET (tree_view)->allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view);
-  tree_view->priv->vadjustment->page_increment = (GTK_WIDGET (tree_view)->allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view)) / 2;
+  gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
+  tree_view->priv->vadjustment->page_size = allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view);
+  tree_view->priv->vadjustment->page_increment = (allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view)) / 2;
   tree_view->priv->vadjustment->lower = 0;
   tree_view->priv->vadjustment->upper = tree_view->priv->height;
   gtk_adjustment_changed (tree_view->priv->vadjustment);
@@ -11380,8 +11480,8 @@ gtk_tree_view_insert_column_with_data_func  (GtkTreeView               *tree_vie
  *
  * Gets the #GtkTreeViewColumn at the given position in the #tree_view.
  *
- * Return value: The #GtkTreeViewColumn, or %NULL if the position is outside the
- * range of columns.
+ * Return value: (transfer none): The #GtkTreeViewColumn, or %NULL if the
+ *     position is outside the range of columns.
  **/
 GtkTreeViewColumn *
 gtk_tree_view_get_column (GtkTreeView *tree_view,
@@ -11513,10 +11613,10 @@ gtk_tree_view_set_expander_column (GtkTreeView       *tree_view,
  * gtk_tree_view_get_expander_column:
  * @tree_view: A #GtkTreeView
  *
- * Returns the column that is the current expander column.  This
- * column has the expander arrow drawn next to it.
+ * Returns the column that is the current expander column.
+ * This column has the expander arrow drawn next to it.
  *
- * Return value: The expander column.
+ * Return value: (transfer none): The expander column.
  **/
 GtkTreeViewColumn *
 gtk_tree_view_get_expander_column (GtkTreeView *tree_view)
@@ -11594,9 +11694,9 @@ gtk_tree_view_scroll_to_point (GtkTreeView *tree_view,
   vadj = tree_view->priv->vadjustment;
 
   if (tree_x != -1)
-    gtk_adjustment_set_value (hadj, CLAMP (tree_x, hadj->lower, hadj->upper - hadj->page_size));
+    gtk_adjustment_set_value (hadj, tree_x);
   if (tree_y != -1)
-    gtk_adjustment_set_value (vadj, CLAMP (tree_y, vadj->lower, vadj->upper - vadj->page_size));
+    gtk_adjustment_set_value (vadj, tree_y);
 }
 
 /**
@@ -11654,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)
@@ -11911,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;
     }
@@ -12354,7 +12454,7 @@ gtk_tree_view_map_expanded_rows_helper (GtkTreeView            *tree_view,
 /**
  * gtk_tree_view_map_expanded_rows:
  * @tree_view: A #GtkTreeView
- * @func: A function to be called
+ * @func: (scope call): A function to be called
  * @data: User data to be passed to the function.
  *
  * Calls @func on all expanded rows.
@@ -12695,12 +12795,13 @@ gtk_tree_view_set_cursor_on_cell (GtkTreeView       *tree_view,
 /**
  * gtk_tree_view_get_bin_window:
  * @tree_view: A #GtkTreeView
- * 
- * Returns the window that @tree_view renders to.  This is used primarily to
- * compare to <literal>event->window</literal> to confirm that the event on
- * @tree_view is on the right window.
- * 
- * Return value: A #GdkWindow, or %NULL when @tree_view hasn't been realized yet
+ *
+ * Returns the window that @tree_view renders to.
+ * This is used primarily to compare to <literal>event->window</literal>
+ * to confirm that the event on @tree_view is on the right window.
+ *
+ * Return value: (transfer none): A #GdkWindow, or %NULL when @tree_view
+ *     hasn't been realized yet
  **/
 GdkWindow *
 gtk_tree_view_get_bin_window (GtkTreeView *tree_view)
@@ -12867,6 +12968,7 @@ gtk_tree_view_get_cell_area (GtkTreeView        *tree_view,
                              GtkTreeViewColumn  *column,
                              GdkRectangle       *rect)
 {
+  GtkAllocation allocation;
   GtkRBTree *tree = NULL;
   GtkRBNode *node = NULL;
   gint vertical_separator;
@@ -12890,8 +12992,9 @@ gtk_tree_view_get_cell_area (GtkTreeView        *tree_view,
 
   if (column)
     {
-      rect->x = column->button->allocation.x + horizontal_separator/2;
-      rect->width = column->button->allocation.width - horizontal_separator;
+      gtk_widget_get_allocation (column->button, &allocation);
+      rect->x = allocation.x + horizontal_separator/2;
+      rect->width = allocation.width - horizontal_separator;
     }
 
   if (path)
@@ -13002,6 +13105,7 @@ void
 gtk_tree_view_get_visible_rect (GtkTreeView  *tree_view,
                                 GdkRectangle *visible_rect)
 {
+  GtkAllocation allocation;
   GtkWidget *widget;
 
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
@@ -13010,10 +13114,11 @@ gtk_tree_view_get_visible_rect (GtkTreeView  *tree_view,
 
   if (visible_rect)
     {
+      gtk_widget_get_allocation (widget, &allocation);
       visible_rect->x = tree_view->priv->hadjustment->value;
       visible_rect->y = tree_view->priv->vadjustment->value;
-      visible_rect->width = widget->allocation.width;
-      visible_rect->height = widget->allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view);
+      visible_rect->width = allocation.width;
+      visible_rect->height = allocation.height - TREE_VIEW_HEADER_HEIGHT (tree_view);
     }
 }
 
@@ -13620,30 +13725,31 @@ 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: 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)
 {
   GtkTreeIter   iter;
   GtkRBTree    *tree;
   GtkRBNode    *node;
+  GtkStyle *style;
   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;
+  cairo_t *cr;
 
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
   g_return_val_if_fail (path != NULL, NULL);
@@ -13667,7 +13773,9 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
                                 &iter,
                                 path))
     return NULL;
-  
+
+  style = gtk_widget_get_style (widget);
+
   is_separator = row_is_separator (tree_view, &iter, NULL);
 
   cell_offset = x;
@@ -13675,25 +13783,16 @@ 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);
+  bin_window_width = gdk_window_get_width (tree_view->priv->bin_window);
 
-  drawable = gdk_pixmap_new (tree_view->priv->bin_window,
-                             bin_window_width + 2,
-                             background_area.height + 2,
-                             -1);
+  surface = gdk_window_create_similar_surface (tree_view->priv->bin_window,
+                                               CAIRO_CONTENT_COLOR,
+                                               bin_window_width + 2,
+                                               background_area.height + 2);
 
-  expose_area.x = 0;
-  expose_area.y = 0;
-  expose_area.width = bin_window_width + 2;
-  expose_area.height = background_area.height + 2;
-
-  gdk_draw_rectangle (drawable,
-                      widget->style->base_gc [gtk_widget_get_state (widget)],
-                      TRUE,
-                      0, 0,
-                      bin_window_width + 2,
-                      background_area.height + 2);
+  cr = cairo_create (surface);
+  gdk_cairo_set_source_color (cr, &style->base [gtk_widget_get_state (widget)]);
+  cairo_paint (cr);
 
   rtl = gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL;
 
@@ -13741,34 +13840,37 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
       if (gtk_tree_view_column_cell_is_visible (column))
        {
          if (is_separator)
-           gtk_paint_hline (widget->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);
+           gtk_paint_hline (style,
+                                   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;
     }
 
-  gdk_draw_rectangle (drawable,
-                      widget->style->black_gc,
-                      FALSE,
-                      0, 0,
-                      bin_window_width + 1,
-                      background_area.height + 1);
+  cairo_set_source_rgb (cr, 0, 0, 0);
+  cairo_rectangle (cr, 
+                   0.5, 0.5, 
+                   bin_window_width + 1,
+                   background_area.height + 1);
+  cairo_set_line_width (cr, 1.0);
+  cairo_stroke (cr);
 
-  return drawable;
+  cairo_destroy (cr);
+
+  cairo_surface_set_device_offset (surface, 2, 2);
+
+  return surface;
 }
 
 
@@ -13948,7 +14050,7 @@ gtk_tree_view_set_search_equal_func (GtkTreeView                *tree_view,
  * entry for @tree_view.  In case the built-in entry is being used, %NULL
  * will be returned.
  *
- * Return value: the entry currently in use as search entry.
+ * Return value: (transfer none): the entry currently in use as search entry.
  *
  * Since: 2.10
  */
@@ -14081,7 +14183,8 @@ gtk_tree_view_get_search_position_func (GtkTreeView *tree_view)
 
 static void
 gtk_tree_view_search_dialog_hide (GtkWidget   *search_dialog,
-                                 GtkTreeView *tree_view)
+                                 GtkTreeView *tree_view,
+                                  GdkDevice   *device)
 {
   if (tree_view->priv->disable_popdown)
     return;
@@ -14101,10 +14204,10 @@ gtk_tree_view_search_dialog_hide (GtkWidget   *search_dialog,
   if (gtk_widget_get_visible (search_dialog))
     {
       /* send focus-in event */
-      send_focus_change (GTK_WIDGET (tree_view->priv->search_entry), FALSE);
+      send_focus_change (GTK_WIDGET (tree_view->priv->search_entry), device, FALSE);
       gtk_widget_hide (search_dialog);
       gtk_entry_set_text (GTK_ENTRY (tree_view->priv->search_entry), "");
-      send_focus_change (GTK_WIDGET (tree_view), TRUE);
+      send_focus_change (GTK_WIDGET (tree_view), device, TRUE);
     }
 }
 
@@ -14116,8 +14219,8 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view,
   gint x, y;
   gint tree_x, tree_y;
   gint tree_width, tree_height;
-  GdkWindow *tree_window = GTK_WIDGET (tree_view)->window;
-  GdkScreen *screen = gdk_drawable_get_screen (tree_window);
+  GdkWindow *tree_window = gtk_widget_get_window (GTK_WIDGET (tree_view));
+  GdkScreen *screen = gdk_window_get_screen (tree_window);
   GtkRequisition requisition;
   gint monitor_num;
   GdkRectangle monitor;
@@ -14128,10 +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_widget_size_request (search_dialog, &requisition);
+  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;
@@ -14190,7 +14292,8 @@ gtk_tree_view_search_activate (GtkEntry    *entry,
   GtkRBTree *tree;
 
   gtk_tree_view_search_dialog_hide (tree_view->priv->search_window,
-                                   tree_view);
+                                   tree_view,
+                                    gtk_get_current_event_device ());
 
   /* If we have a row selected and it's the cursor row, we activate
    * the row XXX */
@@ -14231,7 +14334,7 @@ gtk_tree_view_search_delete_event (GtkWidget *widget,
 {
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
 
-  gtk_tree_view_search_dialog_hide (widget, tree_view);
+  gtk_tree_view_search_dialog_hide (widget, tree_view, NULL);
 
   return TRUE;
 }
@@ -14241,9 +14344,12 @@ gtk_tree_view_search_button_press_event (GtkWidget *widget,
                                         GdkEventButton *event,
                                         GtkTreeView *tree_view)
 {
+  GdkDevice *keyb_device;
+
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
 
-  gtk_tree_view_search_dialog_hide (widget, tree_view);
+  keyb_device = gdk_device_get_associated_device (event->device);
+  gtk_tree_view_search_dialog_hide (widget, tree_view, keyb_device);
 
   if (event->window == tree_view->priv->bin_window)
     gtk_tree_view_button_press (GTK_WIDGET (tree_view), event);
@@ -14295,17 +14401,18 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
 
   /* close window and cancel the search */
   if (!tree_view->priv->search_custom_entry_set
-      && (event->keyval == GDK_Escape ||
-          event->keyval == GDK_Tab ||
-           event->keyval == GDK_KP_Tab ||
-           event->keyval == GDK_ISO_Left_Tab))
+      && (event->keyval == GDK_KEY_Escape ||
+          event->keyval == GDK_KEY_Tab ||
+           event->keyval == GDK_KEY_KP_Tab ||
+           event->keyval == GDK_KEY_ISO_Left_Tab))
     {
-      gtk_tree_view_search_dialog_hide (widget, tree_view);
+      gtk_tree_view_search_dialog_hide (widget, tree_view,
+                                        gdk_event_get_device ((GdkEvent *) event));
       return TRUE;
     }
 
   /* select previous matching iter */
-  if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up)
+  if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_KP_Up)
     {
       if (!gtk_tree_view_search_move (widget, tree_view, TRUE))
         gtk_widget_error_bell (widget);
@@ -14314,7 +14421,7 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
     }
 
   if (((event->state & (GTK_DEFAULT_ACCEL_MOD_MASK | GDK_SHIFT_MASK)) == (GTK_DEFAULT_ACCEL_MOD_MASK | GDK_SHIFT_MASK))
-      && (event->keyval == GDK_g || event->keyval == GDK_G))
+      && (event->keyval == GDK_KEY_g || event->keyval == GDK_KEY_G))
     {
       if (!gtk_tree_view_search_move (widget, tree_view, TRUE))
         gtk_widget_error_bell (widget);
@@ -14323,7 +14430,7 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
     }
 
   /* select next matching iter */
-  if (event->keyval == GDK_Down || event->keyval == GDK_KP_Down)
+  if (event->keyval == GDK_KEY_Down || event->keyval == GDK_KEY_KP_Down)
     {
       if (!gtk_tree_view_search_move (widget, tree_view, FALSE))
         gtk_widget_error_bell (widget);
@@ -14332,7 +14439,7 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
     }
 
   if (((event->state & (GTK_DEFAULT_ACCEL_MOD_MASK | GDK_SHIFT_MASK)) == GTK_DEFAULT_ACCEL_MOD_MASK)
-      && (event->keyval == GDK_g || event->keyval == GDK_G))
+      && (event->keyval == GDK_KEY_g || event->keyval == GDK_KEY_G))
     {
       if (!gtk_tree_view_search_move (widget, tree_view, FALSE))
         gtk_widget_error_bell (widget);
@@ -14743,7 +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_widget_size_request (GTK_WIDGET (cell_editable), &requisition);
+  gtk_widget_get_preferred_size (GTK_WIDGET (cell_editable),
+                                 &requisition, NULL);
 
   GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
 
@@ -14977,7 +15085,7 @@ gtk_tree_view_get_row_separator_func (GtkTreeView *tree_view)
 /**
  * gtk_tree_view_set_row_separator_func:
  * @tree_view: a #GtkTreeView
- * @func: a #GtkTreeViewRowSeparatorFunc
+ * @func: (allow-none): a #GtkTreeViewRowSeparatorFunc
  * @data: (allow-none): user data to pass to @func, or %NULL
  * @destroy: (allow-none): destroy notifier for @data, or %NULL
  * 
@@ -15033,8 +15141,8 @@ gtk_tree_view_state_changed (GtkWidget      *widget,
 
   if (gtk_widget_get_realized (widget))
     {
-      gdk_window_set_back_pixmap (widget->window, NULL, FALSE);
-      gdk_window_set_background (tree_view->priv->bin_window, &widget->style->base[widget->state]);
+      gdk_window_set_background (tree_view->priv->bin_window,
+                                 &gtk_widget_get_style (widget)->base[gtk_widget_get_state (widget)]);
     }
 
   gtk_widget_queue_draw (widget);
@@ -15088,32 +15196,34 @@ gtk_tree_view_set_grid_lines (GtkTreeView           *tree_view,
   if (gtk_widget_get_realized (widget))
     {
       if (grid_lines == GTK_TREE_VIEW_GRID_LINES_NONE &&
-         priv->grid_line_gc)
+         priv->grid_line_width)
        {
-         g_object_unref (priv->grid_line_gc);
-         priv->grid_line_gc = NULL;
+         priv->grid_line_width = 0;
        }
       
       if (grid_lines != GTK_TREE_VIEW_GRID_LINES_NONE && 
-         !priv->grid_line_gc)
+         !priv->grid_line_width)
        {
-         gint line_width;
          gint8 *dash_list;
 
          gtk_widget_style_get (widget,
-                               "grid-line-width", &line_width,
+                               "grid-line-width", &priv->grid_line_width,
                                "grid-line-pattern", (gchar *)&dash_list,
                                NULL);
       
-         priv->grid_line_gc = gdk_gc_new (widget->window);
-         gdk_gc_copy (priv->grid_line_gc, widget->style->black_gc);
-         
-         gdk_gc_set_line_attributes (priv->grid_line_gc, line_width,
-                                     GDK_LINE_ON_OFF_DASH,
-                                     GDK_CAP_BUTT, GDK_JOIN_MITER);
-         gdk_gc_set_dashes (priv->grid_line_gc, 0, dash_list, 2);
-
-         g_free (dash_list);
+          if (dash_list)
+            {
+              priv->grid_line_dashes[0] = dash_list[0];
+              if (dash_list[0])
+                priv->grid_line_dashes[1] = dash_list[1];
+             
+              g_free (dash_list);
+            }
+          else
+            {
+              priv->grid_line_dashes[0] = 1;
+              priv->grid_line_dashes[1] = 1;
+            }
        }      
     }
 
@@ -15175,30 +15285,32 @@ gtk_tree_view_set_enable_tree_lines (GtkTreeView *tree_view,
 
   if (gtk_widget_get_realized (widget))
     {
-      if (!enabled && priv->tree_line_gc)
+      if (!enabled && priv->tree_line_width)
        {
-         g_object_unref (priv->tree_line_gc);
-         priv->tree_line_gc = NULL;
+          priv->tree_line_width = 0;
        }
       
-      if (enabled && !priv->tree_line_gc)
+      if (enabled && !priv->tree_line_width)
        {
-         gint line_width;
          gint8 *dash_list;
          gtk_widget_style_get (widget,
-                               "tree-line-width", &line_width,
+                               "tree-line-width", &priv->tree_line_width,
                                "tree-line-pattern", (gchar *)&dash_list,
                                NULL);
          
-         priv->tree_line_gc = gdk_gc_new (widget->window);
-         gdk_gc_copy (priv->tree_line_gc, widget->style->black_gc);
-         
-         gdk_gc_set_line_attributes (priv->tree_line_gc, line_width,
-                                     GDK_LINE_ON_OFF_DASH,
-                                     GDK_CAP_BUTT, GDK_JOIN_MITER);
-         gdk_gc_set_dashes (priv->tree_line_gc, 0, dash_list, 2);
-
-         g_free (dash_list);
+          if (dash_list)
+            {
+              priv->tree_line_dashes[0] = dash_list[0];
+              if (dash_list[0])
+                priv->tree_line_dashes[1] = dash_list[1];
+             
+              g_free (dash_list);
+            }
+          else
+            {
+              priv->tree_line_dashes[0] = 1;
+              priv->tree_line_dashes[1] = 1;
+            }
        }
     }
 
@@ -15359,6 +15471,7 @@ gtk_tree_view_set_tooltip_cell (GtkTreeView       *tree_view,
                                GtkTreeViewColumn *column,
                                GtkCellRenderer   *cell)
 {
+  GtkAllocation allocation;
   GdkRectangle rect;
 
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
@@ -15399,8 +15512,9 @@ gtk_tree_view_set_tooltip_cell (GtkTreeView       *tree_view,
     }
   else
     {
+      gtk_widget_get_allocation (GTK_WIDGET (tree_view), &allocation);
       rect.x = 0;
-      rect.width = GTK_WIDGET (tree_view)->allocation.width;
+      rect.width = allocation.width;
     }
 
   /* Determine y values. */
@@ -15429,9 +15543,9 @@ gtk_tree_view_set_tooltip_cell (GtkTreeView       *tree_view,
  * @x: the x coordinate (relative to widget coordinates)
  * @y: the y coordinate (relative to widget coordinates)
  * @keyboard_tip: whether this is a keyboard tooltip or not
- * @model: (allow-none): a pointer to receive a #GtkTreeModel or %NULL
- * @path: (allow-none): a pointer to receive a #GtkTreePath or %NULL
- * @iter: (allow-none): a pointer to receive a #GtkTreeIter or %NULL
+ * @model: (out) (allow-none): a pointer to receive a #GtkTreeModel or %NULL
+ * @path: (out) (allow-none): a pointer to receive a #GtkTreePath or %NULL
+ * @iter: (out) (allow-none): a pointer to receive a #GtkTreeIter or %NULL
  *
  * This function is supposed to be used in a #GtkWidget::query-tooltip
  * signal handler for #GtkTreeView.  The @x, @y and @keyboard_tip values
@@ -15616,6 +15730,3 @@ gtk_tree_view_get_tooltip_column (GtkTreeView *tree_view)
 
   return tree_view->priv->tooltip_column;
 }
-
-#define __GTK_TREE_VIEW_C__
-#include "gtkaliasdef.c"