diff -burp gtk+-2.18.4.org/gtk/gtkstyle.c gtk+-2.18.4/gtk/gtkstyle.c
--- gtk+-2.18.4.org/gtk/gtkstyle.c	2009-12-01 04:21:24.000000000 +0100
+++ gtk+-2.18.4/gtk/gtkstyle.c	2010-01-16 21:55:47.000000000 +0100
@@ -3514,6 +3514,22 @@ gtk_default_draw_box (GtkStyle      *sty
       if (area)
 	gdk_gc_set_clip_rectangle (gc, area);
 
+       if (!detail || 
+	  /* this is the complete list: */
+	  /*
+          (
+	   strcmp ("cell_even", detail) &&
+           strcmp ("cell_odd", detail) &&
+           strcmp ("cell_even_ruled", detail) &&
+	   strcmp ("cell_even_ruled_sorted", detail) &&
+ 	   strcmp ("cell_odd_ruled", detail) &&
+	   strcmp ("cell_odd_ruled_sorted", detail) &&
+	   strcmp ("cell_even_sorted", detail) &&
+	   strcmp ("cell_odd_sorted", detail)
+          )
+	  */
+	  /* this is more efficient:*/
+	   !g_str_has_prefix (detail, "cell"))
       gdk_draw_rectangle (window, gc, TRUE,
                           x, y, width, height);
       if (area)
diff -burp gtk+-2.18.4.org/gtk/gtktreeview.c gtk+-2.18.4/gtk/gtktreeview.c
--- gtk+-2.18.4.org/gtk/gtktreeview.c	2009-12-01 04:21:24.000000000 +0100
+++ gtk+-2.18.4/gtk/gtktreeview.c	2010-01-17 16:01:56.000000000 +0100
@@ -63,11 +63,76 @@
 #define BACKGROUND_HEIGHT(node) (GTK_RBNODE_GET_HEIGHT (node))
 #define CELL_HEIGHT(node, separator) ((BACKGROUND_HEIGHT (node)) - (separator))
 
+gint rem (gint x, gint y)
+  {
+    gint result=x;
+
+    while (result<=-y) result+=y;
+    while (result>=y) result-=y;
+
+    return result;
+  }
+gint Y_OFFSET(GtkTreeView* tree_view)
+  {
+    gint pm_height;
+
+    if (GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] &&
+	GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] != (GdkPixmap*) GDK_PARENT_RELATIVE)
+      gdk_drawable_get_size (GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)],
+			     NULL, &pm_height);
+    else
+      pm_height=-1;
+    
+    if (tree_view->priv->bgscroll_ver != GTK_TREE_VIEW_BG_SCROLL_MOVING)
+      return 0;
+    else
+      return ((pm_height==-1)?0:rem(tree_view->priv->vadjustment->value+pm_height, pm_height));
+  }
+gint X_OFFSET(GtkTreeView* tree_view, GtkTreeViewColumn** column)
+  {  
+    gint width;
+    gint offset; 
+    gboolean rtl; 
+    GList *list;
+
+    rtl = (gtk_widget_get_direction (GTK_WIDGET(tree_view)) == GTK_TEXT_DIR_RTL);
+
+    offset = 0; 
+    list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+    if (list) 
+      { 
+        *column = list->data ;
+        width = gtk_tree_view_column_get_width(*column); 
+      } 
+    else 
+      { 
+         *column=NULL;
+         width=-1;
+      } 
+
+    while ((width>=0) && (offset + width <= tree_view->priv->dx)) {
+      offset += width;
+      list =  (rtl ? list->prev : list->next);
+      if (list) 
+	{
+	  *column = list->data;
+          width = gtk_tree_view_column_get_width(*column);
+	}
+      else
+	{
+	  *column = NULL;
+          width=-1;
+	}
+    };
+    return offset - tree_view->priv->dx;
+  };
+
+
 /* Translate from bin_window coordinates to rbtree (tree coordinates) and
  * vice versa.
  */
-#define TREE_WINDOW_Y_TO_RBTREE_Y(tree_view,y) ((y) + tree_view->priv->dy)
-#define RBTREE_Y_TO_TREE_WINDOW_Y(tree_view,y) ((y) - tree_view->priv->dy)
+#define TREE_WINDOW_Y_TO_RBTREE_Y(tree_view,y) ((y) + tree_view->priv->dy - Y_OFFSET(tree_view))
+#define RBTREE_Y_TO_TREE_WINDOW_Y(tree_view,y) ((y) - tree_view->priv->dy + Y_OFFSET(tree_view))
 
 /* This is in bin_window coordinates */
 #define BACKGROUND_FIRST_PIXEL(tree_view,tree,node) (RBTREE_Y_TO_TREE_WINDOW_Y (tree_view, _gtk_rbtree_node_find_offset ((tree), (node))))
@@ -76,11 +141,23 @@
 #define ROW_HEIGHT(tree_view,height) \
   ((height > 0) ? (height) : (tree_view)->priv->expander_size)
 
+#define SET_BACKGROUND(widget,tree_view)	     \
+  if ((GdkPixmap*) GDK_PARENT_RELATIVE == widget->style->bg_pixmap[widget->state]) { \
+    gdk_window_set_back_pixmap (widget->window, NULL, TRUE); \
+    gdk_window_set_back_pixmap (tree_view->priv->bin_window, NULL, TRUE); \
+  } else if (widget->style->rc_style && widget->style->rc_style->bg_pixmap_name[widget->state]) { \
+    gdk_window_set_back_pixmap (widget->window, NULL, FALSE); \
+    gdk_window_set_back_pixmap (tree_view->priv->bin_window, widget->style->bg_pixmap[widget->state], FALSE); \
+  } else { \
+    gdk_window_set_back_pixmap (widget->window, NULL, FALSE); \
+    gdk_window_set_background (tree_view->priv->bin_window, &widget->style->base[widget->state]); \
+  }
 
 typedef struct _GtkTreeViewChild GtkTreeViewChild;
 struct _GtkTreeViewChild
 {
   GtkWidget *widget;
+  gint node_offset;
   gint x;
   gint y;
   gint width;
@@ -144,7 +221,11 @@ enum {
   PROP_RUBBER_BANDING,
   PROP_ENABLE_GRID_LINES,
   PROP_ENABLE_TREE_LINES,
-  PROP_TOOLTIP_COLUMN
+  PROP_TOOLTIP_COLUMN,
+  PROP_BGSCROLL_HOR,
+  PROP_BGSCROLL_VER,
+  PROP_ENABLE_DRAGWINDOW_ANCHOR,
+  PROP_DRAGWINDOW_ANCHOR
 };
 
 /* object signals */
@@ -301,6 +382,10 @@ static gboolean validate_rows           
 static gboolean presize_handler_callback (gpointer     data);
 static void     install_presize_handler  (GtkTreeView *tree_view);
 static void     install_scroll_sync_handler (GtkTreeView *tree_view);
+static void     gtk_tree_view_set_first_column   (GtkTreeView *tree_view,
+					     GtkTreeViewColumn *column,
+					     gint         offset);
+static void	gtk_tree_view_dx_to_first_column (GtkTreeView *tree_view);
 static void     gtk_tree_view_set_top_row   (GtkTreeView *tree_view,
 					     GtkTreePath *path,
 					     gint         offset);
@@ -764,12 +849,61 @@ gtk_tree_view_class_init (GtkTreeViewCla
 						       -1,
 						       GTK_PARAM_READWRITE));
 
+  /**
+   * GtkTreeView:dragwindow-anchor:
+   *
+   * Enable the usage of a specific  anchor point for the drag window. 
+   * When disabled, the dragwindow is attached with the button-up location to the mouse pointer 
+   *
+   * Since: 2.20
+   */
+    g_object_class_install_property (o_class,
+				     PROP_ENABLE_DRAGWINDOW_ANCHOR,
+				     g_param_spec_boolean ("enable-dragwindow-anchor",
+							   P_("Allow dragwindow anchor"),
+							   P_("Use a anchor point for the drag window"),
+							   FALSE,
+							   GTK_PARAM_READWRITE));
+
+  /**
+   * GtkTreeView:dragwindow-anchor:
+   *
+   * The anchor point of the drag window. 
+   *
+   * Since: 2.20
+   */
+    g_object_class_install_property (o_class,
+				     PROP_DRAGWINDOW_ANCHOR,
+				     g_param_spec_enum ("dragwindow-anchor",
+							P_("Dragwindow anchor"),
+							P_("The anchor point of the drag window"),
+							GTK_TYPE_ANCHOR_TYPE,
+							GTK_ANCHOR_CENTER,
+							GTK_PARAM_READWRITE));
+
+
   /* Style properties */
 #define _TREE_VIEW_EXPANDER_SIZE 12
 #define _TREE_VIEW_VERTICAL_SEPARATOR 2
 #define _TREE_VIEW_HORIZONTAL_SEPARATOR 2
 
   gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_enum ("bgscroll-hor",
+						              P_("Background Scroll Horizontal"),
+						              P_("Define the horizontol scrolling policy for background placement"),
+						              GTK_TYPE_TREE_VIEW_BG_SCROLL,
+ 						              GTK_TREE_VIEW_BG_SCROLL_DEFAULT,
+						              GTK_PARAM_READWRITE));
+
+  gtk_widget_class_install_style_property (widget_class,
+                                           g_param_spec_enum ("bgscroll-ver",
+						              P_("Background Scroll Vertical"),
+						              P_("Define the vertical scrolling policy for background placement"),
+						              GTK_TYPE_TREE_VIEW_BG_SCROLL,
+ 						              GTK_TREE_VIEW_BG_SCROLL_DEFAULT,
+						              GTK_PARAM_READWRITE));
+
+  gtk_widget_class_install_style_property (widget_class,
 					   g_param_spec_int ("expander-size",
 							     P_("Expander Size"),
 							     P_("Size of the expander arrow"),
@@ -1333,6 +1467,11 @@ gtk_tree_view_init (GtkTreeView *tree_vi
 
   /* We need some padding */
   tree_view->priv->dy = 0;
+  tree_view->priv->dx = 0;
+
+  tree_view->priv->bgscroll_hor = GTK_TREE_VIEW_BG_SCROLL_DEFAULT;
+  tree_view->priv->bgscroll_ver = GTK_TREE_VIEW_BG_SCROLL_DEFAULT;
+
   tree_view->priv->cursor_offset = 0;
   tree_view->priv->n_columns = 0;
   tree_view->priv->header_height = 1;
@@ -1372,6 +1511,9 @@ gtk_tree_view_init (GtkTreeView *tree_vi
   tree_view->priv->tooltip_column = -1;
 
   tree_view->priv->post_validation_flag = FALSE;
+
+  tree_view->priv->dragwindow_anchor_set = FALSE;
+  tree_view->priv->dragwindow_anchor = GTK_ANCHOR_CENTER;
 }
 
 
@@ -1448,6 +1590,18 @@ gtk_tree_view_set_property (GObject     
     case PROP_TOOLTIP_COLUMN:
       gtk_tree_view_set_tooltip_column (tree_view, g_value_get_int (value));
       break;
+    case PROP_BGSCROLL_HOR:
+      gtk_tree_view_set_bg_scrolling (tree_view, g_value_get_enum (value), GTK_TREE_VIEW_BG_SCROLL_NONE);
+      break;
+    case PROP_BGSCROLL_VER:
+      gtk_tree_view_set_bg_scrolling (tree_view, GTK_TREE_VIEW_BG_SCROLL_NONE, g_value_get_enum (value));
+      break;
+    case PROP_ENABLE_DRAGWINDOW_ANCHOR:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, g_value_get_boolean(value));
+      break;
+    case PROP_DRAGWINDOW_ANCHOR:
+      gtk_tree_view_set_dragwindow_anchor (tree_view, g_value_get_enum(value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1523,6 +1677,22 @@ gtk_tree_view_get_property (GObject    *
     case PROP_TOOLTIP_COLUMN:
       g_value_set_int (value, tree_view->priv->tooltip_column);
       break;
+    case PROP_BGSCROLL_HOR:
+      g_value_set_enum (value, tree_view->priv->bgscroll_hor);
+      break;
+    case PROP_BGSCROLL_VER:
+      g_value_set_enum (value, tree_view->priv->bgscroll_ver);
+      break;
+    case PROP_ENABLE_DRAGWINDOW_ANCHOR:
+      g_value_set_boolean(value, gtk_tree_view_get_enable_dragwindow_anchor (tree_view));
+      break;
+    case PROP_DRAGWINDOW_ANCHOR:
+      {
+	GtkAnchorType anchor;
+	gtk_tree_view_get_dragwindow_anchor (tree_view, &anchor);
+        g_value_set_enum (value, anchor);
+      }
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1770,6 +1940,7 @@ gtk_tree_view_realize (GtkWidget *widget
   GList *tmp_list;
   GdkWindowAttr attributes;
   gint attributes_mask;
+  gint pm_height;
 
   GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 
@@ -1790,11 +1961,20 @@ gtk_tree_view_realize (GtkWidget *widget
 				   &attributes, attributes_mask);
   gdk_window_set_user_data (widget->window, widget);
 
+  if (GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] &&
+      GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)]  != (GdkPixmap*) GDK_PARENT_RELATIVE)
+    {
+      gdk_drawable_get_size (widget->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)],
+			     NULL, &pm_height);
+    }
+  else
+    pm_height=0;
+
   /* 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.height = widget->allocation.height+pm_height; /* we need the pm_height for scrolling */
   attributes.event_mask = (GDK_EXPOSURE_MASK |
                            GDK_SCROLL_MASK |
                            GDK_POINTER_MOTION_MASK |
@@ -1827,8 +2007,7 @@ gtk_tree_view_realize (GtkWidget *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]);
+  SET_BACKGROUND(widget, tree_view);
   gtk_style_set_background (widget->style, tree_view->priv->header_window, GTK_STATE_NORMAL);
 
   tmp_list = tree_view->priv->children;
@@ -2212,7 +2391,7 @@ gtk_tree_view_size_allocate_columns (Gtk
   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 + tree_view->priv->first_column_dx, 0);
     }
   else
     {
@@ -2299,27 +2478,30 @@ gtk_tree_view_size_allocate_columns (Gtk
       allocation.width = column->width;
       width += column->width;
 
-      if (column->width > old_width)
+      if (column->width != old_width)
         column_changed = TRUE;
 
       gtk_widget_size_allocate (column->button, &allocation);
 
-      if (column->window)
+      if (column->window) {
 	gdk_window_move_resize (column->window,
                                 allocation.x + (rtl ? 0 : allocation.width) - TREE_VIEW_DRAG_WIDTH/2,
 				allocation.y,
                                 TREE_VIEW_DRAG_WIDTH, allocation.height);
     }
+    }
 
   /* We change the width here.  The user might have been resizing columns,
    * so the total width of the tree view changes.
    */
   tree_view->priv->width = width;
+  if (column_changed)
+    {
   if (width_changed)
     *width_changed = TRUE;
 
-  if (column_changed)
     gtk_widget_queue_draw (GTK_WIDGET (tree_view));
+    }
 }
 
 
@@ -2331,6 +2513,7 @@ gtk_tree_view_size_allocate (GtkWidget  
   GList *tmp_list;
   gboolean width_changed = FALSE;
   gint old_width = widget->allocation.width;
+  gboolean early_repaint = FALSE;
 
   if (allocation->width != widget->allocation.width)
     width_changed = TRUE;
@@ -2389,8 +2572,22 @@ gtk_tree_view_size_allocate (GtkWidget  
     }
   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);
+      }
+
+  /* we are resize the window, and the visible part is larger than the current shown part;
+     check that hidden columns are made visible again
+  */
+  if (tree_view->priv->bgscroll_hor != GTK_TREE_VIEW_BG_SCROLL_MOVING &&
+      tree_view->priv->hadjustment->value != tree_view->priv->dx)
+    {
+       tree_view->priv->dx *= -1;
+       gtk_tree_view_adjustment_changed (tree_view->priv->hadjustment, tree_view);
 
+       /* we have done the repainting of the window! */
+       early_repaint = TRUE;
+    }
   gtk_adjustment_changed (tree_view->priv->hadjustment);
 
   tree_view->priv->vadjustment->page_size = allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view);
