[gtk+/scrollable: 1/2] Add GtkScrollable interface



commit 7c059df409db3a5728f9717772052790f5cb87dd
Author: Tadej Borovšak <tadeboro gmail com>
Date:   Mon Oct 18 00:21:39 2010 -0400

    Add GtkScrollable interface
    
    The GtkScrollable interface provides "hadjustment" and "vadjustment"
    properties that are used by GtkScrolledWindow. It replaces
    the ::set_scroll_adjustment signal.

 docs/reference/gtk/gtk-docs.sgml     |    1 +
 docs/reference/gtk/gtk3-sections.txt |   26 ++
 docs/reference/gtk/gtk3.types        |    1 +
 gtk/Makefile.am                      |    2 +
 gtk/gtk.symbols                      |   14 ++
 gtk/gtkiconview.c                    |  414 +++++++++++++++++++---------------
 gtk/gtkiconview.h                    |    5 -
 gtk/gtklayout.c                      |  314 ++++++++++----------------
 gtk/gtklayout.h                      |    8 +-
 gtk/gtkscrollable.c                  |  207 +++++++++++++++++
 gtk/gtkscrollable.h                  |   55 +++++
 gtk/gtkscrolledwindow.c              |   53 +++--
 gtk/gtktextview.c                    |  350 +++++++++++++----------------
 gtk/gtktextview.h                    |   10 +-
 gtk/gtktoolpalette.c                 |  177 +++++++++++----
 gtk/gtktoolpalette.h                 |    8 +-
 gtk/gtktreeview.c                    |  184 ++++++----------
 gtk/gtktreeview.h                    |    9 +-
 gtk/gtkviewport.c                    |   68 ++----
 gtk/gtkviewport.h                    |   10 +-
 20 files changed, 1088 insertions(+), 828 deletions(-)
---
diff --git a/docs/reference/gtk/gtk-docs.sgml b/docs/reference/gtk/gtk-docs.sgml
index 146665e..8a3bfd0 100644
--- a/docs/reference/gtk/gtk-docs.sgml
+++ b/docs/reference/gtk/gtk-docs.sgml
@@ -237,6 +237,7 @@
       <xi:include href="xml/gtkhscrollbar.xml" />
       <xi:include href="xml/gtkvscrollbar.xml" />
       <xi:include href="xml/gtkscrolledwindow.xml" />
+      <xi:include href="xml/gtkscrollable.xml" />
     </chapter>
 
     <chapter id="Printing">
diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt
index 9d25db8..095a785 100644
--- a/docs/reference/gtk/gtk3-sections.txt
+++ b/docs/reference/gtk/gtk3-sections.txt
@@ -2770,6 +2770,28 @@ gtk_scale_button_get_type
 </SECTION>
 
 <SECTION>
+<FILE>gtkscrollable</FILE>
+<TITLE>GtkScrollable</TITLE>
+GtkScrollable
+gtk_scrollable_get_hadjustment
+gtk_scrollable_set_hadjustment
+gtk_scrollable_get_vadjustment
+gtk_scrollable_set_vadjustment
+
+<SUBSECTION Standard>
+GtkScrollableIface
+GTK_IS_SCROLLABLE
+GTK_IS_SCROLLABLE_CLASS
+GTK_SCROLLABLE
+GTK_SCROLLABLE_CLASS
+GTK_SCROLLABLE_GET_IFACE
+GTK_TYPE_SCROLLABLE
+
+<SUBSECTION Private>
+gtk_scrollable_get_type
+</SECTION>
+
+<SECTION>
 <FILE>gtkscrollbar</FILE>
 <TITLE>GtkScrollbar</TITLE>
 GtkScrollbar
@@ -3393,7 +3415,9 @@ gtk_text_view_new
 gtk_text_view_new_with_buffer
 gtk_text_view_set_buffer
 gtk_text_view_get_buffer
+gtk_text_view_set_hadjustment
 gtk_text_view_get_hadjustment
+gtk_text_view_set_vadjustment
 gtk_text_view_get_vadjustment
 gtk_text_view_scroll_to_mark
 gtk_text_view_scroll_to_iter
@@ -3820,7 +3844,9 @@ gtk_tool_palette_get_drop_item
 GtkToolPaletteDragTargets
 gtk_tool_palette_set_drag_source
 gtk_tool_palette_get_hadjustment
+gtk_tool_palette_set_hadjustment
 gtk_tool_palette_get_vadjustment
+gtk_tool_palette_set_vadjustment
 <SUBSECTION Standard>
 GtkToolPaletteClass
 GTK_TOOL_PALETTE
diff --git a/docs/reference/gtk/gtk3.types b/docs/reference/gtk/gtk3.types
index 2af1aaa..7159216 100644
--- a/docs/reference/gtk/gtk3.types
+++ b/docs/reference/gtk/gtk3.types
@@ -124,6 +124,7 @@ gtk_recent_manager_get_type
 gtk_ruler_get_type
 gtk_scale_button_get_type
 gtk_scale_get_type
+gtk_scrollable_get_type
 gtk_scrollbar_get_type
 gtk_scrolled_window_get_type
 gtk_separator_get_type
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index d6bf610..7aff462 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -273,6 +273,7 @@ gtk_public_h_sources =          \
 	gtkruler.h		\
 	gtkscale.h		\
 	gtkscalebutton.h	\
+	gtkscrollable.h         \
 	gtkscrollbar.h		\
 	gtkscrolledwindow.h	\
 	gtkselection.h		\
@@ -545,6 +546,7 @@ gtk_base_c_sources =            \
 	gtkruler.c		\
 	gtkscale.c		\
 	gtkscalebutton.c	\
+	gtkscrollable.c         \
 	gtkscrollbar.c		\
 	gtkscrolledwindow.c	\
 	gtkselection.c		\
diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols
index abaf1ee..d6f6fc8 100644
--- a/gtk/gtk.symbols
+++ b/gtk/gtk.symbols
@@ -2909,6 +2909,16 @@ gtk_scale_button_get_popup
 #endif
 #endif
 
+#if IN_HEADER(__GTK_SCROLLABLE_H__)
+#if IN_FILE(__GTK_SCROLLABLE_C__)
+gtk_scrollable_get_hadjustment
+gtk_scrollable_get_type G_GNUC_CONST
+gtk_scrollable_get_vadjustment
+gtk_scrollable_set_hadjustment
+gtk_scrollable_set_vadjustment
+#endif
+#endif
+
 #if IN_HEADER(__GTK_SCROLLBAR_H__)
 #if IN_FILE(__GTK_SCROLLBAR_C__)
 gtk_scrollbar_get_type G_GNUC_CONST
@@ -3504,6 +3514,7 @@ gtk_text_view_set_border_window_size
 gtk_text_view_set_buffer
 gtk_text_view_set_cursor_visible
 gtk_text_view_set_editable
+gtk_text_view_set_hadjustment
 gtk_text_view_set_indent
 gtk_text_view_set_justification
 gtk_text_view_set_left_margin
@@ -3513,6 +3524,7 @@ gtk_text_view_set_pixels_below_lines
 gtk_text_view_set_pixels_inside_wrap
 gtk_text_view_set_right_margin
 gtk_text_view_set_tabs
+gtk_text_view_set_vadjustment
 gtk_text_view_set_wrap_mode
 gtk_text_view_starts_display_line
 gtk_text_view_window_to_buffer_coords
@@ -3701,7 +3713,9 @@ gtk_tool_palette_get_drag_item
 gtk_tool_palette_set_drag_source
 gtk_tool_palette_add_drag_dest
 gtk_tool_palette_get_hadjustment
+gtk_tool_palette_set_hadjustment
 gtk_tool_palette_get_vadjustment
+gtk_tool_palette_set_vadjustment
 gtk_tool_palette_get_drag_target_item G_GNUC_CONST
 gtk_tool_palette_get_drag_target_group G_GNUC_CONST
 #endif
diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c
index f151923..962b78b 100644
--- a/gtk/gtkiconview.c
+++ b/gtk/gtkiconview.c
@@ -39,6 +39,7 @@
 #include "gtkentry.h"
 #include "gtkcombobox.h"
 #include "gtktextbuffer.h"
+#include "gtkscrollable.h"
 #include "gtksizerequest.h"
 #include "gtktreednd.h"
 #include "gtkprivate.h"
@@ -233,7 +234,11 @@ enum
   PROP_MARGIN,
   PROP_REORDERABLE,
   PROP_TOOLTIP_COLUMN,
-  PROP_ITEM_PADDING
+  PROP_ITEM_PADDING,
+
+  /* For scrollable interface */
+  PROP_HADJUSTMENT,
+  PROP_VADJUSTMENT
 };
 
 /* GObject vfuncs */
@@ -283,9 +288,6 @@ static void             gtk_icon_view_forall                    (GtkContainer
 								 gpointer            callback_data);
 
 /* GtkIconView vfuncs */
-static void             gtk_icon_view_set_adjustments           (GtkIconView        *icon_view,
-								 GtkAdjustment      *hadj,
-								 GtkAdjustment      *vadj);
 static void             gtk_icon_view_real_select_all           (GtkIconView        *icon_view);
 static void             gtk_icon_view_real_unselect_all         (GtkIconView        *icon_view);
 static void             gtk_icon_view_real_select_cursor_item   (GtkIconView        *icon_view);
@@ -293,6 +295,15 @@ static void             gtk_icon_view_real_toggle_cursor_item   (GtkIconView
 static gboolean         gtk_icon_view_real_activate_cursor_item (GtkIconView        *icon_view);
 
  /* Internal functions */
+static void                 gtk_icon_view_set_hadjustment_values         (GtkIconView            *icon_view);
+static void                 gtk_icon_view_set_vadjustment_values         (GtkIconView            *icon_view);
+static void                 gtk_icon_view_set_hadjustment                (GtkIconView            *icon_view,
+                                                                          GtkAdjustment          *adjustment);
+static void                 gtk_icon_view_set_vadjustment                (GtkIconView            *icon_view,
+                                                                          GtkAdjustment          *adjustment);
+static void                 gtk_icon_view_accessible_set_adjustment      (GtkIconView            *icon_view,
+                                                                          GtkOrientation          orientation,
+                                                                          GtkAdjustment          *adjustment);
 static void                 gtk_icon_view_adjustment_changed             (GtkAdjustment          *adjustment,
 									  GtkIconView            *icon_view);
 static void                 gtk_icon_view_layout                         (GtkIconView            *icon_view);
@@ -480,7 +491,8 @@ G_DEFINE_TYPE_WITH_CODE (GtkIconView, gtk_icon_view, GTK_TYPE_CONTAINER,
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
 						gtk_icon_view_cell_layout_init)
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
-						gtk_icon_view_buildable_init))
+						gtk_icon_view_buildable_init)
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
 
 static void
 gtk_icon_view_class_init (GtkIconViewClass *klass)
@@ -528,7 +540,6 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
   container_class->remove = gtk_icon_view_remove;
   container_class->forall = gtk_icon_view_forall;
 
-  klass->set_scroll_adjustments = gtk_icon_view_set_adjustments;
   klass->select_all = gtk_icon_view_real_select_all;
   klass->unselect_all = gtk_icon_view_real_unselect_all;
   klass->select_cursor_item = gtk_icon_view_real_select_cursor_item;
@@ -777,6 +788,10 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
 						     0, G_MAXINT, 6,
 						     GTK_PARAM_READWRITE));
 
+  /* Scrollable interface properties */
+  g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
+  g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+
 
 
   /* Style properties */
@@ -797,25 +812,6 @@ gtk_icon_view_class_init (GtkIconViewClass *klass)
 
   /* Signals */
   /**
-   * GtkIconView::set-scroll-adjustments
-   * @horizontal: the horizontal #GtkAdjustment
-   * @vertical: the vertical #GtkAdjustment
-   *
-   * Set the scroll adjustments for the icon view. Usually scrolled containers
-   * like #GtkScrolledWindow will emit this signal to connect two instances
-   * of #GtkScrollbar to the scroll directions of the #GtkIconView.
-   */
-  widget_class->set_scroll_adjustments_signal =
-    g_signal_new (I_("set-scroll-adjustments"),
-		  G_TYPE_FROM_CLASS (gobject_class),
-		  G_SIGNAL_RUN_LAST,
-		  G_STRUCT_OFFSET (GtkIconViewClass, set_scroll_adjustments),
-		  NULL, NULL, 
-		  _gtk_marshal_VOID__OBJECT_OBJECT,
-		  G_TYPE_NONE, 2,
-		  GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
-
-  /**
    * GtkIconView::item-activated:
    * @iconview: the object on which the signal is emitted
    * @path: the #GtkTreePath for the activated item
@@ -1113,8 +1109,6 @@ gtk_icon_view_init (GtkIconView *icon_view)
 
   gtk_widget_set_can_focus (GTK_WIDGET (icon_view), TRUE);
   
-  gtk_icon_view_set_adjustments (icon_view, NULL, NULL);
-
   icon_view->priv->cell_list = NULL;
   icon_view->priv->n_cells = 0;
   icon_view->priv->cursor_cell = -1;
@@ -1202,6 +1196,13 @@ gtk_icon_view_set_property (GObject      *object,
       gtk_icon_view_set_item_padding (icon_view, g_value_get_int (value));
       break;
 
+    case PROP_HADJUSTMENT:
+      gtk_icon_view_set_hadjustment (icon_view, g_value_get_object (value));
+      break;
+    case PROP_VADJUSTMENT:
+      gtk_icon_view_set_vadjustment (icon_view, g_value_get_object (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1267,6 +1268,13 @@ gtk_icon_view_get_property (GObject      *object,
       g_value_set_int (value, icon_view->priv->item_padding);
       break;
 
+    case PROP_HADJUSTMENT:
+      g_value_set_object (value, icon_view->priv->hadjustment);
+      break;
+    case PROP_VADJUSTMENT:
+      g_value_set_object (value, icon_view->priv->vadjustment);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1486,8 +1494,6 @@ gtk_icon_view_size_allocate (GtkWidget      *widget,
 {
   GtkIconView *icon_view = GTK_ICON_VIEW (widget);
 
-  GtkAdjustment *hadjustment, *vadjustment;
-
   gtk_widget_set_allocation (widget, allocation);
 
   if (gtk_widget_get_realized (widget))
@@ -1504,26 +1510,12 @@ gtk_icon_view_size_allocate (GtkWidget      *widget,
   
   gtk_icon_view_allocate_children (icon_view);
 
-  hadjustment = icon_view->priv->hadjustment;
-  vadjustment = icon_view->priv->vadjustment;
-
-  hadjustment->page_size = allocation->width;
-  hadjustment->page_increment = allocation->width * 0.9;
-  hadjustment->step_increment = allocation->width * 0.1;
-  hadjustment->lower = 0;
-  hadjustment->upper = MAX (allocation->width, icon_view->priv->width);
-
-  if (hadjustment->value > hadjustment->upper - hadjustment->page_size)
-    gtk_adjustment_set_value (hadjustment, hadjustment->upper - hadjustment->page_size);
-
-  vadjustment->page_size = allocation->height;
-  vadjustment->page_increment = allocation->height * 0.9;
-  vadjustment->step_increment = allocation->height * 0.1;
-  vadjustment->lower = 0;
-  vadjustment->upper = MAX (allocation->height, icon_view->priv->height);
+  /* Delay signal emission */
+  g_object_freeze_notify (G_OBJECT (icon_view->priv->hadjustment));
+  g_object_freeze_notify (G_OBJECT (icon_view->priv->vadjustment));
 
-  if (vadjustment->value > vadjustment->upper - vadjustment->page_size)
-    gtk_adjustment_set_value (vadjustment, vadjustment->upper - vadjustment->page_size);
+  gtk_icon_view_set_hadjustment_values (icon_view);
+  gtk_icon_view_set_vadjustment_values (icon_view);
 
   if (gtk_widget_get_realized (widget) &&
       icon_view->priv->scroll_to_path)
@@ -1539,11 +1531,10 @@ gtk_icon_view_size_allocate (GtkWidget      *widget,
 				    icon_view->priv->scroll_to_col_align);
       gtk_tree_path_free (path);
     }
