--- gtk+-2.6.4/gtk/gtkscrolledwindow.c	2004-08-09 19:59:52.000000000 +0300
+++ gtk+-2.6.4/gtk/gtkscrolledwindow.c	2005-04-06 16:19:37.898776872 +0300
@@ -289,6 +289,13 @@
 							     DEFAULT_SCROLLBAR_SPACING,
 							     G_PARAM_READABLE));
 
+  gtk_widget_class_install_style_property (widget_class,
+					   g_param_spec_boolean ("scrollbar_dislocation",
+    								 P_("Scrollbar dislocation"),
+    								 P_("Flag for having scrollbar at the outer border or container padding instead of at the inner border"),
+    								 FALSE,
+    								 G_PARAM_READABLE));
+
   signals[SCROLL_CHILD] =
     g_signal_new ("scroll_child",
                   G_TYPE_FROM_CLASS (object_class),
@@ -1062,6 +1069,73 @@
     }
 }
 
+static gdouble
+gtk_scrolled_window_get_focus_movement (GtkScrolledWindow *scrolled_window)
+{
+  GtkWidget *focus_child;
+  GtkRange *range;
+  GtkAdjustment *adj;
+  gdouble value, new_value;
+  gint x, y;
+
+  focus_child = GTK_CONTAINER(scrolled_window)->focus_child;
+  if (focus_child == NULL)
+     return 0;
+
+  while (GTK_IS_CONTAINER (focus_child) &&
+	 GTK_CONTAINER (focus_child)->focus_child)
+    {
+      focus_child = GTK_CONTAINER (focus_child)->focus_child;
+    }
+
+  range = GTK_RANGE (scrolled_window->vscrollbar);
+  adj = range->adjustment;
+  value = gtk_adjustment_get_value (adj);
+
+  gtk_widget_translate_coordinates (focus_child->parent,
+				    GTK_WIDGET(scrolled_window),
+				    focus_child->allocation.x,
+				    focus_child->allocation.y, &x, &y);
+
+  if (y < 0)
+    {
+      /* scroll up */
+      new_value = value + y;
+      if (new_value < adj->lower)
+	new_value = adj->lower;
+    }
+  else if (y + focus_child->allocation.height > adj->page_size)
+    {
+      /* scroll down */
+      new_value = value + y + focus_child->allocation.height - adj->page_size;
+      if (new_value > adj->upper - adj->page_size)
+        new_value = adj->upper - adj->page_size;
+    }
+  else
+    {
+      new_value = value;
+    }
+
+  return new_value - value;
+}
+
+static void
+gtk_scrolled_window_scroll_to_focus (GtkScrolledWindow *scrolled_window)
+{
+  GtkAdjustment *adj;
+  gdouble diff;
+
+  diff = gtk_scrolled_window_get_focus_movement (scrolled_window);
+  if (diff != 0)
+    {
+      adj = GTK_RANGE (scrolled_window->vscrollbar)->adjustment;
+
+      gtk_adjustment_set_value (adj, gtk_adjustment_get_value (adj) + diff);
+      gtk_scrolled_window_set_vadjustment (scrolled_window,
+					   GTK_ADJUSTMENT (adj));
+    }
+}
+
 static void
 gtk_scrolled_window_size_allocate (GtkWidget     *widget,
 				   GtkAllocation *allocation)
@@ -1071,17 +1145,32 @@
   GtkAllocation relative_allocation;
   GtkAllocation child_allocation;
   gint scrollbar_spacing;
-  
+  gboolean is_focus_visible, dislocate;
+  gint dislocation;
+
   g_return_if_fail (GTK_IS_SCROLLED_WINDOW (widget));
   g_return_if_fail (allocation != NULL);
 
   scrolled_window = GTK_SCROLLED_WINDOW (widget);
   bin = GTK_BIN (scrolled_window);
 
+  is_focus_visible =
+    gtk_scrolled_window_get_focus_movement (scrolled_window) == 0;
+
   scrollbar_spacing = _gtk_scrolled_window_get_scrollbar_spacing (scrolled_window);
 
   widget->allocation = *allocation;
 
+  /* See how much scrollbar needs be "dislocated" (to get it to the other
+   * edge of the border). Does not apply to all occasions. */
+  gtk_widget_style_get (GTK_WIDGET (scrolled_window),
+			"scrollbar_dislocation", &dislocate,
+			NULL);
+  if (dislocate)
+    dislocation = GTK_CONTAINER (scrolled_window)->border_width;
+  else
+    dislocation = 0;
+
   if (scrolled_window->hscrollbar_policy == GTK_POLICY_ALWAYS)
     scrolled_window->hscrollbar_visible = TRUE;
   else if (scrolled_window->hscrollbar_policy == GTK_POLICY_NEVER)
@@ -1150,10 +1239,12 @@
 	child_allocation.y = (relative_allocation.y +
 			      relative_allocation.height +
 			      scrollbar_spacing +
+			      dislocation +
 			      (scrolled_window->shadow_type == GTK_SHADOW_NONE ?
 			       0 : widget->style->ythickness));
       else
-	child_allocation.y = GTK_CONTAINER (scrolled_window)->border_width;
+	child_allocation.y = GTK_CONTAINER (scrolled_window)->border_width -
+	  dislocation;
 
       child_allocation.width = relative_allocation.width;
       child_allocation.height = hscrollbar_requisition.height;
@@ -1189,10 +1280,12 @@
 	child_allocation.x = (relative_allocation.x +
 			      relative_allocation.width +
 			      scrollbar_spacing +
+			      dislocation +
 			      (scrolled_window->shadow_type == GTK_SHADOW_NONE ?
 			       0 : widget->style->xthickness));
       else
-	child_allocation.x = GTK_CONTAINER (scrolled_window)->border_width;
+	child_allocation.x = GTK_CONTAINER (scrolled_window)->border_width -
+	  dislocation;
 
       child_allocation.y = relative_allocation.y;
       child_allocation.width = vscrollbar_requisition.width;
@@ -1207,6 +1300,9 @@
 	}
 
       gtk_widget_size_allocate (scrolled_window->vscrollbar, &child_allocation);
+
+      if (is_focus_visible)
+	gtk_scrolled_window_scroll_to_focus (scrolled_window);
     }
   else if (GTK_WIDGET_VISIBLE (scrolled_window->vscrollbar))
     gtk_widget_hide (scrolled_window->vscrollbar);