@@ -2403,17 +2600,31 @@ gtk_tree_view_size_allocate (GtkWidget  
 
   /* 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)
+    {
     gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment), 0);
+    }
   else if (tree_view->priv->vadjustment->value + tree_view->priv->vadjustment->page_size > tree_view->priv->height)
+    {
     gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment),
                               tree_view->priv->height - tree_view->priv->vadjustment->page_size);
-  else if (gtk_tree_row_reference_valid (tree_view->priv->top_row))
-    gtk_tree_view_top_row_to_dy (tree_view);
-  else
-    gtk_tree_view_dy_to_top_row (tree_view);
+    }
+  else if (width_changed)
+    {
+      tree_view->priv->dy=0;
+      gtk_tree_view_adjustment_changed (tree_view->priv->vadjustment, tree_view);
+    }
   
   if (GTK_WIDGET_REALIZED (widget))
     {
+      gint pm_height;
+
+      if (GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] &&
+	  GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)]  != (GdkPixmap*) GDK_PARENT_RELATIVE)
+	gdk_drawable_get_size (widget->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)],
+			       NULL, &pm_height);
+      else
+	pm_height=0;
+
       gdk_window_move_resize (widget->window,
 			      allocation->x, allocation->y,
 			      allocation->width, allocation->height);
@@ -2422,11 +2633,9 @@ gtk_tree_view_size_allocate (GtkWidget  
 			      0,
 			      MAX (tree_view->priv->width, allocation->width),
 			      tree_view->priv->header_height);
-      gdk_window_move_resize (tree_view->priv->bin_window,
-			      - (gint) tree_view->priv->hadjustment->value,
-			      TREE_VIEW_HEADER_HEIGHT (tree_view),
+      gdk_window_resize (tree_view->priv->bin_window,
 			      MAX (tree_view->priv->width, allocation->width),
-			      allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view));
+			      (allocation->height+pm_height) - TREE_VIEW_HEADER_HEIGHT (tree_view));
     }
 
   if (tree_view->priv->tree == NULL)
@@ -2445,7 +2654,7 @@ gtk_tree_view_size_allocate (GtkWidget  
 	}
 
       /* This little hack only works if we have an LTR locale, and no column has the  */
-      if (width_changed)
+      if (width_changed && !early_repaint)
 	{
 	  if (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_LTR &&
 	      ! has_expand_column)
@@ -2590,6 +2799,7 @@ gtk_tree_view_button_press (GtkWidget   
       background_area.y = y_offset + event->y;
       background_area.height = ROW_HEIGHT (tree_view, GTK_RBNODE_GET_HEIGHT (node));
       background_area.x = 0;
+  background_area.x += tree_view->priv->first_column_dx;
 
 
       /* Let the column have a chance at selecting it. */
@@ -2769,9 +2979,10 @@ gtk_tree_view_button_press (GtkWidget   
 	      && !node_selected
 	      && tree_view->priv->selection->type == GTK_SELECTION_MULTIPLE)
 	    {
-	      tree_view->priv->press_start_y += tree_view->priv->dy;
-	      tree_view->priv->rubber_band_x = event->x;
-	      tree_view->priv->rubber_band_y = event->y + tree_view->priv->dy;
+	      tree_view->priv->press_start_x += tree_view->priv->dx;
+              tree_view->priv->press_start_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
+	      tree_view->priv->rubber_band_x = event->x + tree_view->priv->dx;
+	      tree_view->priv->rubber_band_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y);
 	      tree_view->priv->rubber_band_status = RUBBER_BAND_MAYBE_START;
 
 	      if ((event->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
@@ -2952,6 +3163,8 @@ gtk_tree_view_button_release_drag_column
   tree_view->priv->drag_column_window_state = DRAG_COLUMN_WINDOW_STATE_UNSET;
   GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG);
 
+  gtk_tree_view_dx_to_first_column(tree_view);
+
   return TRUE;
 }
 
@@ -2979,6 +3192,7 @@ gtk_tree_view_button_release_column_resi
   gtk_grab_remove (widget);
   gdk_display_pointer_ungrab (gdk_drawable_get_display (event->window),
 			      event->time);
+
   return TRUE;
 }
 
@@ -3392,6 +3606,7 @@ gtk_tree_view_motion_draw_column_motion_
 
       /* Get x, y, width, height of arrow */
       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;
@@ -3469,6 +3684,7 @@ gtk_tree_view_motion_draw_column_motion_
       /* 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);
+ 
       if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT)
 	x += widget->allocation.width - width;
 
@@ -3613,7 +3829,7 @@ gtk_tree_view_vertical_autoscroll (GtkTr
   gfloat value;
 
   gdk_window_get_pointer (tree_view->priv->bin_window, NULL, &y, NULL);
-  y += tree_view->priv->dy;
+  y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, y);
 
   gtk_tree_view_get_visible_rect (tree_view, &visible_rect);
 
@@ -3640,6 +3856,7 @@ gtk_tree_view_horizontal_autoscroll (Gtk
   gfloat value;
 
   gdk_window_get_pointer (tree_view->priv->bin_window, &x, NULL, NULL);
+  x += tree_view->priv->dx;
 
   gtk_tree_view_get_visible_rect (tree_view, &visible_rect);
 
@@ -3839,8 +4056,12 @@ gtk_tree_view_update_rubber_band_selecti
   GtkRBTree *start_tree, *end_tree;
   GtkRBNode *start_node, *end_node;
 
-  _gtk_rbtree_find_offset (tree_view->priv->tree, MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y), &start_tree, &start_node);
-  _gtk_rbtree_find_offset (tree_view->priv->tree, MAX (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y), &end_tree, &end_node);
+  gint y;
+
+  y=MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y);
+  _gtk_rbtree_find_offset (tree_view->priv->tree, y, &start_tree, &start_node);
+  y=MAX (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y);
+  _gtk_rbtree_find_offset (tree_view->priv->tree, y, &end_tree, &end_node);
 
   /* Handle the start area first */
   if (!tree_view->priv->rubber_band_start_node)
@@ -3894,7 +4115,18 @@ gtk_tree_view_update_rubber_band_selecti
   else if (!end_node)
     {
       /* Find the last node in the tree */
-      _gtk_rbtree_find_offset (tree_view->priv->tree, tree_view->priv->height - 1,
+      gint y;
+      gint bin_window_height;
+
+      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+			     NULL, &bin_window_height);
+      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+      y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, bin_window_height);
+
+      if (y < 0)
+	y = 0;
+      _gtk_rbtree_find_offset (tree_view->priv->tree, y-1,
 			       &end_tree, &end_node);
 
       /* Selection reached end of the tree */
@@ -3947,18 +4179,18 @@ gtk_tree_view_update_rubber_band (GtkTre
   GdkRectangle common;
   GdkRegion *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;
+  old_area.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x) - tree_view->priv->dx;
+  old_area.y = RBTREE_Y_TO_TREE_WINDOW_Y(tree_view, MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y));
   old_area.width = ABS (tree_view->priv->rubber_band_x - tree_view->priv->press_start_x) + 1;
   old_area.height = ABS (tree_view->priv->rubber_band_y - tree_view->priv->press_start_y) + 1;
 
   gdk_window_get_pointer (tree_view->priv->bin_window, &x, &y, NULL);
 
-  x = MAX (x, 0);
-  y = MAX (y, 0) + tree_view->priv->dy;
+  x = MAX (x, 0) + tree_view->priv->dx;
+  y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, MAX (y, 0));
 
-  new_area.x = MIN (tree_view->priv->press_start_x, x);
-  new_area.y = MIN (tree_view->priv->press_start_y, y) - tree_view->priv->dy;
+  new_area.x = MIN (tree_view->priv->press_start_x, x) - tree_view->priv->dx;
+  new_area.y = RBTREE_Y_TO_TREE_WINDOW_Y(tree_view, MIN (tree_view->priv->press_start_y, y));
   new_area.width = ABS (x - tree_view->priv->press_start_x) + 1;
   new_area.height = ABS (y - tree_view->priv->press_start_y) + 1;
 
@@ -4000,8 +4232,8 @@ gtk_tree_view_paint_rubber_band (GtkTree
   GdkRectangle rect;
   GdkRectangle rubber_rect;
 
-  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.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x) - tree_view->priv->dx;
+  rubber_rect.y = RBTREE_Y_TO_TREE_WINDOW_Y(tree_view, MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y));
   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;
 
@@ -4119,7 +4351,9 @@ invalidate_empty_focus (GtkTreeView *tre
 
   area.x = 0;
   area.y = 0;
-  gdk_drawable_get_size (tree_view->priv->bin_window, &area.width, &area.height);
+  gdk_drawable_get_size (tree_view->priv->bin_window, &area.width, NULL);
+  gdk_drawable_get_size (GTK_WIDGET(tree_view)->window, NULL, &area.height);
+  area.height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
   gdk_window_invalidate_rect (tree_view->priv->bin_window, &area, FALSE);
 }
 