-  else
-    {
-      gtk_adjustment_changed (hadjustment);
-      gtk_adjustment_changed (vadjustment);
-    }
+
+  /* Emit any pending signals now */
+  g_object_thaw_notify (G_OBJECT (icon_view->priv->hadjustment));
+  g_object_thaw_notify (G_OBJECT (icon_view->priv->vadjustment));
 }
 
 static gboolean
@@ -2510,62 +2501,6 @@ gtk_icon_view_unselect_all_internal (GtkIconView  *icon_view)
 
 /* GtkIconView signals */
 static void
-gtk_icon_view_set_adjustments (GtkIconView   *icon_view,
-			       GtkAdjustment *hadj,
-			       GtkAdjustment *vadj)
-{
-  gboolean need_adjust = FALSE;
-
-  if (hadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
-  else
-    hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-  if (vadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
-  else
-    vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-
-  if (icon_view->priv->hadjustment && (icon_view->priv->hadjustment != hadj))
-    {
-      g_signal_handlers_disconnect_matched (icon_view->priv->hadjustment, G_SIGNAL_MATCH_DATA,
-					   0, 0, NULL, NULL, icon_view);
-      g_object_unref (icon_view->priv->hadjustment);
-    }
-
-  if (icon_view->priv->vadjustment && (icon_view->priv->vadjustment != vadj))
-    {
-      g_signal_handlers_disconnect_matched (icon_view->priv->vadjustment, G_SIGNAL_MATCH_DATA,
-					    0, 0, NULL, NULL, icon_view);
-      g_object_unref (icon_view->priv->vadjustment);
-    }
-
-  if (icon_view->priv->hadjustment != hadj)
-    {
-      icon_view->priv->hadjustment = hadj;
-      g_object_ref_sink (icon_view->priv->hadjustment);
-
-      g_signal_connect (icon_view->priv->hadjustment, "value-changed",
-			G_CALLBACK (gtk_icon_view_adjustment_changed),
-			icon_view);
-      need_adjust = TRUE;
-    }
-
-  if (icon_view->priv->vadjustment != vadj)
-    {
-      icon_view->priv->vadjustment = vadj;
-      g_object_ref_sink (icon_view->priv->vadjustment);
-
-      g_signal_connect (icon_view->priv->vadjustment, "value-changed",
-			G_CALLBACK (gtk_icon_view_adjustment_changed),
-			icon_view);
-      need_adjust = TRUE;
-    }
-
-  if (need_adjust)
-    gtk_icon_view_adjustment_changed (NULL, icon_view);
-}
-
-static void
 gtk_icon_view_real_select_all (GtkIconView *icon_view)
 {
   gtk_icon_view_select_all (icon_view);
@@ -2670,17 +2605,161 @@ gtk_icon_view_process_updates (GtkIconView *icon_view)
 }
 
 static void
+gtk_icon_view_set_hadjustment_values (GtkIconView *icon_view)
+{
+  GtkAllocation  allocation;
+  GtkAdjustment *adj = icon_view->priv->hadjustment;
+  gdouble old_page_size;
+  gdouble old_upper;
+  gdouble old_value;
+  gdouble new_value;
+  gdouble new_upper;
+
+  gtk_widget_get_allocation (GTK_WIDGET (icon_view), &allocation);
+
+  old_value = gtk_adjustment_get_value (adj);
+  old_upper = gtk_adjustment_get_upper (adj);
+  old_page_size = gtk_adjustment_get_page_size (adj);
+  new_upper = MAX (allocation.width, icon_view->priv->width);
+
+  g_object_set (adj,
+                "lower", 0.0,
+                "upper", new_upper,
+                "page-size", (gdouble)allocation.width,
+                "step-increment", allocation.width * 0.1,
+                "page-increment", allocation.width * 0.9,
+                NULL);
+
+  if (gtk_widget_get_direction (GTK_WIDGET (icon_view)) == GTK_TEXT_DIR_RTL)
+    {
+      /* Make sure no scrolling occurs for RTL locales also (if possible) */
+      /* Quick explanation:
+       *   In LTR locales, leftmost portion of visible rectangle should stay
+       *   fixed, which means left edge of scrollbar thumb should remain fixed
+       *   and thus adjustment's value should stay the same.
+       *
+       *   In RTL locales, we want to keep rightmost portion of visible
+       *   rectangle fixed. This means right edge of thumb should remain fixed.
+       *   In this case, upper - value - page_size should remain constant.
+       */
+      new_value = (new_upper - allocation.width) -
+                  (old_upper - old_value - old_page_size);
+      new_value = CLAMP (new_value, 0, new_upper - allocation.width);
+    }
+  else
+    new_value = CLAMP (old_value, 0, new_upper - allocation.width);
+
+  if (new_value != old_value)
+    gtk_adjustment_set_value (adj, new_value);
+}
+
+static void
+gtk_icon_view_set_vadjustment_values (GtkIconView *icon_view)
+{
+  GtkAllocation  allocation;
+  GtkAdjustment *adj = icon_view->priv->vadjustment;
+  gdouble old_value;
+  gdouble new_value;
+  gdouble new_upper;
+
+  gtk_widget_get_allocation (GTK_WIDGET (icon_view), &allocation);
+
+  old_value = gtk_adjustment_get_value (adj);
+  new_upper = MAX (allocation.height, icon_view->priv->height);
+
+  g_object_set (adj,
+                "lower", 0.0,
+                "upper", new_upper,
+                "page-size", (gdouble)allocation.height,
+                "step-increment", allocation.height * 0.1,
+                "page-increment", allocation.height * 0.9,
+                NULL);
+
+  new_value = CLAMP (old_value, 0, new_upper - allocation.height);
+  if (new_value != old_value)
+    gtk_adjustment_set_value (adj, new_value);
+}
+
+static void
+gtk_icon_view_set_hadjustment (GtkIconView   *icon_view,
+                               GtkAdjustment *adjustment)
+{
+  GtkIconViewPrivate *priv = icon_view->priv;
+
+  if (adjustment && priv->hadjustment == adjustment)
+    return;
+
+  if (priv->hadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_matched (priv->hadjustment,
+                                            G_SIGNAL_MATCH_DATA,
+                                            0, 0, NULL, NULL, icon_view);
+      g_object_unref (priv->hadjustment);
+    }
+
+  if (!adjustment)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_icon_view_adjustment_changed), icon_view);
+  priv->hadjustment = g_object_ref_sink (adjustment);
+  gtk_icon_view_set_hadjustment_values (icon_view);
+
+  gtk_icon_view_accessible_set_adjustment (icon_view,
+                                           GTK_ORIENTATION_HORIZONTAL,
+                                           priv->hadjustment);
+
+  g_object_notify (G_OBJECT (icon_view), "hadjustment");
+}
+
+static void
+gtk_icon_view_set_vadjustment (GtkIconView   *icon_view,
+                               GtkAdjustment *adjustment)
+{
+  GtkIconViewPrivate *priv = icon_view->priv;
+
+  if (adjustment && priv->vadjustment == adjustment)
+    return;
+
+  if (priv->vadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_matched (priv->vadjustment,
+                                            G_SIGNAL_MATCH_DATA,
+                                            0, 0, NULL, NULL, icon_view);
+      g_object_unref (priv->vadjustment);
+    }
+
+  if (!adjustment)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_icon_view_adjustment_changed), icon_view);
+  priv->vadjustment = g_object_ref_sink (adjustment);
+  gtk_icon_view_set_vadjustment_values (icon_view);
+
+  gtk_icon_view_accessible_set_adjustment (icon_view,
+                                           GTK_ORIENTATION_VERTICAL,
+                                           priv->vadjustment);
+
+  g_object_notify (G_OBJECT (icon_view), "vadjustment");
+}
+
+static void
 gtk_icon_view_adjustment_changed (GtkAdjustment *adjustment,
-				  GtkIconView   *icon_view)
+                                  GtkIconView   *icon_view)
 {
+  GtkIconViewPrivate *priv = icon_view->priv;
+
   if (gtk_widget_get_realized (GTK_WIDGET (icon_view)))
     {
-      gdk_window_move (icon_view->priv->bin_window,
-		       - icon_view->priv->hadjustment->value,
-		       - icon_view->priv->vadjustment->value);
+      gdk_window_move (priv->bin_window,
+                       - priv->hadjustment->value,
+                       - priv->vadjustment->value);
 
       if (icon_view->priv->doing_rubberband)
-	gtk_icon_view_update_rubberband (GTK_WIDGET (icon_view));
+        gtk_icon_view_update_rubberband (GTK_WIDGET (icon_view));
 
       gtk_icon_view_process_updates (icon_view);
     }
@@ -9113,60 +9192,53 @@ gtk_icon_view_accessible_adjustment_changed (GtkAdjustment *adjustment,
 }
 
 static void
-gtk_icon_view_accessible_set_scroll_adjustments (GtkWidget      *widget,
-                                                 GtkAdjustment *hadj,
-                                                 GtkAdjustment *vadj)
+gtk_icon_view_accessible_set_adjustment (GtkIconView    *icon_view,
+                                         GtkOrientation  orientation,
+                                         GtkAdjustment  *adjustment)
 {
   AtkObject *atk_obj;
   GtkIconViewAccessiblePrivate *priv;
+  GtkAdjustment **old_adj_ptr;
 
-  atk_obj = gtk_widget_get_accessible (widget);
+  atk_obj = gtk_widget_get_accessible (GTK_WIDGET (icon_view));
   priv = gtk_icon_view_accessible_get_priv (atk_obj);
 
-  if (priv->old_hadj != hadj)
+  /* Adjustments are set for the first time in constructor and priv is not
+   * initialized at that time, so skip this first setting. */
+  if (!priv)
+    return;
+
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
     {
-      if (priv->old_hadj)
-        {
-          g_object_remove_weak_pointer (G_OBJECT (priv->old_hadj),
-                                        (gpointer *)&priv->old_hadj);
-          
-          g_signal_handlers_disconnect_by_func (priv->old_hadj,
-                                                (gpointer) gtk_icon_view_accessible_adjustment_changed,
-                                                widget);
-        }
-      priv->old_hadj = hadj;
-      if (priv->old_hadj)
-        {
-          g_object_add_weak_pointer (G_OBJECT (priv->old_hadj),
-                                     (gpointer *)&priv->old_hadj);
-          g_signal_connect (hadj,
-                            "value-changed",
-                            G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
-                            widget);
-        }
+      if (priv->old_hadj == adjustment)
+        return;
+
+      old_adj_ptr = &priv->old_hadj;
     }
-  if (priv->old_vadj != vadj)
+  else
     {
-      if (priv->old_vadj)
-        {
-          g_object_remove_weak_pointer (G_OBJECT (priv->old_vadj),
-                                        (gpointer *)&priv->old_vadj);
-          
-          g_signal_handlers_disconnect_by_func (priv->old_vadj,
-                                                (gpointer) gtk_icon_view_accessible_adjustment_changed,
-                                                widget);
-        }
-      priv->old_vadj = vadj;
-      if (priv->old_vadj)
-        {
-          g_object_add_weak_pointer (G_OBJECT (priv->old_vadj),
-                                     (gpointer *)&priv->old_vadj);
-          g_signal_connect (vadj,
-                            "value-changed",
-                            G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
-                            widget);
-        }
+      if (priv->old_vadj == adjustment)
+        return;
+
+      old_adj_ptr = &priv->old_vadj;
+    }
+
+  /* Disconnect signal handlers */
+  if (*old_adj_ptr)
+    {
+      g_object_remove_weak_pointer (G_OBJECT (*old_adj_ptr),
+                                    (gpointer *)&priv->old_hadj);
+      g_signal_handlers_disconnect_by_func (*old_adj_ptr,
+                                            gtk_icon_view_accessible_adjustment_changed,
+                                            icon_view);
     }
+
+  /* Connect signal */
+  *old_adj_ptr = adjustment;
+  g_object_add_weak_pointer (G_OBJECT (adjustment), (gpointer *)old_adj_ptr);
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
+                    icon_view);
 }
 
 static void