@@ -4134,7 +4368,9 @@ draw_empty_focus (GtkTreeView *tree_view
   if (!GTK_WIDGET_HAS_FOCUS (tree_view))
     return;
 
-  gdk_drawable_get_size (tree_view->priv->bin_window, &w, &h);
+  gdk_drawable_get_size (tree_view->priv->bin_window, &w, NULL);
+  gdk_drawable_get_size (GTK_WIDGET(tree_view)->window, NULL, &h);
+  h -= TREE_VIEW_HEADER_HEIGHT (tree_view);
 
   w -= 2;
   h -= 2;
@@ -4162,8 +4398,10 @@ gtk_tree_view_draw_grid_lines (GtkTreeVi
       && tree_view->priv->grid_lines != GTK_TREE_VIEW_GRID_LINES_BOTH)
     return;
 
+  current_x += tree_view->priv->first_column_dx;
+ 
   /* Only draw the lines for visible rows and columns */
-  for (list = tree_view->priv->columns; list; list = list->next, i++)
+  for (list = (tree_view->priv->first_column)?tree_view->priv->first_column:tree_view->priv->columns; list; list = list->next, i++)
     {
       GtkTreeViewColumn *column = list->data;
 
@@ -4258,11 +4496,14 @@ gtk_tree_view_bin_expose (GtkWidget     
     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);
+                         &bin_window_width, NULL);
+  gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+                         NULL, &bin_window_height);
+  bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
 
   if (tree_view->priv->height < bin_window_height)
     {
-      gtk_paint_flat_box (widget->style,
+      gtk_paint_box (widget->style,
                           event->window,
                           widget->state,
                           GTK_SHADOW_NONE,
@@ -4323,15 +4564,16 @@ gtk_tree_view_bin_expose (GtkWidget     
     }
 
   /* Find the last column */
-  for (last_column = g_list_last (tree_view->priv->columns);
+  for (last_column = (rtl ? g_list_first (tree_view->priv->columns) : g_list_last (tree_view->priv->columns));
        last_column && !(GTK_TREE_VIEW_COLUMN (last_column->data)->visible);
-       last_column = last_column->prev)
+       last_column = (rtl ? last_column->next : last_column->prev))
     ;
 
   /* and the first */
-  for (first_column = g_list_first (tree_view->priv->columns);
+  for (first_column = (tree_view->priv->first_column)?tree_view->priv->first_column:
+       (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
        first_column && !(GTK_TREE_VIEW_COLUMN (first_column->data)->visible);
-       first_column = first_column->next)
+       first_column = (rtl ? first_column->prev : first_column->next))
     ;
 
   /* Actually process the expose event.  To do this, we want to
@@ -4351,6 +4593,7 @@ gtk_tree_view_bin_expose (GtkWidget     
       max_height = ROW_HEIGHT (tree_view, BACKGROUND_HEIGHT (node));
 
       cell_offset = 0;
+      cell_offset += tree_view->priv->first_column_dx;
       highlight_x = 0; /* should match x coord of first cell */
       expander_cell_width = 0;
 
@@ -4385,8 +4628,8 @@ gtk_tree_view_bin_expose (GtkWidget     
 
       has_special_cell = gtk_tree_view_has_special_cell (tree_view);
 
-      for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
-	   list;
+      for (list = first_column;
+	   list != (rtl ? last_column->prev : last_column->next);
 	   list = (rtl ? list->prev : list->next))
 	{
 	  GtkTreeViewColumn *column = list->data;
@@ -4416,6 +4659,11 @@ gtk_tree_view_bin_expose (GtkWidget     
 	  background_area.x = cell_offset;
 	  background_area.width = column->width;
 
+	  if (list == last_column)
+	    {
+	       background_area.width -= tree_view->priv->first_column_dx;
+	    };
+
           cell_area = background_area;
           cell_area.y += vertical_separator / 2;
           cell_area.x += horizontal_separator / 2;
@@ -4528,6 +4776,7 @@ gtk_tree_view_bin_expose (GtkWidget     
 	      else
 		g_snprintf (new_detail, 128, "%s_middle", detail);
 
+if (state != GTK_STATE_NORMAL)
 	      gtk_paint_flat_box (widget->style,
 				  event->window,
 				  state,
@@ -4539,9 +4788,22 @@ gtk_tree_view_bin_expose (GtkWidget     
 				  background_area.y,
 				  background_area.width,
 				  background_area.height);
+else
+	      gtk_paint_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);
 	    }
 	  else
 	    {
+if (state != GTK_STATE_NORMAL)
 	      gtk_paint_flat_box (widget->style,
 				  event->window,
 				  state,
@@ -4553,6 +4815,18 @@ gtk_tree_view_bin_expose (GtkWidget     
 				  background_area.y,
 				  background_area.width,
 				  background_area.height);
+else
+	      gtk_paint_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)
@@ -4647,6 +4921,7 @@ gtk_tree_view_bin_expose (GtkWidget     
 	    }
 
 	  if (gtk_tree_view_is_expander_column (tree_view, column) &&
+	      (TREE_VIEW_DRAW_EXPANDERS(tree_view) || (tree_view->priv->level_indentation>0)) &&
 	      tree_view->priv->tree_lines_enabled)
 	    {
 	      gint x = background_area.x;
@@ -4655,6 +4930,8 @@ gtk_tree_view_bin_expose (GtkWidget     
 	      gint y1 = background_area.y + background_area.height/2;
 	      gint y2 = background_area.y + background_area.height;
 
+	      gint exp_mult = (TREE_VIEW_DRAW_EXPANDERS(tree_view)) ? 1 :0;
+
 	      if (rtl)
 		x += background_area.width - 1;
 
@@ -4663,18 +4940,22 @@ gtk_tree_view_bin_expose (GtkWidget     
 	        {
 		  gdk_draw_line (event->window,
 				 tree_view->priv->tree_line_gc,
-			         x + tree_view->priv->expander_size * (depth - 1.5) * mult,
+			         x + tree_view->priv->expander_size * (depth - 1.5) * mult
+                                   * exp_mult + (depth - 2) * tree_view->priv->level_indentation * mult,
 				 y1,
-			         x + tree_view->priv->expander_size * (depth - 1.1) * mult,
+			         x + tree_view->priv->expander_size * (depth - 1.1) * mult
+				   * exp_mult + (depth - 1) * tree_view->priv->level_indentation * 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,
+			         x + tree_view->priv->expander_size * (depth - 1.5) * mult
+                                   * exp_mult + (depth - 2) * tree_view->priv->level_indentation * mult,
 				 y1,
-			         x + tree_view->priv->expander_size * (depth - 0.5) * mult,
+				 x + tree_view->priv->expander_size * (depth - 0.5) * mult
+				   * exp_mult + (depth - 1) * tree_view->priv->level_indentation * mult,
 				 y1);
 		}
 
@@ -4687,16 +4968,20 @@ gtk_tree_view_bin_expose (GtkWidget     
 	          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,
+				   x + tree_view->priv->expander_size * (depth - 1.5) * mult
+				     * exp_mult + (depth - 2) * tree_view->priv->level_indentation * mult,
 				   y0,
-				   x + tree_view->priv->expander_size * (depth - 1.5) * mult,
+				   x + tree_view->priv->expander_size * (depth - 1.5) * mult
+				     * exp_mult + (depth - 2) * tree_view->priv->level_indentation * mult,
 				   y1);
 		  else
 		    gdk_draw_line (event->window,
 				   tree_view->priv->tree_line_gc,
-				   x + tree_view->priv->expander_size * (depth - 1.5) * mult,
+				   x + tree_view->priv->expander_size * (depth - 1.5) * mult
+				     * exp_mult + (depth - 2) * tree_view->priv->level_indentation * mult,
 				   y0,
-				   x + tree_view->priv->expander_size * (depth - 1.5) * mult,
+				   x + tree_view->priv->expander_size * (depth - 1.5) * mult
+				     * exp_mult + (depth - 2) * tree_view->priv->level_indentation * mult,
 				   y2);
 
 		  tmp_node = tree->parent_node;
@@ -4707,9 +4992,11 @@ gtk_tree_view_bin_expose (GtkWidget     
 	              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,
+				       x + tree_view->priv->expander_size * (i - 0.5) * mult
+				         * exp_mult + (i-1) * tree_view->priv->level_indentation * mult,
 				       y0,
-				       x + tree_view->priv->expander_size * (i - 0.5) * mult,
+				       x + tree_view->priv->expander_size * (i - 0.5) * mult
+				         * exp_mult + (i-1) * tree_view->priv->level_indentation * mult,
 				       y2);
 
 		      tmp_node = tmp_tree->parent_node;
@@ -4800,6 +5087,7 @@ gtk_tree_view_bin_expose (GtkWidget     
                              highlight_y,
                              rtl ? 0 : bin_window_width,
                              highlight_y);
+
             }
         }
 
@@ -5629,7 +5917,8 @@ validate_row (GtkTreeView *tree_view,
        last_column = last_column->prev)
     ;
 
-  for (first_column = g_list_first (tree_view->priv->columns);
+  for (first_column = (tree_view->priv->first_column)?tree_view->priv->first_column:
+	 g_list_first (tree_view->priv->columns);
        first_column && !(GTK_TREE_VIEW_COLUMN (first_column->data)->visible);
        first_column = first_column->next)
     ;
@@ -6041,8 +6330,6 @@ validate_visible_area (GtkTreeView *tree
       gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment), tree_view->priv->height - tree_view->priv->vadjustment->page_size);
       gtk_tree_view_dy_to_top_row (tree_view);
     }
-  else
-    gtk_tree_view_top_row_to_dy (tree_view);
 
   /* update width/height and queue a resize */
   if (size_changed)
@@ -6347,10 +6634,11 @@ scroll_sync_handler (GtkTreeView *tree_v
 {
   if (tree_view->priv->height <= tree_view->priv->vadjustment->page_size)
     gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->vadjustment), 0);
-  else if (gtk_tree_row_reference_valid (tree_view->priv->top_row))
-    gtk_tree_view_top_row_to_dy (tree_view);
+
+  if (tree_view->priv->width <= tree_view->priv->hadjustment->page_size)
+    gtk_adjustment_set_value (GTK_ADJUSTMENT (tree_view->priv->hadjustment), 0);
   else
-    gtk_tree_view_dy_to_top_row (tree_view);
+    gtk_tree_view_dx_to_first_column (tree_view);
 
   tree_view->priv->scroll_sync_timer = 0;
 
@@ -6371,6 +6659,70 @@ install_scroll_sync_handler (GtkTreeView
 }
 
 static void
+gtk_tree_view_set_first_column (GtkTreeView *tree_view,
+			   GtkTreeViewColumn *column,
+			   gint         offset)
+{
+  if (!column)
+    {
+      tree_view->priv->first_column = NULL;
+      tree_view->priv->first_column_dx = 0;
+    }
+  else
+    {
+      GList* priv_column;
+
+      priv_column=tree_view->priv->columns;
+      while (priv_column && (priv_column->data != column)) {
+        priv_column=priv_column->next;
+      };
+      tree_view->priv->first_column = priv_column;
+      tree_view->priv->first_column_dx = offset;
+    }
+}
+
+static void
+gtk_tree_view_dx_to_first_column (GtkTreeView *tree_view)
+{
+  gint offset;
+  GtkTreeViewColumn *column;
+
+  if (tree_view->priv->bgscroll_hor == GTK_TREE_VIEW_BG_SCROLL_MOVING)
+    return;
+
+  if (tree_view->priv->hadjustment == NULL)
+    return;
+
+  if (tree_view->priv->tree == NULL)
+    {
+      gtk_tree_view_set_first_column (tree_view, NULL, 0);
+    }
+  else
+    {
+
+      offset = X_OFFSET(tree_view, &column);
+
+      if (tree_view->priv->hadjustment->value + tree_view->priv->hadjustment->page_size >= tree_view->priv->hadjustment->upper) 
+	{
+	  if (-offset > tree_view->priv->hadjustment->value)
+	    {
+	      offset = -tree_view->priv->hadjustment->value;
+	    }
+	} 
+
+      if (column == NULL)
+        {
+	  tree_view->priv->first_column = NULL;
+	  tree_view->priv->first_column_dx = 0;
+	}
+      else
+        {
+	  gtk_tree_view_set_first_column (tree_view, column, offset);
+	}
+    }
+}
+
+static void
 gtk_tree_view_set_top_row (GtkTreeView *tree_view,
 			   GtkTreePath *path,
 			   gint         offset)
@@ -6407,7 +6759,7 @@ gtk_tree_view_dy_to_top_row (GtkTreeView
   else
     {
       offset = _gtk_rbtree_find_offset (tree_view->priv->tree,
-					tree_view->priv->dy,
+					tree_view->priv->dy-Y_OFFSET(tree_view),
 					&tree, &node);
 
       if (tree == NULL)
@@ -6688,6 +7040,8 @@ drag_scan_timeout (gpointer data)
 
   gdk_window_get_pointer (tree_view->priv->bin_window,
                           &x, &y, &state);
+  x += tree_view->priv->dx;
+  y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, y);
 
   gtk_tree_view_get_visible_rect (tree_view, &visible_rect);
 
@@ -7094,6 +7448,11 @@ gtk_tree_view_drag_begin (GtkWidget     
   GdkPixmap *row_pix;
   TreeViewDragInfo *di;
 
+  gint hotspot_x;
+  gint hotspot_y;
+  gint icon_height;
+  gint icon_width;
+
   tree_view = GTK_TREE_VIEW (widget);
 
   /* if the user uses a custom DND source impl, we don't set the icon here */
@@ -7115,13 +7474,62 @@ gtk_tree_view_drag_begin (GtkWidget     
   row_pix = gtk_tree_view_create_row_drag_icon (tree_view,
                                                 path);
 
+  gdk_drawable_get_size (row_pix, &icon_width, &icon_height);
+
+  /* the + 1 is for the black border in the icon */
+  hotspot_x=1; 
+  hotspot_y=1;
+  if (tree_view->priv->dragwindow_anchor_set)
+    {
+      switch (tree_view->priv->dragwindow_anchor)
+	{
+	case GTK_ANCHOR_NORTH:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_SOUTH:
+	  hotspot_x += icon_width/2;
+	  break;
+	case GTK_ANCHOR_NORTH_EAST:
+	case GTK_ANCHOR_EAST:
+	case GTK_ANCHOR_SOUTH_EAST:
+	  hotspot_x += icon_width;
+	  break;
+	case GTK_ANCHOR_NORTH_WEST:
+	case GTK_ANCHOR_WEST:
+	case GTK_ANCHOR_SOUTH_WEST:
+	  hotspot_x += 0;
+	  break;
+	}
+      switch (tree_view->priv->dragwindow_anchor)
+	{
+	case GTK_ANCHOR_WEST:
+	case GTK_ANCHOR_CENTER:
+	case GTK_ANCHOR_EAST:
+	  hotspot_y += icon_height/2;
+	  break;
+	case GTK_ANCHOR_SOUTH_WEST:
+	case GTK_ANCHOR_SOUTH:
+	case GTK_ANCHOR_SOUTH_EAST:
+	  hotspot_y += icon_height;
+	  break;
+	case GTK_ANCHOR_NORTH_WEST:
+	case GTK_ANCHOR_NORTH:
+	case GTK_ANCHOR_NORTH_EAST:
+	  hotspot_y += 0;
+	  break;
+	}
+    }
+  else
+    {
+      hotspot_x += tree_view->priv->press_start_x;
+      hotspot_y += cell_y;
+    }
+
   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);
+                            hotspot_x,
+                            hotspot_y);
 
   g_object_unref (row_pix);
   gtk_tree_path_free (path);
@@ -7945,8 +8353,7 @@ gtk_tree_view_style_set (GtkWidget *widg
 
   if (GTK_WIDGET_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]);
+      SET_BACKGROUND(widget,tree_view);
       gtk_style_set_background (widget->style, tree_view->priv->header_window, GTK_STATE_NORMAL);
 
       gtk_tree_view_set_grid_lines (tree_view, tree_view->priv->grid_lines);
@@ -8126,6 +8533,16 @@ gtk_tree_view_put (GtkTreeView *tree_vie
   child = g_slice_new (GtkTreeViewChild);
 
   child->widget = child_widget;
+
+  if (tree_view->priv->bgscroll_ver != GTK_TREE_VIEW_BG_SCROLL_MOVING ||
+      !GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] ||
+      GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] == (GdkPixmap*) GDK_PARENT_RELATIVE)
+    child->node_offset = tree_view->priv->vadjustment->value+y-Y_OFFSET(tree_view);
+  else
+    {
+      child->node_offset = tree_view->priv->vadjustment->value+y-Y_OFFSET(tree_view);
+    }
+
   child->x = x;
   child->y = y;
   child->width = width;
@@ -8591,7 +9008,6 @@ gtk_tree_view_rows_reordered (GtkTreeMod
 
   gtk_widget_queue_draw (GTK_WIDGET (tree_view));
 
-  gtk_tree_view_dy_to_top_row (tree_view);
 }
 
 
@@ -8620,7 +9036,9 @@ gtk_tree_view_get_background_xrange (Gtk
   rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
 
   total_width = 0;
-  for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+
+  for (list = (tree_view->priv->first_column) ? tree_view->priv->first_column :
+	 (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
        list;
        list = (rtl ? list->prev : list->next))
     {
@@ -8640,14 +9058,17 @@ gtk_tree_view_get_background_xrange (Gtk
     }
 
   if (x1)
+    {
     *x1 = total_width;
+      *x1 += tree_view->priv->first_column_dx;
+    }
 
   if (x2)
     {
       if (column->visible)
-        *x2 = total_width + column->width;
+        *x2 = *x1 + column->width;
       else
-        *x2 = total_width; /* width of 0 */
+        *x2 = *x1; /* width of 0 */
     }
 }
 static void
@@ -8666,7 +9087,8 @@ gtk_tree_view_get_arrow_xrange (GtkTreeV
   rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
 
   total_width = 0;
-  for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+  for (list = (tree_view->priv->first_column)?tree_view->priv->first_column:
+       (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
        list;
        list = (rtl ? list->prev : list->next))
     {
@@ -8692,12 +9114,18 @@ gtk_tree_view_get_arrow_xrange (GtkTreeV
   if (indent_expanders)
     {
       if (rtl)
-	x_offset -= tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree);
+	x_offset -= tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree)
+	  + (_gtk_rbtree_get_depth (tree)) * tree_view->priv->level_indentation;
       else
-	x_offset += tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree);
+	x_offset += tree_view->priv->expander_size * _gtk_rbtree_get_depth (tree)
+	  + (_gtk_rbtree_get_depth (tree)) * tree_view->priv->level_indentation;
     }
 
+  if (x1)
+    {
   *x1 = x_offset;
+      *x1 += tree_view->priv->first_column_dx;
+    }
   
   if (tmp_column && tmp_column->visible)
     /* +1 because x2 isn't included in the range. */
@@ -9221,7 +9649,7 @@ _gtk_tree_view_column_start_drag (GtkTre
       attributes.window_type = GDK_WINDOW_CHILD;
       attributes.wclass = GDK_INPUT_OUTPUT;
       attributes.x = column->button->allocation.x;
-      attributes.y = 0;
+      attributes.y = 0+TREE_VIEW_HEADER_HEIGHT (tree_view);
       attributes.width = column->button->allocation.width;
       attributes.height = column->button->allocation.height;
       attributes.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
@@ -9229,11 +9657,15 @@ _gtk_tree_view_column_start_drag (GtkTre
       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;
 
-      tree_view->priv->drag_window = gdk_window_new (tree_view->priv->bin_window,
+      tree_view->priv->drag_window = gdk_window_new (GTK_WIDGET(tree_view)->window,
 						     &attributes,
 						     attributes_mask);
       gdk_window_set_user_data (tree_view->priv->drag_window, GTK_WIDGET (tree_view));
     }
+  else
+    {
+      gdk_window_resize (tree_view->priv->drag_window, gtk_tree_view_get_real_requested_width_from_column (tree_view, column), column->button->allocation.height);
+    }
 
   gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME);
   gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME);
@@ -9404,6 +9836,8 @@ gtk_tree_view_draw_arrow (GtkTreeView *t
 
   widget = GTK_WIDGET (tree_view);
 
+  x_offset += tree_view->priv->first_column_dx;
+
   gtk_tree_view_get_arrow_xrange (tree_view, tree, &x_offset, &x2);
 
   area.x = x_offset;
@@ -9744,7 +10178,6 @@ gtk_tree_view_move_cursor_page_up_down (
   gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE, FALSE);
 
   y -= window_y;
-  gtk_tree_view_scroll_to_point (tree_view, -1, y);
   gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
   _gtk_tree_view_queue_draw_node (tree_view, cursor_tree, cursor_node, NULL);
 
@@ -10494,40 +10927,280 @@ gtk_tree_view_adjustment_changed (GtkAdj
 {
   if (GTK_WIDGET_REALIZED (tree_view))
     {
-      gint dy;
+      gint dy, dx;
+      gint updateX;
+      gint updateY;
+      gint invalidateAllWindow=0;
 	
-      gdk_window_move (tree_view->priv->bin_window,
-		       - tree_view->priv->hadjustment->value,
-		       TREE_VIEW_HEADER_HEIGHT (tree_view));
-      gdk_window_move (tree_view->priv->header_window,
-		       - tree_view->priv->hadjustment->value,
-		       0);
-      dy = tree_view->priv->dy - (int) tree_view->priv->vadjustment->value;
-      if (dy && tree_view->priv->edited_column)
-	{
-	  if (GTK_IS_WIDGET (tree_view->priv->edited_column->editable_widget))
-	    {
-	      GList *list;
-	      GtkWidget *widget;
-	      GtkTreeViewChild *child = NULL;
+      gint pm_height;
+      gint n1;
+      gint n2;
 
-	      widget = GTK_WIDGET (tree_view->priv->edited_column->editable_widget);
-	      adjust_allocation (widget, 0, dy); 
+      if (GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] &&
+	  GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] != (GdkPixmap*) GDK_PARENT_RELATIVE)
+        gdk_drawable_get_size (GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)],
+			       NULL, &pm_height);
+      else
+	pm_height = 0;
 	      
-	      for (list = tree_view->priv->children; list; list = list->next)
+      if (pm_height) 
 		{
-		  child = (GtkTreeViewChild *)list->data;
-		  if (child->widget == widget)
+          n1=(gint) (tree_view->priv->dy / pm_height);
+          n2=(gint) (tree_view->priv->vadjustment->value / pm_height);
+        } 
+      else
 		    {
-		      child->y += dy;
-		      break;
+	  n1=n2=0;
+	};
+
+      if ((n1 != n2) || GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] == (GdkPixmap*) GDK_PARENT_RELATIVE)
+	{
+          dy = 0;
+	  updateY = 1;
+
+          dx = 0;
+	  updateX = 1;
+
+	  invalidateAllWindow=1;
 		    }
+      else
+	{
+
+	  if (tree_view->priv->dy < 0)
+	    {
+	      dy = 0;
+	      updateY = 1;
+	      invalidateAllWindow=1;
+	    }
+	  else
+	    {
+	      dy = tree_view->priv->dy - (int) tree_view->priv->vadjustment->value;
+	      updateY = (dy != 0);
 		}
+
+	  if (tree_view->priv->bgscroll_hor == GTK_TREE_VIEW_BG_SCROLL_MOVING)
+	    {
+	      updateX=(tree_view->priv->dx < 0);
+	      tree_view->priv->dx = 0;
+	      dx=0;
+	    }
+	  else if (tree_view->priv->dx >=0)
+	    {
+	      dx = tree_view->priv->dx - (int) tree_view->priv->hadjustment->value;
+	      updateX = (dx != 0);
+	    }
+	  else
+	    {
+	      dx = -tree_view->priv->dx - (int) tree_view->priv->hadjustment->value;
+	      updateX = 1;
+	      invalidateAllWindow=1;
 	    }
 	}
-      gdk_window_scroll (tree_view->priv->bin_window, 0, dy);
 
-      if (tree_view->priv->dy != (int) tree_view->priv->vadjustment->value)
+      if (tree_view->priv->bgscroll_hor == GTK_TREE_VIEW_BG_SCROLL_MOVING)
+	{
+          if (tree_view->priv->bgscroll_ver == GTK_TREE_VIEW_BG_SCROLL_MOVING) 
+	    {
+	      gdk_window_move (tree_view->priv->bin_window,
+			       -tree_view->priv->hadjustment->value,
+			       TREE_VIEW_HEADER_HEIGHT (tree_view)-Y_OFFSET(tree_view));
+	      gdk_window_move (tree_view->priv->header_window,
+			       -tree_view->priv->hadjustment->value,
+			       0);
+	    }
+	  else
+	    {
+	      gdk_window_move (tree_view->priv->bin_window,
+			       -tree_view->priv->hadjustment->value,
+			       TREE_VIEW_HEADER_HEIGHT (tree_view));
+	      gdk_window_move (tree_view->priv->header_window,
+			       -tree_view->priv->hadjustment->value,
+			       0);
+	    }
+	}
+      else
+	{
+          if (tree_view->priv->bgscroll_ver == GTK_TREE_VIEW_BG_SCROLL_MOVING) 
+	    {
+	      gdk_window_move (tree_view->priv->bin_window,
+			       0,
+			       TREE_VIEW_HEADER_HEIGHT (tree_view)-Y_OFFSET(tree_view));
+	      gdk_window_move (tree_view->priv->header_window,
+			       -tree_view->priv->hadjustment->value,
+			       0);
+	    }
+	  else
+	    {
+	      gdk_window_move (tree_view->priv->bin_window,
+			       0,
+			       TREE_VIEW_HEADER_HEIGHT (tree_view));
+	      gdk_window_move (tree_view->priv->header_window,
+			       -tree_view->priv->hadjustment->value,
+			       0);
+	    }
+	}
+
+      if (updateX || updateY)
+        {
+
+	  GdkRectangle invalid_rect;
+
+	  if (invalidateAllWindow)
+	    {
+	      invalid_rect.x=0;
+	      invalid_rect.width=GTK_WIDGET(tree_view)->allocation.width+tree_view->priv->hadjustment->value;
+	    }
+	  else if (tree_view->priv->bgscroll_hor != GTK_TREE_VIEW_BG_SCROLL_MOVING &&
+	      GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] &&
+	      GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] != (GdkPixmap*) GDK_PARENT_RELATIVE)
+	    {
+	      invalid_rect.x=0;
+	      invalid_rect.width=GTK_WIDGET(tree_view)->allocation.width;
+	    }
+	  else
+	    {
+	      gint bin_window_width;
+
+	      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+				      &bin_window_width, NULL);
+
+	      if (dx == 0)
+		{
+		  invalid_rect.x=tree_view->priv->hadjustment->value;
+		  invalid_rect.width=bin_window_width;
+		}
+	      else if (dx < 0)
+		{
+		  /* scroll right */
+		  invalid_rect.x=bin_window_width+dx;
+		  invalid_rect.width=-dx;
+		}
+	      else 
+		{
+		  /* scroll left */
+		  invalid_rect.x=0;
+		  invalid_rect.width=dx;
+		}
+	    }
+
+	  if (invalidateAllWindow)
+	    {
+	      gint bin_window_height;
+
+	      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+				     NULL, &bin_window_height);
+	      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+	      invalid_rect.y=0+Y_OFFSET(tree_view);
+
+	      invalid_rect.height=bin_window_height;
+
+	      gdk_window_invalidate_rect (tree_view->priv->bin_window, &invalid_rect, TRUE);
+
+	    }
+	  else if (!GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] ||
+		   GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] == (GdkPixmap*) GDK_PARENT_RELATIVE)
+	    {
+	      gdk_window_scroll (tree_view->priv->bin_window, dx, dy);
+	    }
+	  else 
+	    {
+	      if (tree_view->priv->bgscroll_hor != GTK_TREE_VIEW_BG_SCROLL_MOVING &&
+		  tree_view->priv->bgscroll_ver != GTK_TREE_VIEW_BG_SCROLL_MOVING)
+		{
+		  if (dy == 0)
+		    {
+		      gint bin_window_height;
+
+		      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					     NULL, &bin_window_height);
+		      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+		      invalid_rect.y=0+Y_OFFSET(tree_view);
+		      invalid_rect.height=bin_window_height;
+		    }
+		  else if (dy > 0)
+		    {
+		      /* scroll down */
+		      gint bin_window_height;
+
+		      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					     NULL, &bin_window_height);
+		      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+		      invalid_rect.y=0+Y_OFFSET(tree_view);
+		      invalid_rect.height=bin_window_height;
+		    }
+		  else
+		    {
+		      /* scroll up */
+		      gint bin_window_height;
+
+		      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					     NULL, &bin_window_height);
+		      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+		      invalid_rect.y=0+Y_OFFSET(tree_view);
+		      invalid_rect.height=bin_window_height;
+		    }
+		}
+	      else if (tree_view->priv->bgscroll_ver != GTK_TREE_VIEW_BG_SCROLL_MOVING)
+		{
+		  gint bin_window_height;
+
+		  gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					 NULL, &bin_window_height);
+		  bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+		  invalid_rect.y=0;
+		  invalid_rect.height=bin_window_height;
+		}
+	      else
+		{
+		  if (dy == 0)
+		    {
+		      gint bin_window_height;
+
+		      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					     NULL, &bin_window_height);
+		      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+		      invalid_rect.y=0+Y_OFFSET(tree_view);
+		      invalid_rect.height=bin_window_height;
+		    }
+		  else if (dy > 0)
+		    {
+		      /* scroll up */
+		      invalid_rect.y=0+Y_OFFSET(tree_view);
+		      invalid_rect.height=dy;
+		    }
+		  else
+		    {
+		      /* scroll down */
+		      gint bin_window_height;
+
+		      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					     NULL, &bin_window_height);
+		      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+		      invalid_rect.y=bin_window_height+dy+Y_OFFSET(tree_view);
+		      invalid_rect.height=-dy;
+		    }
+		}
+
+	      gdk_window_invalidate_rect (tree_view->priv->bin_window, &invalid_rect, TRUE);
+	    }
+        }
+
+      if (updateX)
+	{
+          /* update our dx and first_column */
+          tree_view->priv->dx = (int) tree_view->priv->hadjustment->value;
+
+          gtk_tree_view_dx_to_first_column (tree_view);
+	}
+
+      if (updateY)
         {
           /* update our dy and top_row */
           tree_view->priv->dy = (int) tree_view->priv->vadjustment->value;
@@ -10536,9 +11209,136 @@ gtk_tree_view_adjustment_changed (GtkAdj
             gtk_tree_view_dy_to_top_row (tree_view);
 	}
 
+      if ((updateX || updateY) && tree_view->priv->edited_column)
+	{
+	  if (GTK_IS_WIDGET (tree_view->priv->edited_column->editable_widget))
+	    {
+	      GList *list;
+	      GtkWidget *widget;
+	      GtkTreeViewChild *child = NULL;
+
+	      gboolean childVisible = FALSE;
+	      gint x_offset=0;
+	      gint y_offset=0;
+
+	      gboolean seenFirstColumn;
+
+	      gint vertical_separator;
+	      gint horizontal_separator;
+  
+              gtk_widget_style_get (GTK_WIDGET(tree_view),
+				    "vertical-separator", &vertical_separator,
+				    "horizontal-separator", &horizontal_separator,
+				    NULL);
+	      x_offset+= horizontal_separator / 2;
+
+	      widget = GTK_WIDGET (tree_view->priv->edited_column->editable_widget);
+
+              for (list = tree_view->priv->children; list; list = list->next)
+                {
+                  child = (GtkTreeViewChild *)list->data;
+                  if (child->widget == widget)
+                    {
+                      break;
+                    }
+                }
+
+	      x_offset += tree_view->priv->first_column_dx;
+	      seenFirstColumn = childVisible = (tree_view->priv->first_column==NULL);
+	      for (list = tree_view->priv->columns; 
+		   list;
+		   list = list->next)
+		{
+		  if (tree_view->priv->first_column && (list->data == tree_view->priv->first_column->data))
+		    seenFirstColumn = TRUE;
+
+		  if (list->data == tree_view->priv->edited_column)
+		    {
+		      childVisible = seenFirstColumn;
+		      break;
+		    }
+
+		  if (seenFirstColumn)
+                    x_offset += ((GtkTreeViewColumn*) (list->data))->width;
+		}
+
+	      if (childVisible)
+		{
+		  if (tree_view->priv->bgscroll_ver != GTK_TREE_VIEW_BG_SCROLL_MOVING ||
+		      !GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] ||
+		      GTK_WIDGET(tree_view)->style->bg_pixmap[GTK_WIDGET_STATE (tree_view)] == (GdkPixmap*) GDK_PARENT_RELATIVE)
+		    {
+		      gint bin_window_height;
+
+		      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					     NULL, &bin_window_height);
+		      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+
+		      y_offset += child->node_offset - tree_view->priv->dy ;
+
+		      /* we have to actively hide the edit widget when we are outside
+		       * the visible page; otherwise the widget reappears at another
+		       * instance of the tiled background (which will obviously be the 
+		       * wrong place)
+		       */
+		      if ((y_offset < 0) || (y_offset > bin_window_height))
+			childVisible = FALSE;
+		    }
+		  else
+		    {
+		      gint bin_window_height;
+
+		      gdk_drawable_get_size (GTK_WIDGET(tree_view)->window,
+					     NULL, &bin_window_height);
+		      bin_window_height -= TREE_VIEW_HEADER_HEIGHT (tree_view);
+
+		      y_offset = child->y;
+
+		      /* we have to update the y position of the edit widget
+		       * if we cross the break between two tiled background pictures
+		       */
+		      y_offset += (n1-n2)*pm_height;
+
+		      /* we have to actively hide the edit widget when we are outside
+		       * the visible page; otherwise the widget reappears at another
+		       * instance of the tiled background (which will obviously be the 
+		       * wrong place)
+		       */
+		      if ((child->node_offset > tree_view->priv->dy ) &&
+			  (child->node_offset < tree_view->priv->dy + bin_window_height))
+			;
+		      else
+			childVisible = FALSE;
+
+		    }
+
+
+		}
+	      
+	      //	      adjust_allocation (widget, child->x-x_offset, child->y-y_offset); 
+
+	      child->x=x_offset;
+	      child->y=y_offset;
+
+	      if (!childVisible)
+		gdk_window_hide (widget->window);
+	      else
+		{
+		  gdk_window_show (widget->window);
+	          gdk_window_move (widget->window,
+			           child->x,
+			           child->y);
+		}
+	    }
+	}
+
+      if (updateX || updateY)
+	{
       gdk_window_process_updates (tree_view->priv->header_window, TRUE);
       gdk_window_process_updates (tree_view->priv->bin_window, TRUE);
     }
+    }
 }
 
 
@@ -10673,6 +11473,10 @@ gtk_tree_view_set_model (GtkTreeView  *t
       tree_view->priv->fixed_height_check = 0;
       tree_view->priv->fixed_height = -1;
       tree_view->priv->dy = tree_view->priv->top_row_dy = 0;
+      tree_view->priv->dx = tree_view->priv->first_column_dx = 0;
+
+      tree_view->priv->dragwindow_anchor_set = FALSE;
+      tree_view->priv->dragwindow_anchor = GTK_ANCHOR_CENTER;
     }
 
   tree_view->priv->model = model;
@@ -10873,6 +11677,7 @@ gtk_tree_view_set_headers_visible (GtkTr
 				   gboolean     headers_visible)
 {
   gint x, y;
+  gint header_height;
   GList *list;
   GtkTreeViewColumn *column;
 
@@ -10884,23 +11689,30 @@ gtk_tree_view_set_headers_visible (GtkTr
     return;
 
   if (headers_visible)
+    {
     GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_HEADERS_VISIBLE);
+      header_height = TREE_VIEW_HEADER_HEIGHT (tree_view);
+    }
   else
+    {
+      header_height = TREE_VIEW_HEADER_HEIGHT (tree_view);
     GTK_TREE_VIEW_UNSET_FLAG (tree_view, GTK_TREE_VIEW_HEADERS_VISIBLE);
+    }
 
   if (GTK_WIDGET_REALIZED (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));
+	  gdk_window_move_resize (tree_view->priv->bin_window, x, y  + header_height, tree_view->priv->width, GTK_WIDGET (tree_view)->allocation.height - header_height);
 
           if (GTK_WIDGET_MAPPED (tree_view))
             gtk_tree_view_map_buttons (tree_view);
  	}
       else
 	{
-	  gdk_window_move_resize (tree_view->priv->bin_window, x, y, tree_view->priv->width, tree_view->priv->height);
+	  gdk_window_move_resize (tree_view->priv->bin_window, x, y - header_height, tree_view->priv->width, GTK_WIDGET (tree_view->priv->bin_window)->allocation.height);
 
 	  for (list = tree_view->priv->columns; list; list = list->next)
 	    {
@@ -10915,7 +11727,6 @@ gtk_tree_view_set_headers_visible (GtkTr
   tree_view->priv->vadjustment->page_increment = (GTK_WIDGET (tree_view)->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);
 
   gtk_widget_queue_resize (GTK_WIDGET (tree_view));
 
@@ -10923,6 +11734,215 @@ gtk_tree_view_set_headers_visible (GtkTr
 }
 
 /**
+ * gtk_tree_view_get_bg_scrolling:
+ * @tree_view: A #GtkTreeView.
+ * @hor_bg_scrolling: the policy used for background placement in case of horizontol scrolling
+ * @ver_bg_scrolling: the policy used for background placement in case of vertical scrolling
+ *
+ * Returns %TRUE if the the @tree_view has scrollbars attached.
+ *
+ * Return value: Whether the @tree_view has scrollbars and the policy used for background placement.
+ **/
+gboolean
+gtk_tree_view_get_bg_scrolling (GtkTreeView          *tree_view,
+                                GtkTreeViewBgScroll  *hor_bg_scrolling,
+                                GtkTreeViewBgScroll  *ver_bg_scrolling)
+{
+  gboolean result=FALSE;
+
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
+
+  if (tree_view->priv->hadjustment)
+    {
+      if (hor_bg_scrolling)
+        *hor_bg_scrolling = tree_view->priv->bgscroll_hor;
+      result = TRUE;
+    }
+  else
+    {
+      if (hor_bg_scrolling)
+        *hor_bg_scrolling = GTK_TREE_VIEW_BG_SCROLL_NONE;
+    }
+
+  if (tree_view->priv->vadjustment)
+    {
+      if (ver_bg_scrolling)
+	*ver_bg_scrolling = tree_view->priv->bgscroll_ver;
+      result = TRUE;
+    }
+  else
+    {
+      if (ver_bg_scrolling)
+        *ver_bg_scrolling = GTK_TREE_VIEW_BG_SCROLL_NONE;
+    }
+
+  return result;
+}
+
+/**
+ * gtk_tree_view_set_bg_scrolling:
+ * @tree_view: A #GtkTreeView.
+ * @hor_bg_scrolling: the policy used for background placement in case of horizontol scrolling
+ * @ver_bg_scrolling: the policy used for background placement in case of vertical scrolling
+ *
+ * Sets the background placement in case of scrolling.
+ **/
+
+void
+gtk_tree_view_set_bg_scrolling (GtkTreeView         *tree_view,
+			        GtkTreeViewBgScroll hor_bg_scrolling,
+				GtkTreeViewBgScroll ver_bg_scrolling)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+  if ((hor_bg_scrolling ==  GTK_TREE_VIEW_BG_SCROLL_DEFAULT) &&
+      (tree_view->priv->bgscroll_hor == GTK_TREE_VIEW_BG_SCROLL_FIXED))
+    hor_bg_scrolling = GTK_TREE_VIEW_BG_SCROLL_FIXED;
+  else if ((hor_bg_scrolling ==  GTK_TREE_VIEW_BG_SCROLL_FIXED) &&
+      (tree_view->priv->bgscroll_hor == GTK_TREE_VIEW_BG_SCROLL_DEFAULT))
+    hor_bg_scrolling = GTK_TREE_VIEW_BG_SCROLL_DEFAULT;
+
+  if ((ver_bg_scrolling ==  GTK_TREE_VIEW_BG_SCROLL_DEFAULT) &&
+      (tree_view->priv->bgscroll_ver == GTK_TREE_VIEW_BG_SCROLL_FIXED))
+    ver_bg_scrolling = GTK_TREE_VIEW_BG_SCROLL_FIXED;
+  else if ((ver_bg_scrolling ==  GTK_TREE_VIEW_BG_SCROLL_FIXED) &&
+      (tree_view->priv->bgscroll_ver == GTK_TREE_VIEW_BG_SCROLL_DEFAULT))
+    ver_bg_scrolling = GTK_TREE_VIEW_BG_SCROLL_DEFAULT;
+
+
+  if (hor_bg_scrolling != GTK_TREE_VIEW_BG_SCROLL_NONE) 
+    {
+      if (tree_view->priv->bgscroll_hor != hor_bg_scrolling)
+	{
+	  if (hor_bg_scrolling == GTK_TREE_VIEW_BG_SCROLL_MOVING)
+	    {
+	      /* from FIXED to MOVING */
+	      if (tree_view->priv->hadjustment)
+		{
+		  GList* list;
+		  gint offset = 0;
+		  gboolean rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
+
+		  if (tree_view->priv->first_column)
+		    {
+		      for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+			   (list != NULL) && (list != tree_view->priv->first_column);
+			   list = (rtl ? list->prev : list->next))
+			{
+			  offset +=((GtkTreeViewColumn*) (list->data))->width;
+			}
+		    }
+
+                  tree_view->priv->bgscroll_hor = hor_bg_scrolling;
+	          gtk_tree_view_set_first_column(tree_view, NULL, 0);
+
+		  tree_view->priv->dx *= -1;
+                  gtk_tree_view_adjustment_changed (tree_view->priv->hadjustment, tree_view);
+		}
+	    }
+	  else 
+	    {
+	      /* from MOVING to FIXED */
+	      if (tree_view->priv->hadjustment)
+		{
+		  GList* list;
+		  gint offset = tree_view->priv->hadjustment->value;
+		  gboolean rtl = (gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL);
+
+		  GtkTreeViewColumn* column=NULL;
+
+		  for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns));
+		       (list != NULL) && (offset >= ((GtkTreeViewColumn*) (list->data))->width);
+		       list = (rtl ? list->prev : list->next))
+		    {
+		      column=(GtkTreeViewColumn*) (list->data);
+		      offset -= column->width;
+		    }
+
+		  tree_view->priv->dx=0;
+                  tree_view->priv->bgscroll_hor = hor_bg_scrolling;
+		  if (offset==0)
+	            gtk_tree_view_set_first_column(tree_view, column, 0);
+		  else if (column==NULL)
+	            gtk_tree_view_set_first_column(tree_view, column, -offset);
+		  else
+	            gtk_tree_view_set_first_column(tree_view, column, column->width-offset);
+
+                  gtk_tree_view_adjustment_changed (tree_view->priv->hadjustment, tree_view);
+		}
+	    }
+	}
+    }
+
+  if (ver_bg_scrolling != GTK_TREE_VIEW_BG_SCROLL_NONE) 
+    {
+      if (tree_view->priv->bgscroll_ver != ver_bg_scrolling)
+	{
+	  if (ver_bg_scrolling == GTK_TREE_VIEW_BG_SCROLL_MOVING)
+	    {
+	      /* from FIXED to MOVING */
+	      if (tree_view->priv->vadjustment)
+		{
+		  tree_view->priv->dy=0;
+                  tree_view->priv->bgscroll_ver = ver_bg_scrolling;
+
+                  gtk_tree_view_adjustment_changed (tree_view->priv->vadjustment, tree_view);
+		}
+	    }
+	  else 
+	    {
+	      /* from MOVING to FIXED */
+	      if (tree_view->priv->vadjustment)
+		{
+		  tree_view->priv->dy=-1;
+                  tree_view->priv->bgscroll_ver = ver_bg_scrolling;
+
+                  gtk_tree_view_adjustment_changed (tree_view->priv->vadjustment, tree_view);
+		}
+	    }
+ 	}
+    }
+}
+
+gboolean          
+gtk_tree_view_get_enable_dragwindow_anchor (GtkTreeView *tree_view)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), -1);
+
+  return tree_view->priv->dragwindow_anchor_set;
+}
+
+void
+gtk_tree_view_set_enable_dragwindow_anchor (GtkTreeView  *tree_view,
+                                            gboolean     setting)
+{
+
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+  tree_view->priv->dragwindow_anchor_set = setting;
+}
+
+gboolean
+gtk_tree_view_get_dragwindow_anchor (GtkTreeView   *tree_view,
+                                     GtkAnchorType *anchor)
+{
+  g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), -1);
+
+  *anchor = tree_view->priv->dragwindow_anchor;
+  return tree_view->priv->dragwindow_anchor_set;
+}
+
+void 
+gtk_tree_view_set_dragwindow_anchor (GtkTreeView    *tree_view,
+                                     GtkAnchorType  anchor)
+{
+
+  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+
+  tree_view->priv->dragwindow_anchor = anchor;
+}
+
+/**
  * gtk_tree_view_columns_autosize:
  * @tree_view: A #GtkTreeView.
  *
@@ -12992,7 +14012,7 @@ gtk_tree_view_widget_to_tree_coords (Gtk
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
   if (tx)
-    *tx = wx + tree_view->priv->hadjustment->value;
+    *tx = wx + tree_view->priv->dx;
   if (ty)
     *ty = wy + tree_view->priv->dy;
 }
@@ -13024,7 +14044,7 @@ gtk_tree_view_tree_to_widget_coords (Gtk
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
   if (wx)
-    *wx = tx - tree_view->priv->hadjustment->value;
+    *wx = tx - tree_view->priv->dx;
   if (wy)
     *wy = ty - tree_view->priv->dy;
 }
@@ -13117,9 +14137,9 @@ gtk_tree_view_convert_widget_to_bin_wind
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
   if (bx)
-    *bx = wx + tree_view->priv->hadjustment->value;
+    *bx = wx + tree_view->priv->dx;
   if (by)
-    *by = wy - TREE_VIEW_HEADER_HEIGHT (tree_view);
+    *by = wy - TREE_VIEW_HEADER_HEIGHT (tree_view) + Y_OFFSET (tree_view);
 }
 
 /**
@@ -13145,9 +14165,9 @@ gtk_tree_view_convert_bin_window_to_widg
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
   if (wx)
-    *wx = bx - tree_view->priv->hadjustment->value;
+    *wx = bx - tree_view->priv->dx;
   if (wy)
-    *wy = by + TREE_VIEW_HEADER_HEIGHT (tree_view);
+    *wy = by + TREE_VIEW_HEADER_HEIGHT (tree_view) - Y_OFFSET (tree_view);
 }
 
 /**
@@ -13175,7 +14195,7 @@ gtk_tree_view_convert_tree_to_bin_window
   if (bx)
     *bx = tx;
   if (by)
-    *by = ty - tree_view->priv->dy;
+    *by = RBTREE_Y_TO_TREE_WINDOW_Y(tree_view, ty);
 }
 
 /**
@@ -13203,7 +14223,7 @@ gtk_tree_view_convert_bin_window_to_tree
   if (tx)
     *tx = bx;
   if (ty)
-    *ty = by + tree_view->priv->dy;
+    *ty = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, by);
 }
 
 
@@ -13701,12 +14721,25 @@ gtk_tree_view_create_row_drag_icon (GtkT
   expose_area.width = bin_window_width + 2;
   expose_area.height = background_area.height + 2;
 
+  if (widget->style->bg_pixmap[GTK_WIDGET_STATE (widget)] &&
+      widget->style->bg_pixmap[GTK_WIDGET_STATE (widget)] != (GdkPixmap*) GDK_PARENT_RELATIVE)
+    {
+      gdk_draw_rectangle (drawable,
+			  widget->style->base_gc[GTK_STATE_ACTIVE],
+			  TRUE,
+			  0, 0,
+			  bin_window_width + 2,
+			  background_area.height + 2);
+    }
+  else
+    {
   gdk_draw_rectangle (drawable,
                       widget->style->base_gc [GTK_WIDGET_STATE (widget)],
                       TRUE,
                       0, 0,
                       bin_window_width + 2,
                       background_area.height + 2);
+    }
 
   rtl = gtk_widget_get_direction (GTK_WIDGET (tree_view)) == GTK_TEXT_DIR_RTL;
 
@@ -13774,12 +14807,25 @@ gtk_tree_view_create_row_drag_icon (GtkT
       cell_offset += column->width;
     }
 
+  if (widget->style->bg_pixmap[GTK_WIDGET_STATE (widget)] &&
+      widget->style->bg_pixmap[GTK_WIDGET_STATE (widget)] != (GdkPixmap*) GDK_PARENT_RELATIVE)
+    {
+      gdk_draw_rectangle (drawable,
+			  widget->style->text_gc[GTK_STATE_ACTIVE],
+			  FALSE,
+			  0, 0,
+			  bin_window_width + 1,
+			  background_area.height + 1);
+    }
+  else 
+    {
   gdk_draw_rectangle (drawable,
                       widget->style->black_gc,
                       FALSE,
                       0, 0,
                       bin_window_width + 1,
                       background_area.height + 1);
+    }
 
   return drawable;
 }
@@ -15046,8 +16092,7 @@ gtk_tree_view_state_changed (GtkWidget  
 
   if (GTK_WIDGET_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]);
+      SET_BACKGROUND(widget,tree_view);
     }
 
   gtk_widget_queue_draw (widget);
diff -burp gtk+-2.18.4.org/gtk/gtktypefuncs.c gtk+-2.18.4/gtk/gtktypefuncs.c
--- gtk+-2.18.4.org/gtk/gtktypefuncs.c	2010-01-16 22:54:45.000000000 +0100
+++ gtk+-2.18.4/gtk/gtktypefuncs.c	2010-01-16 21:55:54.000000000 +0100
@@ -352,6 +352,7 @@
 *tp++ = gtk_tree_selection_get_type();
 *tp++ = gtk_tree_sortable_get_type();
 *tp++ = gtk_tree_store_get_type();
+*tp++ = gtk_tree_view_bg_scroll_get_type();
 *tp++ = gtk_tree_view_column_get_type();
 *tp++ = gtk_tree_view_column_sizing_get_type();
 *tp++ = gtk_tree_view_drop_position_get_type();
diff -burp gtk+-2.18.4.org/gtk/gtktreeprivate.h gtk+-2.18.4/gtk/gtktreeprivate.h
--- gtk+-2.18.4.org/gtk/gtktreeprivate.h	2009-12-01 04:21:24.000000000 +0100
+++ gtk+-2.18.4/gtk/gtktreeprivate.h	2010-01-16 21:35:20.000000000 +0100
@@ -105,6 +105,9 @@ struct _GtkTreeViewPrivate
   GtkAdjustment *hadjustment;
   GtkAdjustment *vadjustment;
 
+  GtkTreeViewBgScroll bgscroll_hor : 2;
+  GtkTreeViewBgScroll bgscroll_ver : 2;
+
   GdkWindow *bin_window;
   GdkWindow *header_window;
   GdkWindow *drag_window;
@@ -115,11 +118,14 @@ struct _GtkTreeViewPrivate
   GtkTreeRowReference *last_button_press_2;
 
   /* bin_window offset */