@@ -9469,27 +9541,13 @@ gtk_icon_view_accessible_initialize (AtkObject *accessible,
 
   icon_view = GTK_ICON_VIEW (data);
   if (icon_view->priv->hadjustment)
-    {
-      priv->old_hadj = icon_view->priv->hadjustment;
-      g_object_add_weak_pointer (G_OBJECT (priv->old_hadj), (gpointer *)&priv->old_hadj);
-      g_signal_connect (icon_view->priv->hadjustment,
-                        "value-changed",
-                        G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
-                        icon_view);
-    } 
+    gtk_icon_view_accessible_set_adjustment (icon_view,
+					     GTK_ORIENTATION_HORIZONTAL,
+					     icon_view->priv->hadjustment);
   if (icon_view->priv->vadjustment)
-    {
-      priv->old_vadj = icon_view->priv->vadjustment;
-      g_object_add_weak_pointer (G_OBJECT (priv->old_vadj), (gpointer *)&priv->old_vadj);
-      g_signal_connect (icon_view->priv->vadjustment,
-                        "value-changed",
-                        G_CALLBACK (gtk_icon_view_accessible_adjustment_changed),
-                        icon_view);
-    }
-  g_signal_connect_after (data,
-                          "set-scroll-adjustments",
-                          G_CALLBACK (gtk_icon_view_accessible_set_scroll_adjustments),
-                          NULL);
+    gtk_icon_view_accessible_set_adjustment (icon_view,
+					     GTK_ORIENTATION_VERTICAL,
+					     icon_view->priv->vadjustment);
   g_signal_connect (data,
                     "notify",
                     G_CALLBACK (gtk_icon_view_accessible_notify_gtk),
diff --git a/gtk/gtkiconview.h b/gtk/gtkiconview.h
index f46d533..06b4fd7 100644
--- a/gtk/gtkiconview.h
+++ b/gtk/gtkiconview.h
@@ -89,10 +89,6 @@ struct _GtkIconViewClass
 {
   GtkContainerClass parent_class;
 
-  void    (* set_scroll_adjustments) (GtkIconView      *icon_view,
-				      GtkAdjustment    *hadjustment,
-				      GtkAdjustment    *vadjustment);
-  
   void    (* item_activated)         (GtkIconView      *icon_view,
 				      GtkTreePath      *path);
   void    (* selection_changed)      (GtkIconView      *icon_view);
@@ -150,7 +146,6 @@ void           gtk_icon_view_set_item_padding  (GtkIconView    *icon_view,
 					        gint            item_padding);
 gint           gtk_icon_view_get_item_padding  (GtkIconView    *icon_view);
 
-
 GtkTreePath *  gtk_icon_view_get_path_at_pos   (GtkIconView     *icon_view,
 						gint             x,
 						gint             y);
diff --git a/gtk/gtklayout.c b/gtk/gtklayout.c
index 930e98d..5f71717 100644
--- a/gtk/gtklayout.c
+++ b/gtk/gtklayout.c
@@ -37,6 +37,7 @@
 #include "gtkprivate.h"
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
+#include "gtkscrollable.h"
 
 
 typedef struct _GtkLayoutChild   GtkLayoutChild;
@@ -90,9 +91,6 @@ static void gtk_layout_set_property       (GObject        *object,
                                            guint           prop_id,
                                            const GValue   *value,
                                            GParamSpec     *pspec);
-static GObject *gtk_layout_constructor    (GType                  type,
-					   guint                  n_properties,
-					   GObjectConstructParam *properties);
 static void gtk_layout_finalize           (GObject        *object);
 static void gtk_layout_realize            (GtkWidget      *widget);
 static void gtk_layout_unrealize          (GtkWidget      *widget);
@@ -111,9 +109,6 @@ static void gtk_layout_forall             (GtkContainer   *container,
                                            gboolean        include_internals,
                                            GtkCallback     callback,
                                            gpointer        callback_data);
-static void gtk_layout_set_adjustments    (GtkLayout      *layout,
-                                           GtkAdjustment  *hadj,
-                                           GtkAdjustment  *vadj);
 static void gtk_layout_set_child_property (GtkContainer   *container,
                                            GtkWidget      *child,
                                            guint           property_id,
@@ -131,11 +126,15 @@ static void gtk_layout_adjustment_changed (GtkAdjustment  *adjustment,
 static void gtk_layout_style_set          (GtkWidget      *widget,
 					   GtkStyle       *old_style);
 
-static void gtk_layout_set_adjustment_upper (GtkAdjustment *adj,
-					     gdouble        upper,
-					     gboolean       always_emit_changed);
+static void gtk_layout_set_hadjustment_values (GtkLayout      *layout);
+static void gtk_layout_set_vadjustment_values (GtkLayout      *layout);
+static void gtk_layout_set_hadjustment        (GtkLayout      *layout,
+                                               GtkAdjustment  *adjustment);
+static void gtk_layout_set_vadjustment        (GtkLayout      *layout,
+                                               GtkAdjustment  *adjustment);
 
-G_DEFINE_TYPE (GtkLayout, gtk_layout, GTK_TYPE_CONTAINER)
+G_DEFINE_TYPE_WITH_CODE (GtkLayout, gtk_layout, GTK_TYPE_CONTAINER,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
 
 /* Public interface
  */
@@ -195,6 +194,8 @@ gtk_layout_get_bin_window (GtkLayout *layout)
  * See #GtkScrolledWindow, #GtkScrollbar, #GtkAdjustment for details.
  *
  * Return value: (transfer none): horizontal scroll adjustment
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
  **/
 GtkAdjustment*
 gtk_layout_get_hadjustment (GtkLayout *layout)
@@ -215,6 +216,8 @@ gtk_layout_get_hadjustment (GtkLayout *layout)
  * See #GtkScrolledWindow, #GtkScrollbar, #GtkAdjustment for details.
  *
  * Return value: (transfer none): vertical scroll adjustment
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment()
  **/
 GtkAdjustment*
 gtk_layout_get_vadjustment (GtkLayout *layout)
@@ -224,73 +227,59 @@ gtk_layout_get_vadjustment (GtkLayout *layout)
   return layout->priv->vadjustment;
 }
 
-static GtkAdjustment *
-new_default_adjustment (void)
+static void
+gtk_layout_set_hadjustment_values (GtkLayout *layout)
 {
-  return gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+  GtkLayoutPrivate *priv = layout->priv;
+  GtkAllocation  allocation;
+  GtkAdjustment *adj = priv->hadjustment;
+  gdouble old_value;
+  gdouble new_value;
+  gdouble new_upper;
+
+  gtk_widget_get_allocation (GTK_WIDGET (layout), &allocation);
+
+  old_value = gtk_adjustment_get_value (adj);
+  new_upper = MAX (allocation.width, priv->width);
+
+  g_object_set (adj,
+                "lower", 0.0,
+                "upper", new_upper,
+                "page-size", (gdouble)allocation.width,
+                "step-increment", allocation.width * 0.1,
+                "page-increment", allocation.width * 0.9,
+                NULL);
+
+  new_value = CLAMP (old_value, 0, new_upper - allocation.width);
+  if (new_value != old_value)
+    gtk_adjustment_set_value (adj, new_value);
 }
 
-static void           
-gtk_layout_set_adjustments (GtkLayout     *layout,
-			    GtkAdjustment *hadj,
-			    GtkAdjustment *vadj)
+static void
+gtk_layout_set_vadjustment_values (GtkLayout *layout)
 {
-  GtkLayoutPrivate *priv = layout->priv;
-  gboolean need_adjust = FALSE;
-
-  if (hadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
-  else if (priv->hadjustment)
-    hadj = new_default_adjustment ();
-  if (vadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
-  else if (priv->vadjustment)
-    vadj = new_default_adjustment ();
-
-  if (priv->hadjustment && (priv->hadjustment != hadj))
-    {
-      g_signal_handlers_disconnect_by_func (priv->hadjustment,
-					    gtk_layout_adjustment_changed,
-					    layout);
-      g_object_unref (priv->hadjustment);
-    }
-
-  if (priv->vadjustment && (priv->vadjustment != vadj))
-    {
-      g_signal_handlers_disconnect_by_func (priv->vadjustment,
-					    gtk_layout_adjustment_changed,
-					    layout);
-      g_object_unref (priv->vadjustment);
-    }
-
-  if (priv->hadjustment != hadj)
-    {
-      priv->hadjustment = hadj;
-      g_object_ref_sink (priv->hadjustment);
-      gtk_layout_set_adjustment_upper (priv->hadjustment, priv->width, FALSE);
-
-      g_signal_connect (priv->hadjustment, "value-changed",
-			G_CALLBACK (gtk_layout_adjustment_changed),
-			layout);
-      need_adjust = TRUE;
-    }
-
-  if (priv->vadjustment != vadj)
-    {
-      priv->vadjustment = vadj;
-      g_object_ref_sink (priv->vadjustment);
-      gtk_layout_set_adjustment_upper (priv->vadjustment, priv->height, FALSE);
-
-      g_signal_connect (priv->vadjustment, "value-changed",
-			G_CALLBACK (gtk_layout_adjustment_changed),
-			layout);
-      need_adjust = TRUE;
-    }
-
-  /* vadj or hadj can be NULL while constructing; don't emit a signal
-     then */
-  if (need_adjust && vadj && hadj)
-    gtk_layout_adjustment_changed (NULL, layout);
+  GtkAllocation  allocation;
+  GtkAdjustment *adj = layout->priv->vadjustment;
+  gdouble old_value;
+  gdouble new_value;
+  gdouble new_upper;
+
+  gtk_widget_get_allocation (GTK_WIDGET (layout), &allocation);
+
+  old_value = gtk_adjustment_get_value (adj);
+  new_upper = MAX (allocation.height, layout->priv->height);
+
+  g_object_set (adj,
+                "lower", 0.0,
+                "upper", new_upper,
+                "page-size", (gdouble)allocation.height,
+                "step-increment", allocation.height * 0.1,
+                "page-increment", allocation.height * 0.9,
+                NULL);
+
+  new_value = CLAMP (old_value, 0, new_upper - allocation.height);
+  if (new_value != old_value)
+    gtk_adjustment_set_value (adj, new_value);
 }
 
 static void
@@ -313,22 +302,43 @@ gtk_layout_finalize (GObject *object)
  * Sets the horizontal scroll adjustment for the layout.
  *
  * See #GtkScrolledWindow, #GtkScrollbar, #GtkAdjustment for details.
- * 
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_hadjustment()
  **/
-void           
+void
 gtk_layout_set_hadjustment (GtkLayout     *layout,
-			    GtkAdjustment *adjustment)
+                            GtkAdjustment *adjustment)
 {
   GtkLayoutPrivate *priv;
 
   g_return_if_fail (GTK_IS_LAYOUT (layout));
+  g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
 
   priv = layout->priv;
 
-  gtk_layout_set_adjustments (layout, adjustment, priv->vadjustment);
+  if (adjustment && priv->hadjustment == adjustment)
+        return;
+
+  if (priv->hadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->hadjustment,
+                                            gtk_layout_adjustment_changed,
+                                            layout);
+      g_object_unref (priv->hadjustment);
+    }
+
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_layout_adjustment_changed), layout);
+  priv->hadjustment = g_object_ref_sink (adjustment);
+  gtk_layout_set_hadjustment_values (layout);
+
   g_object_notify (G_OBJECT (layout), "hadjustment");
 }
- 
+
+
 /**
  * gtk_layout_set_vadjustment:
  * @layout: a #GtkLayout
@@ -337,19 +347,39 @@ gtk_layout_set_hadjustment (GtkLayout     *layout,
  * Sets the vertical scroll adjustment for the layout.
  *
  * See #GtkScrolledWindow, #GtkScrollbar, #GtkAdjustment for details.
- * 
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment()
  **/
-void           
+void
 gtk_layout_set_vadjustment (GtkLayout     *layout,
-			    GtkAdjustment *adjustment)
+                            GtkAdjustment *adjustment)
 {
   GtkLayoutPrivate *priv;
 
   g_return_if_fail (GTK_IS_LAYOUT (layout));
+  g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
 
   priv = layout->priv;
 
-  gtk_layout_set_adjustments (layout, priv->hadjustment, adjustment);
+  if (adjustment && priv->vadjustment == adjustment)
+        return;
+
+  if (priv->vadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->vadjustment,
+                                            gtk_layout_adjustment_changed,
+                                            layout);
+      g_object_unref (priv->vadjustment);
+    }
+
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_layout_adjustment_changed), layout);
+  priv->vadjustment = g_object_ref_sink (adjustment);
+  gtk_layout_set_vadjustment_values (layout);
+
   g_object_notify (G_OBJECT (layout), "vadjustment");
 }
 
@@ -472,34 +502,6 @@ gtk_layout_move (GtkLayout     *layout,
   gtk_layout_move_internal (layout, child_widget, TRUE, x, TRUE, y);
 }
 
-static void
-gtk_layout_set_adjustment_upper (GtkAdjustment *adj,
-				 gdouble        upper,
-				 gboolean       always_emit_changed)
-{
-  gboolean changed = FALSE;
-  gboolean value_changed = FALSE;
-  
-  gdouble min = MAX (0., upper - adj->page_size);
-
-  if (upper != adj->upper)
-    {
-      adj->upper = upper;
-      changed = TRUE;
-    }
-      
-  if (adj->value > min)
-    {
-      adj->value = min;
-      value_changed = TRUE;
-    }
-  
-  if (changed || always_emit_changed)
-    gtk_adjustment_changed (adj);
-  if (value_changed)
-    gtk_adjustment_value_changed (adj);
-}
-
 /**
  * gtk_layout_set_size:
  * @layout: a #GtkLayout
@@ -535,11 +537,6 @@ gtk_layout_set_size (GtkLayout     *layout,
      }
   g_object_thaw_notify (G_OBJECT (layout));
 
-  if (priv->hadjustment)
-    gtk_layout_set_adjustment_upper (priv->hadjustment, priv->width, FALSE);
-  if (priv->vadjustment)
-    gtk_layout_set_adjustment_upper (priv->vadjustment, priv->height, FALSE);
-
   if (gtk_widget_get_realized (widget))
     {
       GtkAllocation allocation;
@@ -549,6 +546,9 @@ gtk_layout_set_size (GtkLayout     *layout,
       height = MAX (height, allocation.height);
       gdk_window_resize (priv->bin_window, width, height);
     }
+
+  gtk_layout_set_hadjustment_values (layout);
+  gtk_layout_set_vadjustment_values (layout);
 }
 
 /**
@@ -594,7 +594,6 @@ gtk_layout_class_init (GtkLayoutClass *class)
   gobject_class->set_property = gtk_layout_set_property;
   gobject_class->get_property = gtk_layout_get_property;
   gobject_class->finalize = gtk_layout_finalize;
-  gobject_class->constructor = gtk_layout_constructor;
 
   container_class->set_child_property = gtk_layout_set_child_property;
   container_class->get_child_property = gtk_layout_get_child_property;
@@ -619,21 +618,13 @@ gtk_layout_class_init (GtkLayoutClass *class)
                                                                 0,
                                                                 GTK_PARAM_READWRITE));
   
-  g_object_class_install_property (gobject_class,
-				   PROP_HADJUSTMENT,
-				   g_param_spec_object ("hadjustment",
-							P_("Horizontal adjustment"),
-							P_("The GtkAdjustment for the horizontal position"),
-							GTK_TYPE_ADJUSTMENT,
-							GTK_PARAM_READWRITE));
-  
-  g_object_class_install_property (gobject_class,
-				   PROP_VADJUSTMENT,
-				   g_param_spec_object ("vadjustment",
-							P_("Vertical adjustment"),
-							P_("The GtkAdjustment for the vertical position"),
-							GTK_TYPE_ADJUSTMENT,
-							GTK_PARAM_READWRITE));
+  /* Scrollable interface */
+  g_object_class_override_property (gobject_class,
+				    PROP_HADJUSTMENT,
+				    "hadjustment");
+  g_object_class_override_property (gobject_class,
+				    PROP_VADJUSTMENT,
+				    "vadjustment");
 
   g_object_class_install_property (gobject_class,
 				   PROP_WIDTH,
@@ -665,28 +656,6 @@ gtk_layout_class_init (GtkLayoutClass *class)
   container_class->remove = gtk_layout_remove;
   container_class->forall = gtk_layout_forall;
 
-  class->set_scroll_adjustments = gtk_layout_set_adjustments;
-
-  /**
-   * GtkLayout::set-scroll-adjustments
-   * @horizontal: the horizontal #GtkAdjustment
-   * @vertical: the vertical #GtkAdjustment
-   *
-   * Set the scroll adjustments for the layout. Usually scrolled containers
-   * like #GtkScrolledWindow will emit this signal to connect two instances
-   * of #GtkScrollbar to the scroll directions of the #GtkLayout.
-   */
-  widget_class->set_scroll_adjustments_signal =
-    g_signal_new (I_("set-scroll-adjustments"),
-		  G_OBJECT_CLASS_TYPE (gobject_class),
-		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		  G_STRUCT_OFFSET (GtkLayoutClass, set_scroll_adjustments),
-		  NULL, NULL,
-		  _gtk_marshal_VOID__OBJECT_OBJECT,
-		  G_TYPE_NONE, 2,
-		  GTK_TYPE_ADJUSTMENT,
-		  GTK_TYPE_ADJUSTMENT);
-
   g_type_class_add_private (class, sizeof (GtkLayoutPrivate));
 }
 