+  GList *first_column;
   GtkTreeRowReference *top_row;
+  gint first_column_dx;
   gint top_row_dy;
   /* dy == y pos of top_row + top_row_dy */
   /* we cache it for simplicity of the code */
   gint dy;
+  gint dx;
   gint drag_column_x;
   gint cursor_offset;
 
@@ -176,6 +182,9 @@ struct _GtkTreeViewPrivate
   GtkTreeViewDropPosition drag_dest_pos;
   guint open_dest_timeout;
 
+  gboolean dragwindow_anchor_set;
+  GtkAnchorType dragwindow_anchor;
+
   gint pressed_button;
   gint press_start_x;
   gint press_start_y;
diff -burp gtk+-2.18.4.org/gtk/gtkalias.h gtk+-2.18.4/gtk/gtkalias.h
--- gtk+-2.18.4.org/gtk/gtkalias.h	2009-12-01 05:10:28.000000000 +0100
+++ gtk+-2.18.4/gtk/gtkalias.h	2009-12-30 22:05:28.000000000 +0100
@@ -804,6 +804,9 @@ extern __typeof (gtk_tree_view_column_si
 extern __typeof (gtk_tree_view_drop_position_get_type) IA__gtk_tree_view_drop_position_get_type __attribute((visibility("hidden"))) G_GNUC_CONST;
 #define gtk_tree_view_drop_position_get_type IA__gtk_tree_view_drop_position_get_type
 
+extern __typeof (gtk_tree_view_bg_scroll_get_type) IA__gtk_tree_view_bg_scroll_get_type __attribute((visibility("hidden"))) G_GNUC_CONST;
+#define gtk_tree_view_bg_scroll_get_type IA__gtk_tree_view_bg_scroll_get_type
+
 extern __typeof (gtk_button_box_style_get_type) IA__gtk_button_box_style_get_type __attribute((visibility("hidden"))) G_GNUC_CONST;
 #define gtk_button_box_style_get_type IA__gtk_button_box_style_get_type
 
diff -burp gtk+-2.18.4.org/gtk/gtktypebuiltins.c gtk+-2.18.4/gtk/gtktypebuiltins.c
--- gtk+-2.18.4.org/gtk/gtktypebuiltins.c	2009-12-01 05:10:28.000000000 +0100
+++ gtk+-2.18.4/gtk/gtktypebuiltins.c	2010-01-16 21:52:41.000000000 +0100
@@ -1897,6 +1897,23 @@ gtk_tree_model_flags_get_type (void)
 
 /* enumerations from "gtktreeview.h" */
 GType
+gtk_tree_view_bg_scroll_get_type (void)
+{
+    static GType etype = 0;
+    if (G_UNLIKELY(etype == 0)) {
+        static const GEnumValue values[] = {
+            { GTK_TREE_VIEW_BG_SCROLL_DEFAULT, "GTK_TREE_VIEW_BG_SCROLL_DEFAULT", "default" },
+            { GTK_TREE_VIEW_BG_SCROLL_FIXED, "GTK_TREE_VIEW_BG_SCROLL_FIXED", "fixed" },
+            { GTK_TREE_VIEW_BG_SCROLL_MOVING, "GTK_TREE_VIEW_BG_SCROLL_MOVING", "moving" },
+            { GTK_TREE_VIEW_BG_SCROLL_NONE, "GTK_TREE_VIEW_BG_SCROLL_NONE", "none" },
+            { 0, NULL, NULL }
+        };
+        etype = g_enum_register_static (g_intern_static_string ("GtkTreeViewBgScroll"), values);
+    }
+    return etype;
+}
+
+GType
 gtk_tree_view_drop_position_get_type (void)
 {
     static GType etype = 0;
diff -burp gtk+-2.18.4.org/gtk/gtktreeview.h gtk+-2.18.4/gtk/gtktreeview.h
--- gtk+-2.18.4.org/gtk/gtktreeview.h	2009-06-04 21:18:04.000000000 +0200
+++ gtk+-2.18.4/gtk/gtktreeview.h	2010-01-16 21:42:37.000000000 +0100
@@ -32,6 +32,23 @@
 
 G_BEGIN_DECLS
 
+/* the background image can be place in 2 different ways in the treeview:
+ * GTK_TREE_VIEW_BG_SCROLL_FIXED:   the background image stays fixed in the background and the tree/list scrolls
+ *                                  over the image
+ * GTK_TREE_VIEW_BG_SCROLL_MOVING:  the background image scrolls along with the text of the tree/list 
+ * GTK_TREE_VIEW_BG_SCROLL_NONE:    value to let the value of a scrolling property unchanged
+ *                                  (cf function gtk_tree_view_set_bg_scrolling)
+ * GTK_TREE_VIEW_BG_SCROLL_DEFAULT: the default setting for the background image scrolling (MOVING)
+ *
+ */
+
+typedef enum
+{
+  GTK_TREE_VIEW_BG_SCROLL_DEFAULT,
+  GTK_TREE_VIEW_BG_SCROLL_FIXED,
+  GTK_TREE_VIEW_BG_SCROLL_MOVING,
+  GTK_TREE_VIEW_BG_SCROLL_NONE
+} GtkTreeViewBgScroll;
 
 typedef enum
 {
@@ -155,6 +172,23 @@ void                   gtk_tree_view_set
 gboolean               gtk_tree_view_get_headers_visible           (GtkTreeView               *tree_view);
 void                   gtk_tree_view_set_headers_visible           (GtkTreeView               *tree_view,
 								    gboolean                   headers_visible);
+
+gboolean               gtk_tree_view_get_bg_scrolling              (GtkTreeView               *tree_view,
+                                                                    GtkTreeViewBgScroll       *hor_bg_scrolling,
+                                                                    GtkTreeViewBgScroll       *ver_bg_scrolling);
+void                   gtk_tree_view_set_bg_scrolling              (GtkTreeView               *tree_view,
+								    GtkTreeViewBgScroll        hor_bg_scrolling,
+								    GtkTreeViewBgScroll        ver_bg_scrolling);
+
+gboolean               gtk_tree_view_get_dragwindow_anchor         (GtkTreeView               *tree_view,
+                                                                    GtkAnchorType             *anchor);
+void                   gtk_tree_view_set_dragwindow_anchor         (GtkTreeView               *tree_view,
+                                                                    GtkAnchorType              anchor);
+
+gboolean               gtk_tree_view_get_enable_dragwindow_anchor  (GtkTreeView               *tree_view);
+void                   gtk_tree_view_set_enable_dragwindow_anchor  (GtkTreeView               *tree_view,
+                                                                    gboolean                   setting);
+
 void                   gtk_tree_view_columns_autosize              (GtkTreeView               *tree_view);
 gboolean               gtk_tree_view_get_headers_clickable         (GtkTreeView *tree_view);
 void                   gtk_tree_view_set_headers_clickable         (GtkTreeView               *tree_view,
diff -burp gtk+-2.18.4.org/gtk/gtktypebuiltins.h gtk+-2.18.4/gtk/gtktypebuiltins.h
--- gtk+-2.18.4.org/gtk/gtktypebuiltins.h	2009-12-01 05:10:30.000000000 +0100
+++ gtk+-2.18.4/gtk/gtktypebuiltins.h	2009-12-30 21:44:13.000000000 +0100
@@ -285,6 +285,8 @@ GType gtk_tree_model_flags_get_type (voi
 #define GTK_TYPE_TREE_MODEL_FLAGS (gtk_tree_model_flags_get_type ())
 
 /* enumerations from "gtktreeview.h" */
+GType gtk_tree_view_bg_scroll_get_type (void) G_GNUC_CONST;
+#define GTK_TYPE_TREE_VIEW_BG_SCROLL (gtk_tree_view_bg_scroll_get_type ())
 GType gtk_tree_view_drop_position_get_type (void) G_GNUC_CONST;
 #define GTK_TYPE_TREE_VIEW_DROP_POSITION (gtk_tree_view_drop_position_get_type ())
 
diff -burp gtk+-2.18.4.org/tests/testtreeview.c gtk+-2.18.4/tests/testtreeview.c
--- gtk+-2.18.4.org/tests/testtreeview.c	2009-12-01 04:21:24.000000000 +0100
+++ gtk+-2.18.4/tests/testtreeview.c	2010-01-17 15:31:16.000000000 +0100
@@ -685,6 +685,277 @@ columns_selected (GtkOptionMenu *om, gpo
     }
 }
 
+typedef enum
+{
+  /* BACKGROUND_SCROLL_TYPES */
+  NO_BG,
+  BG_NO_SCROLL,
+  BG_HOR_SCROLL,
+  BG_VER_SCROLL,
+  BG_HOR_VER_SCROLL,
+  BG_LAST_SCROLL
+} BackGroundType;
+
+static const char *scroll_names[BG_LAST_SCROLL] = {
+  "No Background Picture",
+  "Background Picture; no scroll",
+  "Background Picture; horizontal scroll",
+  "Background Picture; vertical scroll",
+  "Background Picture; hor + ver scroll" 
+};
+
+static BackGroundType current_background_type = NO_BG;
+
+static BackGroundType
+get_background_type (void)
+{
+  return current_background_type;
+}
+
+static void
+set_background_type (GtkTreeView *tree_view, BackGroundType type)
+{
+  GtkRcStyle *rc_style;
+  GdkColor color;
+    
+  switch (type)
+    {
+    case NO_BG:
+      rc_style = gtk_rc_style_new ();
+      rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+      gdk_color_parse ("#7f7f00", &color);
+      rc_style->base[GTK_STATE_NORMAL] = color;
+      gtk_widget_modify_style (GTK_WIDGET(tree_view), rc_style);
+      gtk_rc_style_unref (rc_style);
+
+      break;
+
+    case BG_NO_SCROLL:
+      if (current_background_type==NO_BG)
+	{
+          rc_style = gtk_rc_style_new ();
+          rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+          rc_style->bg_pixmap_name[GTK_STATE_NORMAL] = strdup("background.xpm");
+          gtk_widget_modify_style (GTK_WIDGET(tree_view), rc_style);
+          gtk_rc_style_unref (rc_style);
+	};
+
+      gtk_tree_view_set_bg_scrolling (tree_view, GTK_TREE_VIEW_BG_SCROLL_FIXED, GTK_TREE_VIEW_BG_SCROLL_FIXED);
+
+      break;
+
+    case BG_HOR_SCROLL:
+      if (current_background_type==NO_BG)
+	{
+          rc_style = gtk_rc_style_new ();
+          rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+          rc_style->bg_pixmap_name[GTK_STATE_NORMAL] = strdup("background.xpm");
+          gtk_widget_modify_style (GTK_WIDGET(tree_view), rc_style);
+          gtk_rc_style_unref (rc_style);
+	};
+
+      gtk_tree_view_set_bg_scrolling (tree_view, GTK_TREE_VIEW_BG_SCROLL_MOVING, GTK_TREE_VIEW_BG_SCROLL_FIXED);
+
+      break;
+
+    case BG_VER_SCROLL:
+      if (current_background_type==NO_BG)
+	{
+          rc_style = gtk_rc_style_new ();
+          rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+          rc_style->bg_pixmap_name[GTK_STATE_NORMAL] = strdup("background.xpm");
+          gtk_widget_modify_style (GTK_WIDGET(tree_view), rc_style);
+          gtk_rc_style_unref (rc_style);
+	};
+
+      gtk_tree_view_set_bg_scrolling (tree_view, GTK_TREE_VIEW_BG_SCROLL_FIXED, GTK_TREE_VIEW_BG_SCROLL_MOVING);
+
+      break;
+
+    case BG_HOR_VER_SCROLL:
+      if (current_background_type==NO_BG)
+	{
+          rc_style = gtk_rc_style_new ();
+          rc_style->color_flags[GTK_STATE_NORMAL] = GTK_RC_BG;
+          rc_style->bg_pixmap_name[GTK_STATE_NORMAL] = strdup("background.xpm");
+          gtk_widget_modify_style (GTK_WIDGET(tree_view), rc_style);
+          gtk_rc_style_unref (rc_style);
+	};
+
+      gtk_tree_view_set_bg_scrolling (tree_view, GTK_TREE_VIEW_BG_SCROLL_MOVING, GTK_TREE_VIEW_BG_SCROLL_MOVING);
+
+      break;
+
+    default:
+      break;
+    }
+
+  current_background_type = type;
+
+}
+
+static void
+background_selected (GtkOptionMenu *om, gpointer data)
+{
+  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
+  gint hist;
+
+  hist = gtk_option_menu_get_history (om);
+
+  if (hist != get_background_type ())
+    {
+      set_background_type (tree_view, hist);
+    }
+}
+
+typedef enum
+{
+  /* DRAGWINDOW_ANCHOR_TYPES */
+  NO_DW_ANCHOR,
+  DW_ANCHOR_C,
+  DW_ANCHOR_N,
+  DW_ANCHOR_NE,
+  DW_ANCHOR_E,
+  DW_ANCHOR_SE,
+  DW_ANCHOR_S,
+  DW_ANCHOR_SW,
+  DW_ANCHOR_W,
+  DW_ANCHOR_NW,
+  DW_LAST_ANCHOR
+} DWAnchorType;
+
+static const char *dw_anchor_names[DW_LAST_ANCHOR] = {
+  "No Specific Anchor",
+  "Draw Window Anchor: Center",
+  "Draw Window Anchor: North",
+  "Draw Window Anchor: North East",
+  "Draw Window Anchor: East",
+  "Draw Window Anchor: South East",
+  "Draw Window Anchor: South",
+  "Draw Window Anchor: South West",
+  "Draw Window Anchor: West",
+  "Draw Window Anchor: North West",
+};
+
+static DWAnchorType current_dw_anchor_type = NO_DW_ANCHOR;
+
+static DWAnchorType
+get_dw_anchor_type (void)
+{
+  return current_dw_anchor_type;
+}
+
+static void
+set_dw_anchor_type (GtkTreeView *tree_view, DWAnchorType type)
+{
+  switch (type)
+    {
+    case NO_DW_ANCHOR:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, FALSE);
+      break;
+
+    case DW_ANCHOR_C:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_CENTER);
+      break;
+
+    case DW_ANCHOR_N:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_NORTH);
+      break;
+
+    case DW_ANCHOR_NE:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_NORTH_EAST);
+      break;
+
+    case DW_ANCHOR_E:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_EAST);
+      break;
+
+    case DW_ANCHOR_SE:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_SOUTH_EAST);
+      break;
+
+    case DW_ANCHOR_S:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_SOUTH);
+      break;
+
+    case DW_ANCHOR_SW:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_SOUTH_WEST);
+      break;
+
+    case DW_ANCHOR_W:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_WEST);
+      break;
+
+    case DW_ANCHOR_NW:
+      gtk_tree_view_set_enable_dragwindow_anchor (tree_view, TRUE);
+      gtk_tree_view_set_dragwindow_anchor (tree_view, GTK_ANCHOR_NORTH_WEST);
+      break;
+
+    default:
+      break;
+    }
+
+  current_dw_anchor_type = type;
+
+}
+
+static void
+dw_anchor_selected (GtkOptionMenu *om, gpointer data)
+{
+  GtkTreeView *tree_view = GTK_TREE_VIEW (data);
+  gint hist;
+
+  hist = gtk_option_menu_get_history (om);
+
+  if (hist != get_dw_anchor_type ())
+    {
+      set_dw_anchor_type (tree_view, hist);
+    }
+}
+
+static void
+button_toggled_hdr (GtkToggleButton* tb, gpointer data)
+{
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(data), gtk_toggle_button_get_active(tb));
+}
+
+static void
+button_toggled_gl (GtkToggleButton* tb, gpointer data)
+{
+  if (gtk_toggle_button_get_active(tb))
+    gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(data), GTK_TREE_VIEW_GRID_LINES_BOTH);
+  else
+    gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(data), GTK_TREE_VIEW_GRID_LINES_NONE);
+}
+
+static void
+button_toggled_exp (GtkToggleButton* tb, gpointer data)
+{
+  gtk_tree_view_set_show_expanders (GTK_TREE_VIEW(data), gtk_toggle_button_get_active(tb));
+}
+
+static void
+button_toggled_tl (GtkToggleButton* tb, gpointer data)
+{
+  gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW(data), gtk_toggle_button_get_active(tb));
+}
+
+static void
+button_toggled_indent (GtkToggleButton* tb, gpointer data)
+{
+  if (gtk_toggle_button_get_active(tb))
+    gtk_tree_view_set_level_indentation (GTK_TREE_VIEW(data), 20);
+  else
+    gtk_tree_view_set_level_indentation (GTK_TREE_VIEW(data), 0);
+}
 
 enum
 {
@@ -696,6 +967,7 @@ static GtkTargetEntry row_targets[] = {
     TARGET_GTK_TREE_MODEL_ROW }
 };
 