@@ -831,32 +800,6 @@ gtk_layout_init (GtkLayout *layout)
   priv->freeze_count = 0;
 }
 
-static GObject *
-gtk_layout_constructor (GType                  type,
-			guint                  n_properties,
-			GObjectConstructParam *properties)
-{
-  GtkLayoutPrivate *priv;
-  GtkLayout *layout;
-  GObject *object;
-  GtkAdjustment *hadj, *vadj;
-  
-  object = G_OBJECT_CLASS (gtk_layout_parent_class)->constructor (type,
-								  n_properties,
-								  properties);
-
-  layout = GTK_LAYOUT (object);
-  priv = layout->priv;
-
-  hadj = priv->hadjustment ? priv->hadjustment : new_default_adjustment ();
-  vadj = priv->vadjustment ? priv->vadjustment : new_default_adjustment ();
-
-  if (!priv->hadjustment || !priv->vadjustment)
-    gtk_layout_set_adjustments (layout, hadj, vadj);
-
-  return object;
-}
-
 /* Widget methods
  */
 
@@ -1010,17 +953,8 @@ gtk_layout_size_allocate (GtkWidget     *widget,
 			 MAX (priv->height, allocation->height));
     }
 
-  priv->hadjustment->page_size = allocation->width;
-  priv->hadjustment->page_increment = allocation->width * 0.9;
-  priv->hadjustment->lower = 0;
-  /* set_adjustment_upper() emits ::changed */
-  gtk_layout_set_adjustment_upper (priv->hadjustment, MAX (allocation->width, priv->width), TRUE);
-
-  priv->vadjustment->page_size = allocation->height;
-  priv->vadjustment->page_increment = allocation->height * 0.9;
-  priv->vadjustment->lower = 0;
-  priv->vadjustment->upper = MAX (allocation->height, priv->height);
-  gtk_layout_set_adjustment_upper (priv->vadjustment, MAX (allocation->height, priv->height), TRUE);
+  gtk_layout_set_hadjustment_values (layout);
+  gtk_layout_set_vadjustment_values (layout);
 }
 
 static gboolean
diff --git a/gtk/gtklayout.h b/gtk/gtklayout.h
index d29e733..5c4f8b2 100644
--- a/gtk/gtklayout.h
+++ b/gtk/gtklayout.h
@@ -66,10 +66,6 @@ struct _GtkLayoutClass
 {
   GtkContainerClass parent_class;
 
-  void  (*set_scroll_adjustments)   (GtkLayout	    *layout,
-				     GtkAdjustment  *hadjustment,
-				     GtkAdjustment  *vadjustment);
-
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
@@ -98,6 +94,8 @@ void           gtk_layout_get_size        (GtkLayout     *layout,
 					   guint         *width,
 					   guint         *height);
 
+#ifndef GTK_DISABLE_DEPRECATED
+
 GtkAdjustment* gtk_layout_get_hadjustment (GtkLayout     *layout);
 GtkAdjustment* gtk_layout_get_vadjustment (GtkLayout     *layout);
 void           gtk_layout_set_hadjustment (GtkLayout     *layout,
@@ -105,6 +103,8 @@ void           gtk_layout_set_hadjustment (GtkLayout     *layout,
 void           gtk_layout_set_vadjustment (GtkLayout     *layout,
 					   GtkAdjustment *adjustment);
 
+#endif
+
 G_END_DECLS
 
 #endif /* __GTK_LAYOUT_H__ */
diff --git a/gtk/gtkscrollable.c b/gtk/gtkscrollable.c
new file mode 100644
index 0000000..0017c33
--- /dev/null
+++ b/gtk/gtkscrollable.c
@@ -0,0 +1,207 @@
+/* gtkscrollable.c
+ * Copyright (C) 2008 Tadej Borovšak <tadeboro gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gtkscrollable
+ * @Short_Description: An interface for scrollable widgets
+ * @Title: GtkScrollable
+ *
+ * #GtkScrollable is interface that is implemented by widgets with native
+ * scrolling ability.
+ *
+ * To implement this interface, all one needs to do is to override
+ * #GtkScrollable:hadjustment and #GtkScrollable:vadjustment properties.
+ *
+ * <refsect2>
+ * <title>Creating scrollable widget</title>
+ * <para>
+ * There are some common things all scrollable widgets will need to do.
+ *
+ * <orderedlist>
+ *   <listitem>
+ *     <para>
+ *       When parent sets adjustments, widget needs to populate adjustment's
+ *       #GtkAdjustment:lower, #GtkAdjustment:upper,
+ *       #GtkAdjustment:step-increment, #GtkAdjustment:page-increment and
+ *       #GtkAdjustment:page-size properties and connect to
+ *       #GtkAdjustment::value-changed signal.
+ *     </para>
+ *   </listitem>
+ *   <listitem>
+ *     <para>
+ *       When parent allocates space to child, scrollable widget needs to update
+ *       properties listed under 1 with new values.
+ *     </para>
+ *   </listitem>
+ *   <listitem>
+ *     <para>
+ *       When any of the adjustments emits #GtkAdjustment::value-changed signal,
+ *       scrollable widget needs to scroll it's contents.
+ *     </para>
+ *   </listitem>
+ * </orderedlist>
+ * </para>
+ * </refsect2>
+ *
+ * FIXME: Add some sample code here for demo purposes.
+ */
+
+#include "config.h"
+
+#include "gtkscrollable.h"
+#include "gtkprivate.h"
+#include "gtkintl.h"
+
+G_DEFINE_INTERFACE (GtkScrollable, gtk_scrollable, G_TYPE_OBJECT)
+
+static void
+gtk_scrollable_default_init (GtkScrollableInterface *iface)
+{
+  GParamSpec *pspec;
+
+  /**
+   * GtkScrollable:hadjustment:
+   *
+   * Horizontal #GtkAdjustment of scrollable widget. This adjustment is
+   * shared between scrollable widget and it's parent.
+   *
+   * Since: 3.0
+   */
+  pspec = g_param_spec_object ("hadjustment",
+                               P_("Horizontal adjustment"),
+                               P_("Horizontal adjustment that is shared "
+                                  "between scrollable widget and it's "
+                                  "controller"),
+                               GTK_TYPE_ADJUSTMENT,
+                               GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+  g_object_interface_install_property (iface, pspec);
+
+  /**
+   * GtkScrollable:vadjustment:
+   *
+   * Verical #GtkAdjustment of scrollable widget. This adjustment is shared
+   * between scrollable widget and it's parent.
+   *
+   * Since: 3.0
+   */
+  pspec = g_param_spec_object ("vadjustment",
+                               P_("Vertical adjustment"),
+                               P_("Vertical adjustment that is shared "
+                                  "between scrollable widget and it's "
+                                  "controller"),
+                               GTK_TYPE_ADJUSTMENT,
+                               GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+  g_object_interface_install_property (iface, pspec);
+}
+
+/**
+ * gtk_scrollable_get_hadjustment:
+ * @scrollable: a #GtkScrollable
+ *
+ * Retrieves the #GtkAdjustment, used for horizontal scrolling.
+ *
+ * Return value: (transfer none): horizontal #GtkAdjustment.
+ *
+ * Since: 3.0
+ **/
+GtkAdjustment *
+gtk_scrollable_get_hadjustment (GtkScrollable *scrollable)
+{
+  GtkAdjustment *adj = NULL;
+
+  g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), NULL);
+
+  g_object_get (scrollable, "hadjustment", &adj, NULL);
+
+  /* Horrid hack; g_object_get() returns a new reference but
+   * that contradicts the memory management conventions
+   * for accessors.
+   */
+  if (adj)
+    g_object_unref (adj);
+
+  return adj;
+}
+
+/**
+ * gtk_scrollable_set_hadjustment:
+ * @scrollable: a #GtkScrollable
+ * @hadjustment: (allow-none): a #GtkAdjustment
+ *
+ * Sets the horizontal adjustment of the #GtkScrollable.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_scrollable_set_hadjustment (GtkScrollable *scrollable,
+                                GtkAdjustment *hadjustment)
+{
+  g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
+  g_return_if_fail (hadjustment == NULL || GTK_IS_ADJUSTMENT (hadjustment));
+
+  g_object_set (scrollable, "hadjustment", hadjustment, NULL);
+}
+
+/**
+ * gtk_scrollable_get_vadjustment:
+ * @scrollable: a #GtkScrollable
+ *
+ * Retrieves the #GtkAdjustment, used for vertical scrolling.
+ *
+ * Return value: (transfer none): vertical #GtkAdjustment.
+ *
+ * Since: 3.0
+ **/
+GtkAdjustment *
+gtk_scrollable_get_vadjustment (GtkScrollable *scrollable)
+{
+  GtkAdjustment *adj = NULL;
+
+  g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), NULL);
+
+  g_object_get (scrollable, "vadjustment", &adj, NULL);
+
+  /* Horrid hack; g_object_get() returns a new reference but
+   * that contradicts the memory management conventions
+   * for accessors.
+   */
+  if (adj)
+    g_object_unref (adj);
+
+  return adj;
+}
+
+/**
+ * gtk_scrollable_set_vadjustment:
+ * @scrollable: a #GtkScrollable
+ * @vadjustment: (allow-none): a #GtkAdjustment
+ *
+ * Sets the vertical adjustment of the #GtkScrollable.
+ *
+ * Since: 3.0
+ **/
+void
+gtk_scrollable_set_vadjustment (GtkScrollable *scrollable,
+                                GtkAdjustment *vadjustment)
+{
+  g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
+  g_return_if_fail (vadjustment == NULL || GTK_IS_ADJUSTMENT (vadjustment));
+
+  g_object_set (scrollable, "vadjustment", vadjustment, NULL);
+}
diff --git a/gtk/gtkscrollable.h b/gtk/gtkscrollable.h
new file mode 100644
index 0000000..7b334a9
--- /dev/null
+++ b/gtk/gtkscrollable.h
@@ -0,0 +1,55 @@
+/* gtkscrollable.h
+ * Copyright (C) 2008 Tadej Borovšak <tadeboro gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#ifndef __GTK_SCROLLABLE_H__
+#define __GTK_SCROLLABLE_H__
+
+#include <gtk/gtkadjustment.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_SCROLLABLE            (gtk_scrollable_get_type ())
+#define GTK_SCROLLABLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj),     GTK_TYPE_SCROLLABLE, GtkScrollable))
+#define GTK_IS_SCROLLABLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj),     GTK_TYPE_SCROLLABLE))
+#define GTK_SCROLLABLE_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_SCROLLABLE, GtkScrollableInterface))
+
+typedef struct _GtkScrollable          GtkScrollable; /* Dummy */
+typedef struct _GtkScrollableInterface GtkScrollableInterface;
+
+struct _GtkScrollableInterface
+{
+  GTypeInterface base_iface;
+};
+
+/* Public API */
+GType          gtk_scrollable_get_type        (void) G_GNUC_CONST;
+GtkAdjustment *gtk_scrollable_get_hadjustment (GtkScrollable *scrollable);
+void           gtk_scrollable_set_hadjustment (GtkScrollable *scrollable,
+                                               GtkAdjustment *hadjustment);
+GtkAdjustment *gtk_scrollable_get_vadjustment (GtkScrollable *scrollable);
+void           gtk_scrollable_set_vadjustment (GtkScrollable *scrollable,
+                                               GtkAdjustment *vadjustment);
+
+G_END_DECLS
+
+#endif /* __GTK_SCROLLABLE_H__ */
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index bdd4a2d..95fee96 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -29,6 +29,7 @@
 #include <gdk/gdkkeysyms.h>
 #include "gtkbindings.h"
 #include "gtkmarshalers.h"
+#include "gtkscrollable.h"
 #include "gtkscrolledwindow.h"
 #include "gtkwindow.h"
 #include "gtktypeutils.h"
@@ -40,7 +41,7 @@
  * SECTION:gtkscrolledwindow
  * @Short_description: Adds scrollbars to its child widget
  * @Title: GtkScrolledWindow
- * @See_also: #GtkViewport, #GtkAdjustment, #GtkWidgetClass
+ * @See_also: #GtkScrollable, #GtkViewport, #GtkAdjustment
  *
  * #GtkScrolledWindow is a #GtkBin subclass: it's a container
  * the accepts a single child widget. #GtkScrolledWindow adds scrollbars
@@ -48,16 +49,7 @@
  * child widget.
  *
  * The scrolled window can work in two ways. Some widgets have native
- * scrolling support; these widgets have "slots" for #GtkAdjustment
- * objects.
- * <footnote><para>The scrolled window installs #GtkAdjustment objects in
- * the child window's slots using the set_scroll_adjustments_signal,
- * found in #GtkWidgetClass. (Conceptually, these widgets implement a
- * "Scrollable" interface; because GTK+ 1.2 lacked interface support in
- * the object system, this interface is hackily implemented as a signal
- * in #GtkWidgetClass. The GTK+ 2.0 object system would allow a clean
- * implementation, but it wasn't worth breaking the
- * API.)</para></footnote>
+ * scrolling support; these widgets implement the #GtkScrollable interface.
  * Widgets with native scroll support include #GtkTreeView, #GtkTextView,
  * and #GtkLayout.
  *