+
 int
 main (int    argc,
       char **argv)
@@ -706,6 +978,8 @@ main (int    argc,
   GtkWidget *table;
   GtkWidget *om;
   GtkWidget *menu;
+  GtkWidget *hb;
+  GtkWidget *cb;
   GtkTreeModel *model;
   gint i;
   
@@ -738,7 +1012,7 @@ main (int    argc,
   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
   gtk_window_set_default_size (GTK_WINDOW (window), 430, 400);
 
-  table = gtk_table_new (3, 1, FALSE);
+  table = gtk_table_new (5, 1, FALSE);
 
   gtk_container_add (GTK_CONTAINER (window), table);
 
@@ -831,17 +1105,154 @@ main (int    argc,
                     G_CALLBACK (columns_selected),
                     tv);
   
+  /* Background menu */
+
+  menu = gtk_menu_new ();
+  
+  i = 0;
+  while (i < BG_LAST_SCROLL)
+    {
+      GtkWidget *mi;
+      const char *name;
+
+      name = scroll_names[i];
+      
+      mi = gtk_menu_item_new_with_label (name);
+
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+      ++i;
+    }
+  gtk_widget_show_all (menu);
+  
+  om = gtk_option_menu_new ();
+  gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
+  
+  gtk_table_attach (GTK_TABLE (table), om,
+                    0, 1, 2, 3,
+                    0, 0, 
+                    0, 0);
+
+  g_signal_connect (om,
+                    "changed",
+                    G_CALLBACK (background_selected),
+		    tv);
+  
+
+  /* dragwindow anchor menu */
+
+  menu = gtk_menu_new ();
+  
+  i = 0;
+  while (i < DW_LAST_ANCHOR)
+    {
+      GtkWidget *mi;
+      const char *name;
+
+      name = dw_anchor_names[i];
+      
+      mi = gtk_menu_item_new_with_label (name);
+
+      gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+      ++i;
+    }
+  gtk_widget_show_all (menu);
+  
+  om = gtk_option_menu_new ();
+  gtk_option_menu_set_menu (GTK_OPTION_MENU (om), menu);
+  
+  gtk_table_attach (GTK_TABLE (table), om,
+                    0, 1, 3, 4,
+                    0, 0, 
+                    0, 0);
+
+  g_signal_connect (om,
+                    "changed",
+                    G_CALLBACK (dw_anchor_selected),
+		    tv);
+  
+
   sw = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                   GTK_POLICY_AUTOMATIC,
                                   GTK_POLICY_AUTOMATIC);
   
   gtk_table_attach (GTK_TABLE (table), sw,
-                    0, 1, 2, 3,
+                    0, 1, 4, 5,
                     GTK_EXPAND | GTK_FILL,
                     GTK_EXPAND | GTK_FILL,
                     0, 0);
   
+
+  /* tree view in scrolled window */
+
+  sw = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
+                                  GTK_POLICY_AUTOMATIC,
+                                  GTK_POLICY_AUTOMATIC);
+  
+  gtk_table_attach (GTK_TABLE (table), sw,
+                    0, 1, 4, 5,
+                    GTK_EXPAND | GTK_FILL,
+                    GTK_EXPAND | GTK_FILL,
+                    0, 0);
+
+  /* radio button strip */
+
+  hb = gtk_hbox_new(TRUE, 0);
+
+  cb = gtk_check_button_new_with_label ("headers");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), gtk_tree_view_get_headers_visible (GTK_TREE_VIEW(tv)));
+  g_signal_connect (cb,
+                    "toggled",
+                    G_CALLBACK (button_toggled_hdr),
+		    tv);
+  
+  gtk_box_pack_start (GTK_BOX(hb), cb, TRUE, TRUE, 0);
+
+  cb = gtk_check_button_new_with_label ("grid lines");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), gtk_tree_view_get_grid_lines (GTK_TREE_VIEW(tv)));
+  g_signal_connect (cb,
+                    "toggled",
+                    G_CALLBACK (button_toggled_gl),
+		    tv);
+
+  gtk_box_pack_start (GTK_BOX(hb), cb, TRUE, TRUE, 0);
+
+  cb = gtk_check_button_new_with_label ("expanders");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), gtk_tree_view_get_show_expanders (GTK_TREE_VIEW(tv)));
+  g_signal_connect (cb,
+                    "toggled",
+                    G_CALLBACK (button_toggled_exp),
+		    tv);
+
+  gtk_box_pack_start (GTK_BOX(hb), cb, TRUE, TRUE, 0);
+
+  cb = gtk_check_button_new_with_label ("tree lines");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), gtk_tree_view_get_enable_tree_lines (GTK_TREE_VIEW(tv)));
+  g_signal_connect (cb,
+                    "toggled",
+                    G_CALLBACK (button_toggled_tl),
+		    tv);
+
+  gtk_box_pack_start (GTK_BOX(hb), cb, TRUE, TRUE, 0);
+
+  cb = gtk_check_button_new_with_label ("indentation");
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cb), gtk_tree_view_get_level_indentation (GTK_TREE_VIEW(tv)) != 0);
+  g_signal_connect (cb,
+                    "toggled",
+                    G_CALLBACK (button_toggled_indent),
+		    tv);
+
+  gtk_box_pack_start (GTK_BOX(hb), cb, TRUE, TRUE, 0);
+
+  gtk_table_attach (GTK_TABLE (table), hb,
+                    0, 1, 5, 6,
+                    GTK_FILL, GTK_FILL,
+                    0, 0);
+
+
   gtk_container_add (GTK_CONTAINER (sw), tv);
   
   gtk_widget_show_all (window);
@@ -1353,6 +1764,7 @@ treestore_torture_recurse (GtkTreeStore 
       treestore_torture_recurse (store, &iter, depth);
       gtk_tree_store_remove (store, &iter);
     }
+
 }
 
 static void