@@ -583,7 +575,10 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
   gtk_scrolled_window_adjustment_changed (hadjustment, scrolled_window);
 
   child = gtk_bin_get_child (bin);
-  if (child)
+  if (GTK_IS_SCROLLABLE (child))
+    gtk_scrollable_set_hadjustment (GTK_SCROLLABLE (child),
+                                    gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)));
+  else if (child)
     gtk_widget_set_scroll_adjustments (child,
 				       gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)),
 				       gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)));
@@ -600,7 +595,7 @@ gtk_scrolled_window_set_hadjustment (GtkScrolledWindow *scrolled_window,
  */
 void
 gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
-				     GtkAdjustment     *vadjustment)
+                                     GtkAdjustment     *vadjustment)
 {
   GtkScrolledWindowPrivate *priv;
   GtkBin *bin;
@@ -648,7 +643,10 @@ gtk_scrolled_window_set_vadjustment (GtkScrolledWindow *scrolled_window,
   gtk_scrolled_window_adjustment_changed (vadjustment, scrolled_window);
 
   child = gtk_bin_get_child (bin);
-  if (child)
+  if (GTK_IS_SCROLLABLE (child))
+    gtk_scrollable_set_vadjustment (GTK_SCROLLABLE (child),
+                                    gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)));
+  else if (child)
     gtk_widget_set_scroll_adjustments (child,
 				       gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)),
 				       gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar)));
@@ -1868,6 +1866,7 @@ gtk_scrolled_window_add (GtkContainer *container,
   GtkScrolledWindow *scrolled_window;
   GtkBin *bin;
   GtkWidget *child_widget;
+  GtkAdjustment *hadj, *vadj;
 
   bin = GTK_BIN (container);
   child_widget = gtk_bin_get_child (bin);
@@ -1879,12 +1878,14 @@ gtk_scrolled_window_add (GtkContainer *container,
   _gtk_bin_set_child (bin, child);
   gtk_widget_set_parent (child, GTK_WIDGET (bin));
 
-  /* this is a temporary message */
-  if (!gtk_widget_set_scroll_adjustments (child,
-					  gtk_range_get_adjustment (GTK_RANGE (priv->hscrollbar)),
-					  gtk_range_get_adjustment (GTK_RANGE (priv->vscrollbar))))
+  hadj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->priv->hscrollbar));
+  vadj = gtk_range_get_adjustment (GTK_RANGE (scrolled_window->priv->vscrollbar));
+
+  if (GTK_IS_SCROLLABLE (child))
+    g_object_set (child, "hadjustment", hadj, "vadjustment", vadj, NULL);
+  else if (!gtk_widget_set_scroll_adjustments (child, hadj, vadj))
     g_warning ("gtk_scrolled_window_add(): cannot add non scrollable widget "
-	       "use gtk_scrolled_window_add_with_viewport() instead");
+               "use gtk_scrolled_window_add_with_viewport() instead");
 }
 
 static void
@@ -1894,8 +1895,11 @@ gtk_scrolled_window_remove (GtkContainer *container,
   g_return_if_fail (GTK_IS_SCROLLED_WINDOW (container));
   g_return_if_fail (child != NULL);
   g_return_if_fail (gtk_bin_get_child (GTK_BIN (container)) == child);
-  
-  gtk_widget_set_scroll_adjustments (child, NULL, NULL);
+
+  if (GTK_IS_SCROLLABLE (child))
+    g_object_set (child, "hadjustment", NULL, "vadjustment", NULL, NULL);
+  else
+    gtk_widget_set_scroll_adjustments (child, NULL, NULL);
 
   /* chain parent class handler to remove child */
   GTK_CONTAINER_CLASS (gtk_scrolled_window_parent_class)->remove (container, child);
@@ -1920,9 +1924,8 @@ gtk_scrolled_window_remove (GtkContainer *container,
  * widgets with native scrolling support should not be used with the 
  * #GtkViewport proxy.
  *
- * A widget supports scrolling natively if the 
- * set_scroll_adjustments_signal field in #GtkWidgetClass is non-zero,
- * i.e. has been filled in with a valid signal identifier.
+ * A widget supports scrolling natively if it implements the
+ * #GtkScrollable interface.
  */
 void
 gtk_scrolled_window_add_with_viewport (GtkScrolledWindow *scrolled_window,
@@ -1950,7 +1953,7 @@ gtk_scrolled_window_add_with_viewport (GtkScrolledWindow *scrolled_window,
     {
       viewport =
         gtk_viewport_new (gtk_scrolled_window_get_hadjustment (scrolled_window),
-			  gtk_scrolled_window_get_vadjustment (scrolled_window));
+                          gtk_scrolled_window_get_vadjustment (scrolled_window));
       gtk_container_add (GTK_CONTAINER (scrolled_window), viewport);
     }
 
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index 3c28fde..fb2391a 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -48,6 +48,7 @@
 #include "gtkprivate.h"
 #include "gtktextutil.h"
 #include "gtkwindow.h"
+#include "gtkscrollable.h"
 
 
 /* How scrolling, validation, exposes, etc. work.
@@ -221,7 +222,6 @@ struct _GtkTextPendingScroll
 
 enum
 {
-  SET_SCROLL_ADJUSTMENTS,
   POPULATE_POPUP,
   MOVE_CURSOR,
   PAGE_HORIZONTALLY,
@@ -257,7 +257,9 @@ enum
   PROP_BUFFER,
   PROP_OVERWRITE,
   PROP_ACCEPTS_TAB,
-  PROP_IM_MODULE
+  PROP_IM_MODULE,
+  PROP_HADJUSTMENT,
+  PROP_VADJUSTMENT
 };
 
 static void gtk_text_view_finalize             (GObject          *object);
@@ -348,9 +350,6 @@ static void     gtk_text_view_drag_data_received (GtkWidget        *widget,
                                                   guint             info,
                                                   guint             time);
 
-static void gtk_text_view_set_scroll_adjustments (GtkTextView   *text_view,
-                                                  GtkAdjustment *hadj,
-                                                  GtkAdjustment *vadj);
 static gboolean gtk_text_view_popup_menu         (GtkWidget     *widget);
 
 static void gtk_text_view_move_cursor       (GtkTextView           *text_view,
@@ -440,9 +439,6 @@ static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
                                                   gint               x,
                                                   gint               y);
 
-static GtkAdjustment* get_hadjustment            (GtkTextView       *text_view);
-static GtkAdjustment* get_vadjustment            (GtkTextView       *text_view);
-
 static void gtk_text_view_do_popup               (GtkTextView       *text_view,
 						  GdkEventButton    *event);
 
@@ -459,6 +455,13 @@ static void     gtk_text_view_update_adjustments   (GtkTextView *text_view);
 static void     gtk_text_view_invalidate           (GtkTextView *text_view);
 static void     gtk_text_view_flush_first_validate (GtkTextView *text_view);
 
+static void     gtk_text_view_set_hadjustment        (GtkTextView   *text_view,
+                                                      GtkAdjustment *adjustment);
+static void     gtk_text_view_set_vadjustment        (GtkTextView   *text_view,
+                                                      GtkAdjustment *adjustment);
+static void     gtk_text_view_set_hadjustment_values (GtkTextView   *text_view);
+static void     gtk_text_view_set_vadjustment_values (GtkTextView   *text_view);
+
 static void gtk_text_view_update_im_spot_location (GtkTextView *text_view);
 
 /* Container methods */
@@ -534,7 +537,8 @@ static gint           text_window_get_height      (GtkTextWindow     *win);
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_TYPE (GtkTextView, gtk_text_view, GTK_TYPE_CONTAINER)
+G_DEFINE_TYPE_WITH_CODE (GtkTextView, gtk_text_view, GTK_TYPE_CONTAINER,
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
 
 static void
 add_move_binding (GtkBindingSet  *binding_set,
@@ -626,7 +630,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   klass->paste_clipboard = gtk_text_view_paste_clipboard;
   klass->toggle_overwrite = gtk_text_view_toggle_overwrite;
   klass->move_focus = gtk_text_view_compat_move_focus;
-  klass->set_scroll_adjustments = gtk_text_view_set_scroll_adjustments;
 
   /*
    * Properties
@@ -778,6 +781,10 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                                                          NULL,
                                                          GTK_PARAM_READWRITE));
 
+   /* GtkScrollable interface */
+   g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
+   g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+
   /*
    * Style properties
    */
@@ -1032,27 +1039,6 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
 		  G_TYPE_NONE, 0);
 
   /**
-   * GtkTextView::set-scroll-adjustments
-   * @horizontal: the horizontal #GtkAdjustment
-   * @vertical: the vertical #GtkAdjustment
-   *
-   * Set the scroll adjustments for the text view. Usually scrolled containers
-   * like #GtkScrolledWindow will emit this signal to connect two instances
-   * of #GtkScrollbar to the scroll directions of the #GtkTextView.
-   */
-  signals[SET_SCROLL_ADJUSTMENTS] =
-    g_signal_new (I_("set-scroll-adjustments"),
-		  G_OBJECT_CLASS_TYPE (gobject_class),
-		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		  G_STRUCT_OFFSET (GtkTextViewClass, set_scroll_adjustments),
-		  NULL, NULL,
-		  _gtk_marshal_VOID__OBJECT_OBJECT,
-		  G_TYPE_NONE, 2,
-		  GTK_TYPE_ADJUSTMENT,
-		  GTK_TYPE_ADJUSTMENT);
-  widget_class->set_scroll_adjustments_signal = signals[SET_SCROLL_ADJUSTMENTS];
-
-  /**
    * GtkTextView::populate-popup:
    * @entry: The text view on which the signal is emitted
    * @menu: the menu that is being populated
@@ -1924,7 +1910,7 @@ gtk_text_view_scroll_to_iter (GtkTextView   *text_view,
   
   if (scroll_inc != 0)
     {
-      retval = set_adjustment_clamped (get_vadjustment (text_view),
+      retval = set_adjustment_clamped (text_view->priv->vadjustment,
                                        current_y_scroll + scroll_inc);
 
       DV (g_print (" vert increment %d\n", scroll_inc));
@@ -1961,7 +1947,7 @@ gtk_text_view_scroll_to_iter (GtkTextView   *text_view,
   
   if (scroll_inc != 0)
     {
-      retval = set_adjustment_clamped (get_hadjustment (text_view),
+      retval = set_adjustment_clamped (text_view->priv->hadjustment,
                                        current_x_scroll + scroll_inc);
 
       DV (g_print (" horiz increment %d\n", scroll_inc));
@@ -2090,33 +2076,6 @@ gtk_text_view_flush_scroll (GtkTextView *text_view)
 }
 
 static void
-gtk_text_view_set_adjustment_upper (GtkAdjustment *adj, gdouble upper)
-{  
-  if (upper != adj->upper)
-    {
-      gdouble min = MAX (0.0, upper - adj->page_size);
-      gboolean value_changed = FALSE;
-
-      adj->upper = upper;
-
-      if (adj->value > min)
-        {
-          adj->value = min;
-          value_changed = TRUE;
-        }
-
-      gtk_adjustment_changed (adj);
-      DV(g_print(">Changed adj upper to %g ("G_STRLOC")\n", upper));
-      
-      if (value_changed)
-        {
-          DV(g_print(">Changed adj value because upper decreased ("G_STRLOC")\n"));
-	  gtk_adjustment_value_changed (adj);
-        }
-    }
-}
-
-static void
 gtk_text_view_update_adjustments (GtkTextView *text_view)
 {
   GtkTextViewPrivate *priv;
@@ -2140,28 +2099,8 @@ gtk_text_view_update_adjustments (GtkTextView *text_view)
       priv->width = width;
       priv->height = height;
 
-      gtk_text_view_set_adjustment_upper (get_hadjustment (text_view),
-                                          MAX (SCREEN_WIDTH (text_view), width));
-      gtk_text_view_set_adjustment_upper (get_vadjustment (text_view),
-                                          MAX (SCREEN_HEIGHT (text_view), height));
-      
-      /* hadj/vadj exist since we called get_hadjustment/get_vadjustment above */
-
-      /* Set up the step sizes; we'll say that a page is
-         our allocation minus one step, and a step is
-         1/10 of our allocation. */
-      priv->hadjustment->step_increment =
-        SCREEN_WIDTH (text_view) / 10.0;
-      priv->hadjustment->page_increment =
-        SCREEN_WIDTH (text_view) * 0.9;
-      
-      priv->vadjustment->step_increment =
-        SCREEN_HEIGHT (text_view) / 10.0;
-      priv->vadjustment->page_increment =
-        SCREEN_HEIGHT (text_view) * 0.9;
-
-      gtk_adjustment_changed (get_hadjustment (text_view));
-      gtk_adjustment_changed (get_vadjustment (text_view));
+      gtk_text_view_set_hadjustment_values (text_view);
+      gtk_text_view_set_vadjustment_values (text_view);
     }
 }
 
@@ -3156,6 +3095,14 @@ gtk_text_view_set_property (GObject         *object,
         gtk_im_multicontext_set_context_id (GTK_IM_MULTICONTEXT (priv->im_context), priv->im_module);
       break;
 
+    case PROP_HADJUSTMENT:
+      gtk_text_view_set_hadjustment (text_view, g_value_get_object (value));
+      break;
+
+    case PROP_VADJUSTMENT:
+      gtk_text_view_set_vadjustment (text_view, g_value_get_object (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3236,6 +3183,14 @@ gtk_text_view_get_property (GObject         *object,
       g_value_set_string (value, priv->im_module);
       break;
 
+    case PROP_HADJUSTMENT:
+      g_value_set_object (value, priv->hadjustment);
+      break;
+
+    case PROP_VADJUSTMENT:
+      g_value_set_object (value, priv->vadjustment);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -3475,8 +3430,6 @@ gtk_text_view_size_allocate (GtkWidget *widget,
   GtkAllocation widget_allocation;
   GtkTextView *text_view;
   GtkTextViewPrivate *priv;
-  GtkTextIter first_para;
-  gint y;
   gint width, height;
   GdkRectangle text_rect;
   GdkRectangle left_rect;
@@ -3607,44 +3560,9 @@ gtk_text_view_size_allocate (GtkWidget *widget,
   /* Note that this will do some layout validation */
   gtk_text_view_allocate_children (text_view);
 
-  /* Ensure h/v adj exist */
-  get_hadjustment (text_view);
-  get_vadjustment (text_view);
-
-  priv->hadjustment->page_size = SCREEN_WIDTH (text_view);
-  priv->hadjustment->page_increment = SCREEN_WIDTH (text_view) * 0.9;
-  priv->hadjustment->step_increment = SCREEN_WIDTH (text_view) * 0.1;
-  priv->hadjustment->lower = 0;
-  priv->hadjustment->upper = MAX (SCREEN_WIDTH (text_view),
-                                  priv->width);
-
-  if (priv->hadjustment->value > priv->hadjustment->upper - priv->hadjustment->page_size)
-    gtk_adjustment_set_value (priv->hadjustment, MAX (0, priv->hadjustment->upper - priv->hadjustment->page_size));
-
-  gtk_adjustment_changed (priv->hadjustment);
-
-  priv->vadjustment->page_size = SCREEN_HEIGHT (text_view);
-  priv->vadjustment->page_increment = SCREEN_HEIGHT (text_view) * 0.9;
-  priv->vadjustment->step_increment = SCREEN_HEIGHT (text_view) * 0.1;
-  priv->vadjustment->lower = 0;
-  priv->vadjustment->upper = MAX (SCREEN_HEIGHT (text_view),
-                                  priv->height);
-
-  /* Now adjust the value of the adjustment to keep the cursor at the
-   * same place in the buffer
-   */
-  gtk_text_view_get_first_para_iter (text_view, &first_para);
-  gtk_text_layout_get_line_yrange (priv->layout, &first_para, &y, NULL);
-
-  y += priv->first_para_pixels;
-
-  if (y > priv->vadjustment->upper - priv->vadjustment->page_size)
-    y = MAX (0, priv->vadjustment->upper - priv->vadjustment->page_size);
-
-  if (y != priv->yoffset)
-    gtk_adjustment_set_value (priv->vadjustment, y);
-
-  gtk_adjustment_changed (priv->vadjustment);
+  /* Update adjustments */
+  gtk_text_view_set_hadjustment_values (text_view);
+  gtk_text_view_set_vadjustment_values (text_view);
 
   /* The GTK resize loop processes all the pending exposes right
    * after doing the resize stuff, so the idle sizer won't have a
@@ -3923,14 +3841,14 @@ changed_handler (GtkTextLayout     *layout,
         {
           priv->yoffset += new_first_para_top - old_first_para_top;
           
-          get_vadjustment (text_view)->value = priv->yoffset;
+          text_view->priv->vadjustment->value = priv->yoffset;
           yoffset_changed = TRUE;
         }
 
       if (yoffset_changed)
         {
           DV(g_print ("Changing scroll position (%s)\n", G_STRLOC));
-          gtk_adjustment_value_changed (get_vadjustment (text_view));
+          gtk_adjustment_value_changed (text_view->priv->vadjustment);
         }
 
       /* FIXME be smarter about which anchored widgets we update */
@@ -5530,15 +5448,15 @@ gtk_text_view_move_viewport (GtkTextView     *text_view,
     case GTK_SCROLL_STEPS:
     case GTK_SCROLL_PAGES:
     case GTK_SCROLL_ENDS:
-      adjustment = get_vadjustment (text_view);
+      adjustment = text_view->priv->vadjustment;
       break;
     case GTK_SCROLL_HORIZONTAL_STEPS:
     case GTK_SCROLL_HORIZONTAL_PAGES:
     case GTK_SCROLL_HORIZONTAL_ENDS:
-      adjustment = get_hadjustment (text_view);
+      adjustment = text_view->priv->hadjustment;
       break;
     default:
-      adjustment = get_vadjustment (text_view);
+      adjustment = text_view->priv->vadjustment;
       break;
     }
 
@@ -7348,13 +7266,43 @@ gtk_text_view_drag_data_received (GtkWidget        *widget,
  * Returns: (transfer none): pointer to the horizontal #GtkAdjustment
  *
  * Since: 2.22
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
  **/
 GtkAdjustment*
 gtk_text_view_get_hadjustment (GtkTextView *text_view)
 {
   g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), NULL);
 
-  return get_hadjustment (text_view);
+  return text_view->priv->hadjustment;
+}
+
+static void
+gtk_text_view_set_hadjustment (GtkTextView   *text_view,
+                               GtkAdjustment *adjustment)
+{
+  GtkTextViewPrivate *priv = text_view->priv;
+
+  if (adjustment && priv->hadjustment == adjustment)
+    return;
+
+  if (priv->hadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->hadjustment,
+                                            gtk_text_view_value_changed,
+                                            text_view);
+      g_object_unref (priv->hadjustment);
+    }
+
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_text_view_value_changed), text_view);
+  priv->hadjustment = g_object_ref_sink (adjustment);
+  gtk_text_view_set_hadjustment_values (text_view);
+
+  g_object_notify (G_OBJECT (text_view), "hadjustment");
 }
 
 /**
@@ -7372,89 +7320,103 @@ gtk_text_view_get_vadjustment (GtkTextView *text_view)
 {
   g_return_val_if_fail (GTK_IS_TEXT_VIEW (text_view), NULL);
 
-  return get_vadjustment (text_view);
+  return text_view->priv->vadjustment;
 }
 
-static GtkAdjustment*
-get_hadjustment (GtkTextView *text_view)
+static void
+gtk_text_view_set_vadjustment (GtkTextView   *text_view,
+                               GtkAdjustment *adjustment)
 {
-  if (text_view->priv->hadjustment == NULL)
-    gtk_text_view_set_scroll_adjustments (text_view,
-                                          NULL, /* forces creation */
-                                          text_view->priv->vadjustment);
+  GtkTextViewPrivate *priv = text_view->priv;
 
-  return text_view->priv->hadjustment;
+  if (adjustment && priv->vadjustment == adjustment)
+    return;
+
+  if (priv->vadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->vadjustment,
+                                            gtk_text_view_value_changed,
+                                            text_view);
+      g_object_unref (priv->vadjustment);
+    }
+
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_text_view_value_changed), text_view);
+  priv->vadjustment = g_object_ref_sink (adjustment);
+  gtk_text_view_set_vadjustment_values (text_view);
+
+  g_object_notify (G_OBJECT (text_view), "vadjustment");
 }
 
-static GtkAdjustment*
-get_vadjustment (GtkTextView *text_view)
+static void
+gtk_text_view_set_hadjustment_values (GtkTextView *text_view)
 {
-  if (text_view->priv->vadjustment == NULL)
-    gtk_text_view_set_scroll_adjustments (text_view,
-                                          text_view->priv->hadjustment,
-                                          NULL); /* forces creation */
-  return text_view->priv->vadjustment;
-}
+  GtkTextViewPrivate *priv;
+  gint screen_width;
+  gdouble old_value;
+  gdouble new_value;
+  gdouble new_upper;
+
+  priv = text_view->priv;
+
+  screen_width = SCREEN_WIDTH (text_view);
+  old_value = gtk_adjustment_get_value (priv->hadjustment);
+  new_upper = MAX (screen_width, priv->width);
 
+  g_object_set (priv->hadjustment,
+                "lower", 0.0,
+                "upper", new_upper,
+                "page-size", (gdouble)screen_width,
+                "step-increment", screen_width * 0.1,
+                "page-increment", screen_width * 0.9,
+                NULL);
+
+  new_value = CLAMP (old_value, 0, new_upper - screen_width);
+  if (new_value != old_value)
+    gtk_adjustment_set_value (priv->hadjustment, new_value);
+}
 
 static void
-gtk_text_view_set_scroll_adjustments (GtkTextView   *text_view,
-                                      GtkAdjustment *hadj,
-                                      GtkAdjustment *vadj)
+gtk_text_view_set_vadjustment_values (GtkTextView *text_view)
 {
-  GtkTextViewPrivate *priv = text_view->priv;
-  gboolean need_adjust = FALSE;
+  GtkTextViewPrivate *priv;
+  GtkTextIter first_para;
+  gint screen_height;
+  gint y;
+  gdouble old_value;
+  gdouble new_value;
+  gdouble new_upper;
 
-  if (hadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
-  else
-    hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-  if (vadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
-  else
-    vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+  priv = text_view->priv;
 
-  if (priv->hadjustment && (priv->hadjustment != hadj))
-    {
-      g_signal_handlers_disconnect_by_func (priv->hadjustment,
-					    gtk_text_view_value_changed,
-					    text_view);
-      g_object_unref (priv->hadjustment);
-    }
+  screen_height = SCREEN_HEIGHT (text_view);
+  old_value = gtk_adjustment_get_value (priv->vadjustment);
+  new_upper = MAX (screen_height, priv->height);
 
-  if (priv->vadjustment && (priv->vadjustment != vadj))
-    {
-      g_signal_handlers_disconnect_by_func (priv->vadjustment,
-					    gtk_text_view_value_changed,
-					    text_view);
-      g_object_unref (priv->vadjustment);
-    }
+  g_object_set (priv->vadjustment,
+                "lower", 0.0,
+                "upper", new_upper,
+                "page-size", (gdouble)screen_height,
+                "step-increment", screen_height * 0.1,
+                "page-increment", screen_height * 0.9,
+                NULL);
 
-  if (priv->hadjustment != hadj)
-    {
-      priv->hadjustment = hadj;
-      g_object_ref_sink (priv->hadjustment);
-      
-      g_signal_connect (priv->hadjustment, "value-changed",
-                        G_CALLBACK (gtk_text_view_value_changed),
-			text_view);
-      need_adjust = TRUE;
-    }
+  /* Now adjust the value of the adjustment to keep the cursor at the
+   * same place in the buffer */
+  gtk_text_view_ensure_layout (text_view);
+  gtk_text_view_get_first_para_iter (text_view, &first_para);
+  gtk_text_layout_get_line_yrange (priv->layout, &first_para, &y, NULL);
 
-  if (priv->vadjustment != vadj)
-    {
-      priv->vadjustment = vadj;
-      g_object_ref_sink (priv->vadjustment);
-      
-      g_signal_connect (priv->vadjustment, "value-changed",
-                        G_CALLBACK (gtk_text_view_value_changed),
-			text_view);
-      need_adjust = TRUE;
-    }
+  y += priv->first_para_pixels;
+
+  new_value = CLAMP (y, 0, new_upper - screen_height);
+  if (new_value != old_value)
+    gtk_adjustment_set_value (priv->vadjustment, new_value);
+ }
 
-  if (need_adjust)
-    gtk_text_view_value_changed (NULL, text_view);
-}
 
 /* FIXME this adjust_allocation is a big cut-and-paste from
  * GtkCList, needs to be some "official" way to do this
diff --git a/gtk/gtktextview.h b/gtk/gtktextview.h
index 1391c1b..6c5c500 100644
--- a/gtk/gtktextview.h
+++ b/gtk/gtktextview.h
@@ -73,10 +73,6 @@ struct _GtkTextViewClass
 {
   GtkContainerClass parent_class;
 
-  void (* set_scroll_adjustments)   (GtkTextView    *text_view,
-                                     GtkAdjustment  *hadjustment,
-                                     GtkAdjustment  *vadjustment);
-
   void (* populate_popup)           (GtkTextView    *text_view,
                                      GtkMenu        *menu);
 
@@ -188,8 +184,10 @@ void gtk_text_view_window_to_buffer_coords (GtkTextView       *text_view,
                                             gint              *buffer_x,
                                             gint              *buffer_y);
 
-GtkAdjustment* gtk_text_view_get_hadjustment (GtkTextView *text_view);
-GtkAdjustment* gtk_text_view_get_vadjustment (GtkTextView *text_view);
+#ifndef GTK_DISABLE_DEPRECATED
+GtkAdjustment*   gtk_text_view_get_hadjustment (GtkTextView   *text_view);
+GtkAdjustment*   gtk_text_view_get_vadjustment (GtkTextView   *text_view);
+#endif
 
 GdkWindow*        gtk_text_view_get_window      (GtkTextView       *text_view,
                                                  GtkTextWindowType  win);
diff --git a/gtk/gtktoolpalette.c b/gtk/gtktoolpalette.c
index 397608e..cbc77c6 100644
--- a/gtk/gtktoolpalette.c
+++ b/gtk/gtktoolpalette.c
@@ -28,6 +28,7 @@
 #include "gtkmarshalers.h"
 
 #include "gtkprivate.h"
+#include "gtkscrollable.h"
 #include "gtkintl.h"
 
 #define DEFAULT_ICON_SIZE       GTK_ICON_SIZE_SMALL_TOOLBAR
@@ -120,6 +121,8 @@ enum
   PROP_ICON_SIZE_SET,
   PROP_ORIENTATION,
   PROP_TOOLBAR_STYLE,
+  PROP_HADJUSTMENT,
+  PROP_VADJUSTMENT
 };
 
 enum
@@ -177,10 +180,17 @@ static const GtkTargetEntry dnd_targets[] =
   { "application/x-gtk-tool-palette-group", GTK_TARGET_SAME_APP, 0 },
 };
 
+static void gtk_tool_palette_set_hadjustment (GtkToolPalette *palette,
+                                              GtkAdjustment  *adjustment);
+static void gtk_tool_palette_set_vadjustment (GtkToolPalette *palette,
+                                              GtkAdjustment  *adjustment);
+
+
 G_DEFINE_TYPE_WITH_CODE (GtkToolPalette,
                gtk_tool_palette,
                GTK_TYPE_CONTAINER,
-               G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL));
+               G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)
+	       G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
 
 static void
 gtk_tool_palette_init (GtkToolPalette *palette)
@@ -258,6 +268,14 @@ gtk_tool_palette_set_property (GObject      *object,
           }
         break;
 
+      case PROP_HADJUSTMENT:
+        gtk_tool_palette_set_hadjustment (palette, g_value_get_object (value));
+        break;
+
+      case PROP_VADJUSTMENT:
+        gtk_tool_palette_set_vadjustment (palette, g_value_get_object (value));
+        break;
+
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -290,6 +308,14 @@ gtk_tool_palette_get_property (GObject    *object,
         g_value_set_enum (value, gtk_tool_palette_get_style (palette));
         break;
 
+      case PROP_HADJUSTMENT:
+        g_value_set_object (value, palette->priv->hadjustment);
+        break;
+
+      case PROP_VADJUSTMENT:
+        g_value_set_object (value, palette->priv->vadjustment);
+        break;
+
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -703,33 +729,47 @@ gtk_tool_palette_adjustment_value_changed (GtkAdjustment *adjustment,
 }
 
 static void
-gtk_tool_palette_set_scroll_adjustments (GtkWidget     *widget,
-                                         GtkAdjustment *hadjustment,
-                                         GtkAdjustment *vadjustment)
+gtk_tool_palette_set_adjustment (GtkToolPalette *palette,
+				 GtkOrientation  orientation,
+				 GtkAdjustment  *adjustment)
 {
-  GtkToolPalette *palette = GTK_TOOL_PALETTE (widget);
+  GtkAdjustment **adj_ptr;
 
-  if (hadjustment)
-    g_object_ref_sink (hadjustment);
-  if (vadjustment)
-    g_object_ref_sink (vadjustment);
+  if (orientation == GTK_ORIENTATION_HORIZONTAL)
+    {
+      if (adjustment && palette->priv->hadjustment == adjustment)
+	return;
 
-  if (palette->priv->hadjustment)
-    g_object_unref (palette->priv->hadjustment);
-  if (palette->priv->vadjustment)
-    g_object_unref (palette->priv->vadjustment);
+      adj_ptr = &palette->priv->hadjustment;
+    }
+  else
+    {
+      if (adjustment && palette->priv->vadjustment == adjustment)
+	return;
 
-  palette->priv->hadjustment = hadjustment;
-  palette->priv->vadjustment = vadjustment;
+      adj_ptr = &palette->priv->vadjustment;
+    }
 
-  if (palette->priv->hadjustment)
-    g_signal_connect (palette->priv->hadjustment, "value-changed",
-                      G_CALLBACK (gtk_tool_palette_adjustment_value_changed),
-                      palette);
-  if (palette->priv->vadjustment)
-    g_signal_connect (palette->priv->vadjustment, "value-changed",
-                      G_CALLBACK (gtk_tool_palette_adjustment_value_changed),
-                      palette);
+  /* Disconnect handler */
+  if (*adj_ptr)
+    {
+      g_signal_handlers_disconnect_by_func (*adj_ptr,
+					    gtk_tool_palette_adjustment_value_changed,
+					    palette);
+      g_object_unref (*adj_ptr);
+    }
+
+  /* Ensure adjustment */
+  if (!adjustment)
+    adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0,
+						     0.0, 0.0, 0.0));
+
+  /* Connect signal handler */
+  g_signal_connect (adjustment, "value-changed",
+		    G_CALLBACK (gtk_tool_palette_adjustment_value_changed),
+		    palette);
+  *adj_ptr = g_object_ref_sink (adjustment);
+  /* FIXME: Adjustment should probably have it's values updated now */
 }
 
 static void
@@ -952,38 +992,15 @@ gtk_tool_palette_class_init (GtkToolPaletteClass *cls)
   cclass->set_child_property  = gtk_tool_palette_set_child_property;
   cclass->get_child_property  = gtk_tool_palette_get_child_property;
 
-  cls->set_scroll_adjustments = gtk_tool_palette_set_scroll_adjustments;
-
   /* Handle screen-changed so we can update our GtkSettings.
    */
   wclass->screen_changed      = gtk_tool_palette_screen_changed;
 
-  /**
-   * GtkToolPalette::set-scroll-adjustments:
-   * @widget: the GtkToolPalette that received the signal
-   * @hadjustment: The horizontal adjustment
-   * @vadjustment: The vertical adjustment
-   *
-   * Set the scroll adjustments for the viewport.
-   * Usually scrolled containers like GtkScrolledWindow will emit this
-   * signal to connect two instances of GtkScrollbar to the scroll
-   * directions of the GtkToolpalette.
-   *
-   * Since: 2.20
-   */
-  wclass->set_scroll_adjustments_signal =
-    g_signal_new ("set-scroll-adjustments",
-                  G_TYPE_FROM_CLASS (oclass),
-                  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-                  G_STRUCT_OFFSET (GtkToolPaletteClass, set_scroll_adjustments),
-                  NULL, NULL,
-                  _gtk_marshal_VOID__OBJECT_OBJECT,
-                  G_TYPE_NONE, 2,
-                  GTK_TYPE_ADJUSTMENT,
-                  GTK_TYPE_ADJUSTMENT);
-
   g_object_class_override_property (oclass, PROP_ORIENTATION, "orientation");
 
+  g_object_class_override_property (oclass, PROP_HADJUSTMENT, "hadjustment");
+  g_object_class_override_property (oclass, PROP_VADJUSTMENT, "vadjustment");
+
   /**
    * GtkToolPalette:icon-size:
    *
@@ -1908,6 +1925,8 @@ _gtk_tool_palette_set_expanding_child (GtkToolPalette *palette,
  * Returns: (transfer none): the horizontal adjustment of @palette
  *
  * Since: 2.20
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
  */
 GtkAdjustment*
 gtk_tool_palette_get_hadjustment (GtkToolPalette *palette)
@@ -1917,6 +1936,35 @@ gtk_tool_palette_get_hadjustment (GtkToolPalette *palette)
   return palette->priv->hadjustment;
 }
 
+static void
+gtk_tool_palette_set_hadjustment (GtkToolPalette *palette,
+                                  GtkAdjustment  *adjustment)
+{
+  GtkToolPalettePrivate *priv = palette->priv;
+
+  if (adjustment && priv->hadjustment == adjustment)
+    return;
+
+  if (priv->hadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->hadjustment,
+                                            gtk_tool_palette_adjustment_value_changed,
+                                            palette);
+      g_object_unref (priv->hadjustment);
+    }
+
+  if (adjustment != NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_tool_palette_adjustment_value_changed),
+                    palette);
+  priv->hadjustment = g_object_ref_sink (adjustment);
+  /* FIXME: Adjustment should probably have it's values updated now */
+  g_object_notify (G_OBJECT (palette), "hadjustment");
+}
+
 /**
  * gtk_tool_palette_get_vadjustment:
  * @palette: a #GtkToolPalette
@@ -1926,6 +1974,8 @@ gtk_tool_palette_get_hadjustment (GtkToolPalette *palette)
  * Returns: (transfer none): the vertical adjustment of @palette
  *
  * Since: 2.20
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment()
  */
 GtkAdjustment*
 gtk_tool_palette_get_vadjustment (GtkToolPalette *palette)
@@ -1935,6 +1985,35 @@ gtk_tool_palette_get_vadjustment (GtkToolPalette *palette)
   return palette->priv->vadjustment;
 }
 
+static void
+gtk_tool_palette_set_vadjustment (GtkToolPalette *palette,
+                                  GtkAdjustment  *adjustment)
+{
+  GtkToolPalettePrivate *priv = palette->priv;
+
+  if (adjustment && priv->vadjustment == adjustment)
+    return;
+
+  if (priv->vadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->vadjustment,
+                                            gtk_tool_palette_adjustment_value_changed,
+                                            palette);
+      g_object_unref (priv->vadjustment);
+    }
+
+  if (adjustment != NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_tool_palette_adjustment_value_changed),
+                    palette);
+  priv->vadjustment = g_object_ref_sink (adjustment);
+  /* FIXME: Adjustment should probably have it's values updated now */
+  g_object_notify (G_OBJECT (palette), "vadjustment");
+}
+
 GtkSizeGroup *
 _gtk_tool_palette_get_size_group (GtkToolPalette *palette)
 {
diff --git a/gtk/gtktoolpalette.h b/gtk/gtktoolpalette.h
index c98dbef..d34ece5 100644
--- a/gtk/gtktoolpalette.h
+++ b/gtk/gtktoolpalette.h
@@ -72,10 +72,6 @@ struct _GtkToolPaletteClass
 {
   GtkContainerClass parent_class;
 
-  void (*set_scroll_adjustments) (GtkWidget     *widget,
-                                  GtkAdjustment *hadjustment,
-                                  GtkAdjustment *vadjustment);
-
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
   void (*_gtk_reserved2) (void);
@@ -132,9 +128,13 @@ void                           gtk_tool_palette_add_drag_dest         (GtkToolPa
                                                                        GtkToolPaletteDragTargets  targets,
                                                                        GdkDragAction              actions);
 
+#ifndef GTK_DISABLE_DEPRECATED
+
 GtkAdjustment*                 gtk_tool_palette_get_hadjustment       (GtkToolPalette            *palette);
 GtkAdjustment*                 gtk_tool_palette_get_vadjustment       (GtkToolPalette            *palette);
 
+#endif
+
 G_CONST_RETURN GtkTargetEntry* gtk_tool_palette_get_drag_target_item  (void) G_GNUC_CONST;
 G_CONST_RETURN GtkTargetEntry* gtk_tool_palette_get_drag_target_group (void) G_GNUC_CONST;
 
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 662b7e0..36f6280 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -44,6 +44,7 @@
 #include "gtkframe.h"
 #include "gtktreemodelsort.h"
 #include "gtktooltip.h"
+#include "gtkscrollable.h"
 #include "gtkprivate.h"
 
 #define GTK_TREE_VIEW_PRIORITY_VALIDATE (GDK_PRIORITY_REDRAW + 5)
@@ -248,9 +249,10 @@ static void     gtk_tree_view_drag_data_received (GtkWidget        *widget,
                                                   guint             time);
 
 /* tree_model signals */
-static void gtk_tree_view_set_adjustments                 (GtkTreeView     *tree_view,
-							   GtkAdjustment   *hadj,
-							   GtkAdjustment   *vadj);
+static void     gtk_tree_view_set_hadjustment             (GtkTreeView     *tree_view,
+                                                           GtkAdjustment   *adjustment);
+static void     gtk_tree_view_set_vadjustment             (GtkTreeView     *tree_view,
+                                                           GtkAdjustment   *adjustment);
 static gboolean gtk_tree_view_real_move_cursor            (GtkTreeView     *tree_view,
 							   GtkMovementStep  step,
 							   gint             count);
@@ -487,7 +489,8 @@ static guint tree_view_signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE_WITH_CODE (GtkTreeView, gtk_tree_view, GTK_TYPE_CONTAINER,
 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
-						gtk_tree_view_buildable_init))
+						gtk_tree_view_buildable_init)
+			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
 
 static void
 gtk_tree_view_class_init (GtkTreeViewClass *class)
@@ -545,7 +548,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   container_class->forall = gtk_tree_view_forall;
   container_class->set_focus_child = gtk_tree_view_set_focus_child;
 
-  class->set_scroll_adjustments = gtk_tree_view_set_adjustments;
   class->move_cursor = gtk_tree_view_real_move_cursor;
   class->select_all = gtk_tree_view_real_select_all;
   class->unselect_all = gtk_tree_view_real_unselect_all;
@@ -565,21 +567,8 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 							GTK_TYPE_TREE_MODEL,
 							GTK_PARAM_READWRITE));
 
-  g_object_class_install_property (o_class,
-                                   PROP_HADJUSTMENT,
-                                   g_param_spec_object ("hadjustment",
-							P_("Horizontal Adjustment"),
-                                                        P_("Horizontal Adjustment for the widget"),
-                                                        GTK_TYPE_ADJUSTMENT,
-                                                        GTK_PARAM_READWRITE));
-
-  g_object_class_install_property (o_class,
-                                   PROP_VADJUSTMENT,
-                                   g_param_spec_object ("vadjustment",
-							P_("Vertical Adjustment"),
-                                                        P_("Vertical Adjustment for the widget"),
-                                                        GTK_TYPE_ADJUSTMENT,
-                                                        GTK_PARAM_READWRITE));
+  g_object_class_override_property (o_class, PROP_HADJUSTMENT, "hadjustment");
+  g_object_class_override_property (o_class, PROP_VADJUSTMENT, "vadjustment");
 
   g_object_class_install_property (o_class,
                                    PROP_HEADERS_VISIBLE,
@@ -856,26 +845,6 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   /* Signals */
   /**
-   * GtkTreeView::set-scroll-adjustments
-   * @horizontal: the horizontal #GtkAdjustment
-   * @vertical: the vertical #GtkAdjustment
-   *
-   * Set the scroll adjustments for the tree view. Usually scrolled containers
-   * like #GtkScrolledWindow will emit this signal to connect two instances
-   * of #GtkScrollbar to the scroll directions of the #GtkTreeView.
-   */
-  widget_class->set_scroll_adjustments_signal =
-    g_signal_new (I_("set-scroll-adjustments"),
-		  G_TYPE_FROM_CLASS (o_class),
-		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		  G_STRUCT_OFFSET (GtkTreeViewClass, set_scroll_adjustments),
-		  NULL, NULL,
-		  _gtk_marshal_VOID__OBJECT_OBJECT,
-		  G_TYPE_NONE, 2,
-		  GTK_TYPE_ADJUSTMENT,
-		  GTK_TYPE_ADJUSTMENT);
-
-  /**
    * GtkTreeView::row-activated:
    * @tree_view: the object on which the signal is emitted
    * @path: the #GtkTreePath for the activated row
@@ -1336,7 +1305,6 @@ gtk_tree_view_init (GtkTreeView *tree_view)
   tree_view->priv->fixed_height = -1;
   tree_view->priv->fixed_height_mode = FALSE;
   tree_view->priv->fixed_height_check = 0;
-  gtk_tree_view_set_adjustments (tree_view, NULL, NULL);
   tree_view->priv->selection = _gtk_tree_selection_new_with_tree_view (tree_view);
   tree_view->priv->enable_search = TRUE;
   tree_view->priv->search_column = -1;
@@ -8111,67 +8079,6 @@ gtk_tree_view_set_focus_child (GtkContainer *container,
   GTK_CONTAINER_CLASS (gtk_tree_view_parent_class)->set_focus_child (container, child);
 }
 
-static void
-gtk_tree_view_set_adjustments (GtkTreeView   *tree_view,
-			       GtkAdjustment *hadj,
-			       GtkAdjustment *vadj)
-{
-  gboolean need_adjust = FALSE;
-
-  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
-
-  if (hadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
-  else
-    hadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-  if (vadj)
-    g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
-  else
-    vadj = gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
-
-  if (tree_view->priv->hadjustment && (tree_view->priv->hadjustment != hadj))
-    {
-      g_signal_handlers_disconnect_by_func (tree_view->priv->hadjustment,
-					    gtk_tree_view_adjustment_changed,
-					    tree_view);
-      g_object_unref (tree_view->priv->hadjustment);
-    }
-
-  if (tree_view->priv->vadjustment && (tree_view->priv->vadjustment != vadj))
-    {
-      g_signal_handlers_disconnect_by_func (tree_view->priv->vadjustment,
-					    gtk_tree_view_adjustment_changed,
-					    tree_view);
-      g_object_unref (tree_view->priv->vadjustment);
-    }
-
-  if (tree_view->priv->hadjustment != hadj)
-    {
-      tree_view->priv->hadjustment = hadj;
-      g_object_ref_sink (tree_view->priv->hadjustment);
-
-      g_signal_connect (tree_view->priv->hadjustment, "value-changed",
-			G_CALLBACK (gtk_tree_view_adjustment_changed),
-			tree_view);
-      need_adjust = TRUE;
-    }
-
-  if (tree_view->priv->vadjustment != vadj)
-    {
-      tree_view->priv->vadjustment = vadj;
-      g_object_ref_sink (tree_view->priv->vadjustment);
-
-      g_signal_connect (tree_view->priv->vadjustment, "value-changed",
-			G_CALLBACK (gtk_tree_view_adjustment_changed),
-			tree_view);
-      need_adjust = TRUE;
-    }
-
-  if (need_adjust)
-    gtk_tree_view_adjustment_changed (NULL, tree_view);
-}
-
-
 static gboolean
 gtk_tree_view_real_move_cursor (GtkTreeView       *tree_view,
 				GtkMovementStep    step,
@@ -10928,15 +10835,14 @@ gtk_tree_view_get_selection (GtkTreeView *tree_view)
  *
  * Return value: (transfer none): A #GtkAdjustment object, or %NULL
  *     if none is currently being used.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
  **/
 GtkAdjustment *
 gtk_tree_view_get_hadjustment (GtkTreeView *tree_view)
 {
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
 
-  if (tree_view->priv->hadjustment == NULL)
-    gtk_tree_view_set_hadjustment (tree_view, NULL);
-
   return tree_view->priv->hadjustment;
 }
 
@@ -10946,16 +10852,40 @@ gtk_tree_view_get_hadjustment (GtkTreeView *tree_view)
  * @adjustment: (allow-none): The #GtkAdjustment to set, or %NULL
  *
  * Sets the #GtkAdjustment for the current horizontal aspect.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_hadjustment()
  **/
 void
 gtk_tree_view_set_hadjustment (GtkTreeView   *tree_view,
-			       GtkAdjustment *adjustment)
+                               GtkAdjustment *adjustment)
 {
+  GtkTreeViewPrivate *priv = tree_view->priv;
+
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
+
+  if (adjustment && priv->hadjustment == adjustment)
+    return;
 
-  gtk_tree_view_set_adjustments (tree_view,
-				 adjustment,
-				 tree_view->priv->vadjustment);
+  if (priv->hadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->hadjustment,
+                                            gtk_tree_view_adjustment_changed,
+                                            tree_view);
+      g_object_unref (priv->hadjustment);
+    }
+
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_tree_view_adjustment_changed), tree_view);
+  priv->hadjustment = g_object_ref_sink (adjustment);
+  /* FIXME: Adjustment should probably be populated here with fresh values, but
+   * internal details are too complicated for me to decipher right now.
+   */
+  gtk_tree_view_adjustment_changed (NULL, tree_view);
 
   g_object_notify (G_OBJECT (tree_view), "hadjustment");
 }
@@ -10968,15 +10898,14 @@ gtk_tree_view_set_hadjustment (GtkTreeView   *tree_view,
  *
  * Return value: (transfer none): A #GtkAdjustment object, or %NULL
  *     if none is currently being used.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment()
  **/
 GtkAdjustment *
 gtk_tree_view_get_vadjustment (GtkTreeView *tree_view)
 {
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), NULL);
 
-  if (tree_view->priv->vadjustment == NULL)
-    gtk_tree_view_set_vadjustment (tree_view, NULL);
-
   return tree_view->priv->vadjustment;
 }
 
@@ -10986,17 +10915,40 @@ gtk_tree_view_get_vadjustment (GtkTreeView *tree_view)
  * @adjustment: (allow-none): The #GtkAdjustment to set, or %NULL
  *
  * Sets the #GtkAdjustment for the current vertical aspect.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment()
  **/
 void
 gtk_tree_view_set_vadjustment (GtkTreeView   *tree_view,
-			       GtkAdjustment *adjustment)
+                               GtkAdjustment *adjustment)
 {
+  GtkTreeViewPrivate *priv = tree_view->priv;
+
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
+  g_return_if_fail (adjustment == NULL || GTK_IS_ADJUSTMENT (adjustment));
+
+  if (adjustment && priv->vadjustment == adjustment)
+    return;
 
-  gtk_tree_view_set_adjustments (tree_view,
-				 tree_view->priv->hadjustment,
-				 adjustment);
+  if (priv->vadjustment != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (priv->vadjustment,
+                                            gtk_tree_view_adjustment_changed,
+                                            tree_view);
+      g_object_unref (priv->vadjustment);
+    }
 
+  if (adjustment == NULL)
+    adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+                                     0.0, 0.0, 0.0);
+
+  g_signal_connect (adjustment, "value-changed",
+                    G_CALLBACK (gtk_tree_view_adjustment_changed), tree_view);
+  priv->vadjustment = g_object_ref_sink (adjustment);
+  /* FIXME: Adjustment should probably be populated here with fresh values, but
+   * internal details are too complicated for me to decipher right now.
+   */
+  gtk_tree_view_adjustment_changed (NULL, tree_view);
   g_object_notify (G_OBJECT (tree_view), "vadjustment");
 }
 
diff --git a/gtk/gtktreeview.h b/gtk/gtktreeview.h
index e8dbd0c..2376304 100644
--- a/gtk/gtktreeview.h
+++ b/gtk/gtktreeview.h
@@ -70,9 +70,6 @@ struct _GtkTreeViewClass
 {
   GtkContainerClass parent_class;
 
-  void     (* set_scroll_adjustments)     (GtkTreeView       *tree_view,
-				           GtkAdjustment     *hadjustment,
-				           GtkAdjustment     *vadjustment);
   void     (* row_activated)              (GtkTreeView       *tree_view,
 				           GtkTreePath       *path,
 					   GtkTreeViewColumn *column);
@@ -147,12 +144,18 @@ GtkTreeModel          *gtk_tree_view_get_model                     (GtkTreeView
 void                   gtk_tree_view_set_model                     (GtkTreeView               *tree_view,
 								    GtkTreeModel              *model);
 GtkTreeSelection      *gtk_tree_view_get_selection                 (GtkTreeView               *tree_view);
+
+#ifndef GTK_DISABLE_DEPRECATED
+
 GtkAdjustment         *gtk_tree_view_get_hadjustment               (GtkTreeView               *tree_view);
 void                   gtk_tree_view_set_hadjustment               (GtkTreeView               *tree_view,
 								    GtkAdjustment             *adjustment);
 GtkAdjustment         *gtk_tree_view_get_vadjustment               (GtkTreeView               *tree_view);
 void                   gtk_tree_view_set_vadjustment               (GtkTreeView               *tree_view,
 								    GtkAdjustment             *adjustment);
+
+#endif
+
 gboolean               gtk_tree_view_get_headers_visible           (GtkTreeView               *tree_view);
 void                   gtk_tree_view_set_headers_visible           (GtkTreeView               *tree_view,
 								    gboolean                   headers_visible);
diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c
index 5988682..4c14a96 100644
--- a/gtk/gtkviewport.c
+++ b/gtk/gtkviewport.c
@@ -29,6 +29,7 @@
 #include "gtkintl.h"
 #include "gtkmarshalers.h"
 #include "gtktypeutils.h"
+#include "gtkscrollable.h"
 #include "gtkprivate.h"
 
 
@@ -81,9 +82,6 @@ static void gtk_viewport_get_property             (GObject         *object,
 						   guint            prop_id,
 						   GValue          *value,
 						   GParamSpec      *pspec);
-static void gtk_viewport_set_scroll_adjustments	  (GtkViewport	    *viewport,
-						   GtkAdjustment    *hadjustment,
-						   GtkAdjustment    *vadjustment);
 static void gtk_viewport_destroy                  (GtkWidget        *widget);
 static void gtk_viewport_realize                  (GtkWidget        *widget);
 static void gtk_viewport_unrealize                (GtkWidget        *widget);
@@ -106,7 +104,8 @@ static void gtk_viewport_get_preferred_height     (GtkWidget        *widget,
 						   gint             *natural_size);
 
 
-G_DEFINE_TYPE (GtkViewport, gtk_viewport, GTK_TYPE_BIN)
+G_DEFINE_TYPE_WITH_CODE (GtkViewport, gtk_viewport, GTK_TYPE_BIN,
+                         G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
 
 static void
 gtk_viewport_class_init (GtkViewportClass *class)
@@ -134,23 +133,13 @@ gtk_viewport_class_init (GtkViewportClass *class)
   
   container_class->add = gtk_viewport_add;
 
-  class->set_scroll_adjustments = gtk_viewport_set_scroll_adjustments;
-
-  g_object_class_install_property (gobject_class,
-                                   PROP_HADJUSTMENT,
-                                   g_param_spec_object ("hadjustment",
-							P_("Horizontal adjustment"),
-							P_("The GtkAdjustment that determines the values of the horizontal position for this viewport"),
-                                                        GTK_TYPE_ADJUSTMENT,
-                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
-  g_object_class_install_property (gobject_class,
-                                   PROP_VADJUSTMENT,
-                                   g_param_spec_object ("vadjustment",
-							P_("Vertical adjustment"),
-							P_("The GtkAdjustment that determines the values of the vertical position for this viewport"),
-                                                        GTK_TYPE_ADJUSTMENT,
-                                                        GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+  /* GtkScrollable implementation */
+  g_object_class_override_property (gobject_class,
+				    PROP_HADJUSTMENT,
+				    "hadjustment");
+  g_object_class_override_property (gobject_class,
+				    PROP_VADJUSTMENT,
+				    "vadjustment");
 
   g_object_class_install_property (gobject_class,
                                    PROP_SHADOW_TYPE,
@@ -161,26 +150,6 @@ gtk_viewport_class_init (GtkViewportClass *class)
 						      GTK_SHADOW_IN,
 						      GTK_PARAM_READWRITE));
 
-  /**
-   * GtkViewport::set-scroll-adjustments
-   * @horizontal: the horizontal #GtkAdjustment
-   * @vertical: the vertical #GtkAdjustment
-   *
-   * Set the scroll adjustments for the viewport. Usually scrolled containers
-   * like #GtkScrolledWindow will emit this signal to connect two instances
-   * of #GtkScrollbar to the scroll directions of the #GtkViewport.
-   */
-  widget_class->set_scroll_adjustments_signal =
-    g_signal_new (I_("set-scroll-adjustments"),
-		  G_OBJECT_CLASS_TYPE (gobject_class),
-		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		  G_STRUCT_OFFSET (GtkViewportClass, set_scroll_adjustments),
-		  NULL, NULL,
-		  _gtk_marshal_VOID__OBJECT_OBJECT,
-		  G_TYPE_NONE, 2,
-		  GTK_TYPE_ADJUSTMENT,
-		  GTK_TYPE_ADJUSTMENT);
-
   g_type_class_add_private (class, sizeof (GtkViewportPrivate));
 }
 
@@ -331,6 +300,8 @@ gtk_viewport_destroy (GtkWidget *widget)
  * Returns the horizontal adjustment of the viewport.
  *
  * Return value: (transfer none): the horizontal adjustment of @viewport.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_hadjustment()
  **/
 GtkAdjustment*
 gtk_viewport_get_hadjustment (GtkViewport *viewport)
@@ -354,6 +325,8 @@ gtk_viewport_get_hadjustment (GtkViewport *viewport)
  * Returns the vertical adjustment of the viewport.
  *
  * Return value: (transfer none): the vertical adjustment of @viewport.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_get_vadjustment()
  **/
 GtkAdjustment*
 gtk_viewport_get_vadjustment (GtkViewport *viewport)
@@ -537,6 +510,8 @@ viewport_set_adjustment (GtkViewport    *viewport,
  * @adjustment: (allow-none): a #GtkAdjustment.
  *
  * Sets the horizontal adjustment of the viewport.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_hadjustment()
  **/
 void
 gtk_viewport_set_hadjustment (GtkViewport   *viewport,
@@ -557,6 +532,8 @@ gtk_viewport_set_hadjustment (GtkViewport   *viewport,
  * @adjustment: (allow-none): a #GtkAdjustment.
  *
  * Sets the vertical adjustment of the viewport.
+ *
+ * Deprecated: 3.0: Use gtk_scrollable_set_vadjustment()
  **/
 void
 gtk_viewport_set_vadjustment (GtkViewport   *viewport,
@@ -571,15 +548,6 @@ gtk_viewport_set_vadjustment (GtkViewport   *viewport,
   g_object_notify (G_OBJECT (viewport), "vadjustment");
 }
 
-static void
-gtk_viewport_set_scroll_adjustments (GtkViewport      *viewport,
-				     GtkAdjustment    *hadjustment,
-				     GtkAdjustment    *vadjustment)
-{
-  gtk_viewport_set_hadjustment (viewport, hadjustment);
-  gtk_viewport_set_vadjustment (viewport, vadjustment);
-}
-
 /** 
  * gtk_viewport_set_shadow_type:
  * @viewport: a #GtkViewport.
diff --git a/gtk/gtkviewport.h b/gtk/gtkviewport.h
index fcbff21..e70e489 100644
--- a/gtk/gtkviewport.h
+++ b/gtk/gtkviewport.h
@@ -62,22 +62,24 @@ struct _GtkViewport
 struct _GtkViewportClass
 {
   GtkBinClass parent_class;
-
-  void	(*set_scroll_adjustments)	(GtkViewport	*viewport,
-					 GtkAdjustment	*hadjustment,
-					 GtkAdjustment	*vadjustment);
 };
 
 
 GType          gtk_viewport_get_type        (void) G_GNUC_CONST;
 GtkWidget*     gtk_viewport_new             (GtkAdjustment *hadjustment,
 					     GtkAdjustment *vadjustment);
+
+#ifndef GTK_DISABLE_DEPRECATED
+
 GtkAdjustment* gtk_viewport_get_hadjustment (GtkViewport   *viewport);
 GtkAdjustment* gtk_viewport_get_vadjustment (GtkViewport   *viewport);
 void           gtk_viewport_set_hadjustment (GtkViewport   *viewport,
 					     GtkAdjustment *adjustment);
 void           gtk_viewport_set_vadjustment (GtkViewport   *viewport,
 					     GtkAdjustment *adjustment);
+
+#endif
+
 void           gtk_viewport_set_shadow_type (GtkViewport   *viewport,
 					     GtkShadowType  type);
 GtkShadowType  gtk_viewport_get_shadow_type (GtkViewport   *viewport);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]