Index: gtk/gtkscalebutton.c
===================================================================
--- gtk/gtkscalebutton.c	(revision 20691)
+++ gtk/gtkscalebutton.c	(working copy)
@@ -46,6 +46,7 @@
 #include "gtkmain.h"
 #include "gtkintl.h"
 #include "gtkbindings.h"
+#include "gtkhscale.h"
 #include "gtkvscale.h"
 #include "gtkframe.h"
 #include "gtkvbox.h"
@@ -73,6 +74,7 @@ enum
 {
   PROP_0,
 
+  PROP_ORIENTATION,
   PROP_VALUE,
   PROP_SIZE,
   PROP_ADJUSTMENT,
@@ -88,6 +90,7 @@ struct _GtkScaleButtonPrivate
   GtkWidget *image;
 
   GtkIconSize size;
+  GtkOrientation orientation;
 
   guint click_id;
   gint click_timeout;
@@ -96,8 +99,13 @@ struct _GtkScaleButtonPrivate
   guint32 pop_time;
 
   gchar **icon_list;
+
+  GtkAdjustment *adjustment; /* needed because it must be settable in init() */
 };
 
+static GObject* gtk_scale_button_constructor    (GType                  type,
+                                                 guint                  n_construct_properties,
+                                                 GObjectConstructParam *construct_params);
 static void	gtk_scale_button_dispose	(GObject             *object);
 static void     gtk_scale_button_finalize       (GObject             *object);
 static void	gtk_scale_button_set_property	(GObject             *object,
@@ -143,10 +151,10 @@ static void gtk_scale_button_update_icon
 static void gtk_scale_button_scale_value_changed(GtkRange            *range);
 
 /* see below for scale definitions */
-static GtkWidget *gtk_scale_button_scale_new	(GtkScaleButton      *button,
-						 gdouble              min,
-						 gdouble              max,
-						 gdouble              step);
+static GtkWidget *gtk_scale_button_scale_new    (GtkScaleButton      *button,
+                                                 gdouble              min,
+                                                 gdouble              max,
+                                                 gdouble              step);
 
 static guint signals[LAST_SIGNAL] = { 0, };
 
@@ -161,6 +169,7 @@ gtk_scale_button_class_init (GtkScaleBut
 
   g_type_class_add_private (klass, sizeof (GtkScaleButtonPrivate));
 
+  gobject_class->constructor = gtk_scale_button_constructor;
   gobject_class->finalize = gtk_scale_button_finalize;
   gobject_class->dispose = gtk_scale_button_dispose;
   gobject_class->set_property = gtk_scale_button_set_property;
@@ -172,6 +181,16 @@ gtk_scale_button_class_init (GtkScaleBut
   widget_class->screen_changed = gtk_scale_button_screen_changed;
 
   g_object_class_install_property (gobject_class,
+				   PROP_ORIENTATION,
+				   g_param_spec_enum ("orientation",
+                                                      P_("Orientation"),
+                                                      P_("The orientation of the scale"),
+                                                      GTK_TYPE_ORIENTATION,
+                                                      GTK_ORIENTATION_VERTICAL,
+                                                      GTK_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (gobject_class,
 				   PROP_VALUE,
 				   g_param_spec_double ("value",
 							P_("Value"),
@@ -308,7 +327,6 @@ gtk_scale_button_class_init (GtkScaleBut
 static void
 gtk_scale_button_init (GtkScaleButton *button)
 {
-  GtkWidget *frame, *box;
   GtkScaleButtonPrivate *priv;
 
   button->priv = priv = GET_PRIVATE (button);
@@ -337,6 +355,42 @@ gtk_scale_button_init (GtkScaleButton *b
 		    G_CALLBACK (cb_dock_grab_broken_event), button);
   gtk_window_set_decorated (GTK_WINDOW (priv->dock), FALSE);
 
+  /* + */
+  button->plus_button = gtk_button_new_with_label ("+");
+  gtk_button_set_relief (GTK_BUTTON (button->plus_button), GTK_RELIEF_NONE);
+  g_signal_connect (button->plus_button, "button-press-event",
+		    G_CALLBACK (cb_button_press), button);
+  g_signal_connect (button->plus_button, "button-release-event",
+		    G_CALLBACK (cb_button_release), button);
+
+  /* - */
+  button->minus_button = gtk_button_new_with_label ("-");
+  gtk_button_set_relief (GTK_BUTTON (button->minus_button), GTK_RELIEF_NONE);
+  g_signal_connect (button->minus_button, "button-press-event",
+		   G_CALLBACK (cb_button_press), button);
+  g_signal_connect (button->minus_button, "button-release-event",
+		    G_CALLBACK (cb_button_release), button);
+
+  priv->adjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 100.0, 2, 20, 0));
+  g_object_ref_sink (priv->adjustment);
+}
+
+static GObject *
+gtk_scale_button_constructor (GType                  type,
+                              guint                  n_construct_properties,
+                              GObjectConstructParam *construct_params)
+{
+  GObject *object;
+  GtkScaleButton *button;
+  GtkWidget *frame, *box;
+  GtkScaleButtonPrivate *priv;
+
+  object = G_OBJECT_CLASS (gtk_scale_button_parent_class)->constructor (type, n_construct_properties, construct_params);
+
+  button = GTK_SCALE_BUTTON (object);
+
+  priv = button->priv;
+
   /* frame */
   frame = gtk_frame_new (NULL);
   gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
@@ -345,35 +399,33 @@ gtk_scale_button_init (GtkScaleButton *b
   gtk_container_add (GTK_CONTAINER (frame), box);
 
   /* + */
-  button->plus_button = gtk_button_new_with_label ("+");
-  gtk_button_set_relief (GTK_BUTTON (button->plus_button), GTK_RELIEF_NONE);
-  g_signal_connect (button->plus_button, "button-press-event",
-		    G_CALLBACK (cb_button_press), button);
-  g_signal_connect (button->plus_button, "button-release-event",
-		    G_CALLBACK (cb_button_release), button);
   gtk_box_pack_start (GTK_BOX (box), button->plus_button, TRUE, FALSE, 0);
 
   /* scale */
   priv->scale = gtk_scale_button_scale_new (button, 0., 100., 2.);
-  gtk_widget_set_size_request (priv->scale, -1, SCALE_SIZE);
+  if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+    {
+      gtk_widget_set_size_request (priv->scale, -1, SCALE_SIZE);
+      gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE);
+    }
+  else
+    {
+      gtk_widget_set_size_request (priv->scale, SCALE_SIZE, -1);
+    }
+
   gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
-  gtk_range_set_inverted (GTK_RANGE (priv->scale), TRUE);
   gtk_box_pack_start (GTK_BOX (box), priv->scale, TRUE, FALSE, 0);
   g_signal_connect (priv->scale, "grab-notify",
 		    G_CALLBACK (cb_scale_grab_notify), button);
 
   /* - */
-  button->minus_button = gtk_button_new_with_label ("-");
-  gtk_button_set_relief (GTK_BUTTON (button->minus_button), GTK_RELIEF_NONE);
-  g_signal_connect (button->minus_button, "button-press-event",
-		   G_CALLBACK (cb_button_press), button);
-  g_signal_connect (button->minus_button, "button-release-event",
-		    G_CALLBACK (cb_button_release), button);
   gtk_box_pack_start (GTK_BOX (box), button->minus_button, TRUE, FALSE, 0);
 
   /* set button text and size */
   priv->size = GTK_ICON_SIZE_SMALL_TOOLBAR;
   gtk_scale_button_update_icon (button);
+
+  return object;
 }
 
 static void
@@ -388,6 +440,9 @@ gtk_scale_button_set_property (GObject  
 
   switch (prop_id)
     {
+    case PROP_ORIENTATION:
+      button->priv->orientation = g_value_get_enum (value);
+      break;
     case PROP_VALUE:
       gtk_scale_button_set_value (button, g_value_get_double (value));
       break;
@@ -429,6 +484,9 @@ gtk_scale_button_get_property (GObject  
 
   switch (prop_id)
     {
+    case PROP_ORIENTATION:
+      g_value_set_enum (value, priv->orientation);
+      break;
     case PROP_VALUE:
       g_value_set_double (value, gtk_scale_button_get_value (button));
       break;
@@ -540,7 +598,7 @@ gtk_scale_button_get_value (GtkScaleButt
 
   priv = button->priv;
 
-  return gtk_range_get_value (GTK_RANGE (priv->scale));
+  return gtk_adjustment_get_value (priv->adjustment);
 }
 
 /**
@@ -611,14 +669,9 @@ gtk_scale_button_set_icons (GtkScaleButt
 GtkAdjustment*
 gtk_scale_button_get_adjustment	(GtkScaleButton *button)
 {
-  GtkRange *range;
-
   g_return_val_if_fail (GTK_IS_SCALE_BUTTON (button), NULL);
 
-  range = GTK_RANGE (button->priv->scale);
-  g_return_val_if_fail (range != NULL, NULL);
-
-  return gtk_range_get_adjustment (range);
+  return button->priv->adjustment;
 }
 
 /**
@@ -639,8 +692,12 @@ gtk_scale_button_set_adjustment	(GtkScal
   g_return_if_fail (GTK_IS_SCALE_BUTTON (button));
   g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment));
 
-  gtk_range_set_adjustment (GTK_RANGE (button->priv->scale),
-			    adjustment);
+  if (button->priv->adjustment)
+    g_object_unref (button->priv->adjustment);
+  button->priv->adjustment = g_object_ref_sink (adjustment);
+
+  if (button->priv->scale)
+    gtk_range_set_adjustment (GTK_RANGE (button->priv->scale), adjustment);
 
   g_object_notify (G_OBJECT (button), "adjustment");
 }
@@ -660,7 +717,7 @@ gtk_scale_button_scroll (GtkWidget      
 
   button = GTK_SCALE_BUTTON (widget);
   priv = button->priv;
-  adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+  adj = priv->adjustment;
 
   if (event->type != GDK_SCROLL)
     return FALSE;
@@ -718,14 +775,14 @@ gtk_scale_popup (GtkWidget *widget,
   GtkScaleButton *button;
   GtkScaleButtonPrivate *priv;
   GtkAdjustment *adj;
-  gint x, y, m, dx, dy, sx, sy, ystartoff;
+  gint x, y, m, dx, dy, sx, sy, startoff;
   gdouble v;
   GdkDisplay *display;
   GdkScreen *screen;
 
   button = GTK_SCALE_BUTTON (widget);
   priv = button->priv;
-  adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+  adj = priv->adjustment;
 
   display = gtk_widget_get_display (widget);
   screen = gtk_widget_get_screen (widget);
@@ -736,23 +793,49 @@ gtk_scale_popup (GtkWidget *widget,
   gdk_window_get_origin (widget->window, &x, &y);
   x += widget->allocation.x;
   y += widget->allocation.y;
-  gtk_window_move (GTK_WINDOW (priv->dock), x, y - (SCALE_SIZE / 2));
+
+  if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+    gtk_window_move (GTK_WINDOW (priv->dock), x, y - (SCALE_SIZE / 2));
+  else
+    gtk_window_move (GTK_WINDOW (priv->dock), x - (SCALE_SIZE / 2), y);
+
   gtk_widget_show_all (priv->dock);
+
   gdk_window_get_origin (priv->dock->window, &dx, &dy);
+  dx += priv->dock->allocation.x;
   dy += priv->dock->allocation.y;
+
   gdk_window_get_origin (priv->scale->window, &sx, &sy);
+  sx += priv->scale->allocation.x;
   sy += priv->scale->allocation.y;
-  ystartoff = sy - dy;
+
   priv->timeout = TRUE;
 
   /* position (needs widget to be shown already) */
   v = gtk_scale_button_get_value (button) / (adj->upper - adj->lower);
-  x += (widget->allocation.width - priv->dock->allocation.width) / 2;
-  y -= ystartoff;
-  y -= GTK_RANGE (priv->scale)->min_slider_size / 2;
-  m = priv->scale->allocation.height -
-      GTK_RANGE (priv->scale)->min_slider_size;
-  y -= m * (1.0 - v);
+
+  if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+    {
+      startoff = sy - dy;
+
+      x += (widget->allocation.width - priv->dock->allocation.width) / 2;
+      y -= startoff;
+      y -= GTK_RANGE (priv->scale)->min_slider_size / 2;
+      m = priv->scale->allocation.height -
+          GTK_RANGE (priv->scale)->min_slider_size;
+      y -= m * (1.0 - v);
+    }
+  else
+    {
+      startoff = sx - dx;
+
+      x -= startoff;
+      y += (widget->allocation.height - priv->dock->allocation.height) / 2;
+      x -= GTK_RANGE (priv->scale)->min_slider_size / 2;
+      m = priv->scale->allocation.width -
+          GTK_RANGE (priv->scale)->min_slider_size;
+      x -= m * v;
+    }
 
   /* Make sure the dock stays inside the monitor */
   if (event->type == GDK_BUTTON_PRESS)
@@ -768,7 +851,11 @@ gtk_scale_popup (GtkWidget *widget,
 						 button_event->y_root);
       gdk_screen_get_monitor_geometry (screen, monitor, &rect);
 
-      y += button_event->y;
+      if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+        y += button_event->y;
+      else
+        x += button_event->x;
+
       if (y < rect.y)
 	y = rect.y;
       else if (y + d->allocation.height > rect.height + rect.y)
@@ -820,11 +907,23 @@ gtk_scale_popup (GtkWidget *widget,
       /* position: the X position isn't relevant, halfway will work just fine.
        * The vertical position should be *exactly* in the middle of the slider
        * of the scale; if we don't do that correctly, it'll move from its current
-       * position, which means a position change on-click, which is bad. */
-      e->x = priv->scale->allocation.width / 2;
-      m = priv->scale->allocation.height -
-	GTK_RANGE (priv->scale)->min_slider_size;
-      e->y = ((1.0 - v) * m) + GTK_RANGE (priv->scale)->min_slider_size / 2;
+       * position, which means a position change on-click, which is bad.
+       */
+      if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+        {
+          e->x = priv->scale->allocation.width / 2;
+          m = priv->scale->allocation.height -
+              GTK_RANGE (priv->scale)->min_slider_size;
+          e->y = ((1.0 - v) * m) + GTK_RANGE (priv->scale)->min_slider_size / 2;
+        }
+      else
+        {
+          e->y = priv->scale->allocation.height / 2;
+          m = priv->scale->allocation.width -
+              GTK_RANGE (priv->scale)->min_slider_size;
+          e->x = (v * m) + GTK_RANGE (priv->scale)->min_slider_size / 2;
+        }
+
       gtk_widget_event (priv->scale, (GdkEvent *) e);
       e->window = button_event->window;
       gdk_event_free ((GdkEvent *) e);
@@ -910,7 +1009,7 @@ cb_button_timeout (gpointer user_data)
   if (priv->click_id == 0)
     return FALSE;
 
-  adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+  adj = priv->adjustment;
 
   val = gtk_scale_button_get_value (button);
   val += priv->direction;
@@ -946,7 +1045,7 @@ cb_button_press (GtkWidget      *widget,
 
   button = GTK_SCALE_BUTTON (user_data);
   priv = button->priv;
-  adj = gtk_range_get_adjustment (GTK_RANGE (priv->scale));
+  adj = priv->adjustment;
 
   if (priv->click_id != 0)
     g_source_remove (priv->click_id);
@@ -1109,30 +1208,54 @@ cb_scale_grab_notify (GtkWidget *widget,
  * Scale stuff.
  */
 
-#define GTK_TYPE_SCALE_BUTTON_SCALE \
-  (gtk_scale_button_scale_get_type ())
-#define GTK_SCALE_BUTTON_SCALE(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_BUTTON_SCALE, \
-			       GtkScaleButtonScale))
+#define GTK_TYPE_SCALE_BUTTON_VSCALE    (gtk_scale_button_vscale_get_type ())
+#define GTK_SCALE_BUTTON_VSCALE(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_BUTTON_VSCALE, GtkScaleButtonVScale))
+#define GTK_IS_SCALE_BUTTON_VSCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SCALE_BUTTON_VSCALE))
+
+typedef struct _GtkScaleButtonVScale {
+  GtkVScale parent;
+  GtkScaleButton *button;
+} GtkScaleButtonVScale;
 
-typedef struct _GtkScaleButtonScaleClass {
+typedef struct _GtkScaleButtonVScaleClass {
   GtkVScaleClass parent_class;
-} GtkScaleButtonScaleClass;
+} GtkScaleButtonVScaleClass;
 
-typedef struct _GtkScaleButtonScale {
+#define GTK_TYPE_SCALE_BUTTON_HSCALE    (gtk_scale_button_hscale_get_type ())
+#define GTK_SCALE_BUTTON_HSCALE(obj)    (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SCALE_BUTTON_HSCALE, GtkScaleButtonHScale))
+#define GTK_IS_SCALE_BUTTON_HSCALE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SCALE_BUTTON_HSCALE))
+
+typedef struct _GtkScaleButtonHScale {
   GtkVScale parent;
   GtkScaleButton *button;
-} GtkScaleButtonScale;
+} GtkScaleButtonHScale;
+
+typedef struct _GtkScaleButtonHScaleClass {
+  GtkVScaleClass parent_class;
+} GtkScaleButtonHScaleClass;
 
-static gboolean gtk_scale_button_scale_press   (GtkWidget      *widget,
+static gboolean	gtk_scale_button_scale_press   (GtkWidget      *widget,
                                                 GdkEventButton *event);
 static gboolean gtk_scale_button_scale_release (GtkWidget      *widget,
                                                 GdkEventButton *event);
 
-G_DEFINE_TYPE (GtkScaleButtonScale, gtk_scale_button_scale, GTK_TYPE_VSCALE)
+G_DEFINE_TYPE (GtkScaleButtonVScale, gtk_scale_button_vscale, GTK_TYPE_VSCALE)
+
+G_DEFINE_TYPE (GtkScaleButtonHScale, gtk_scale_button_hscale, GTK_TYPE_HSCALE)
+
+static void
+gtk_scale_button_vscale_class_init (GtkScaleButtonVScaleClass *klass)
+{
+  GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
+  GtkRangeClass *gtkrange_class = GTK_RANGE_CLASS (klass);
+
+  gtkwidget_class->button_press_event = gtk_scale_button_scale_press;
+  gtkwidget_class->button_release_event = gtk_scale_button_scale_release;
+  gtkrange_class->value_changed = gtk_scale_button_scale_value_changed;
+}
 
 static void
-gtk_scale_button_scale_class_init (GtkScaleButtonScaleClass *klass)
+gtk_scale_button_hscale_class_init (GtkScaleButtonHScaleClass *klass)
 {
   GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass);
   GtkRangeClass *gtkrange_class = GTK_RANGE_CLASS (klass);
@@ -1143,24 +1266,32 @@ gtk_scale_button_scale_class_init (GtkSc
 }
 
 static void
-gtk_scale_button_scale_init (GtkScaleButtonScale *scale)
+gtk_scale_button_vscale_init (GtkScaleButtonVScale *scale)
+{
+}
+
+static void
+gtk_scale_button_hscale_init (GtkScaleButtonHScale *scale)
 {
 }
 
 static GtkWidget *
 gtk_scale_button_scale_new (GtkScaleButton *button,
-			    gdouble         min,
-			    gdouble         max,
-			    gdouble         step)
+                            gdouble         min,
+                            gdouble         max,
+                            gdouble         step)
 {
-  GtkScaleButtonScale *scale;
-  GtkScaleButtonPrivate *priv;
-  GtkObject *adj;
+  GtkScaleButtonPrivate *priv = button->priv;
+  GtkScaleButtonVScale *scale;
+
+  if (priv->orientation == GTK_ORIENTATION_VERTICAL)
+    scale = g_object_new (GTK_TYPE_SCALE_BUTTON_VSCALE, NULL);
+  else
+    scale = g_object_new (GTK_TYPE_SCALE_BUTTON_HSCALE, NULL);
+
+  gtk_range_set_adjustment (GTK_RANGE (scale),
+                            GTK_ADJUSTMENT (priv->adjustment));
 
-  priv = button->priv;
-  scale = g_object_new (GTK_TYPE_SCALE_BUTTON_SCALE, NULL);
-  adj = gtk_adjustment_new (min, min, max, step, 10 * step, 0);
-  gtk_range_set_adjustment (GTK_RANGE (scale), GTK_ADJUSTMENT (adj));
   scale->button = button;
 
   return GTK_WIDGET (scale);
@@ -1170,46 +1301,59 @@ static gboolean
 gtk_scale_button_scale_press (GtkWidget      *widget,
 			      GdkEventButton *event)
 {
-  GtkScaleButtonScale *scale;
   GtkScaleButtonPrivate *priv;
+  GtkWidgetClass *widget_class;
 
-  scale = GTK_SCALE_BUTTON_SCALE (widget);
-  priv = scale->button->priv;
+  if (GTK_IS_SCALE_BUTTON_VSCALE (widget))
+    {
+      priv = GTK_SCALE_BUTTON_VSCALE (widget)->button->priv;
+      widget_class = GTK_WIDGET_CLASS (gtk_scale_button_vscale_parent_class);
+    }
+  else
+    {
+      priv = GTK_SCALE_BUTTON_HSCALE (widget)->button->priv;
+      widget_class = GTK_WIDGET_CLASS (gtk_scale_button_hscale_parent_class);
+    }
 
   /* the scale will grab input; if we have input grabbed, all goes
    * horribly wrong, so let's not do that. */
   gtk_grab_remove (priv->dock);
 
-  return GTK_WIDGET_CLASS (gtk_scale_button_scale_parent_class)->button_press_event (widget, event);
+  return widget_class->button_press_event (widget, event);
 }
 
 static gboolean
 gtk_scale_button_scale_release (GtkWidget      *widget,
 				GdkEventButton *event)
 {
-  GtkScaleButtonScale *scale;
-  GtkScaleButtonPrivate *priv;
+  GtkScaleButton *button;
   GtkWidgetClass *widget_class;
   gboolean res;
 
-  scale = GTK_SCALE_BUTTON_SCALE (widget);
-  priv = scale->button->priv;
-
-  widget_class = GTK_WIDGET_CLASS (gtk_scale_button_scale_parent_class);
+  if (GTK_IS_SCALE_BUTTON_VSCALE (widget))
+    {
+      button = GTK_SCALE_BUTTON_VSCALE (widget)->button;
+      widget_class = GTK_WIDGET_CLASS (gtk_scale_button_vscale_parent_class);
+    }
+  else
+    {
+      button = GTK_SCALE_BUTTON_HSCALE (widget)->button;
+      widget_class = GTK_WIDGET_CLASS (gtk_scale_button_hscale_parent_class);
+    }
 
-  if (priv->timeout)
+  if (button->priv->timeout)
     {
       /* if we did a quick click, leave the window open; else, hide it */
-      if (event->time > priv->pop_time + priv->click_timeout)
+      if (event->time > button->priv->pop_time + button->priv->click_timeout)
         {
 
-	  gtk_scale_button_release_grab (scale->button, event);
+	  gtk_scale_button_release_grab (button, event);
 	  widget_class->button_release_event (widget, event);
 
 	  return TRUE;
 	}
 
-      priv->timeout = FALSE;
+      button->priv->timeout = FALSE;
     }
 
   res = widget_class->button_release_event (widget, event);
@@ -1218,8 +1362,9 @@ gtk_scale_button_scale_release (GtkWidge
    * it back so we can catch out-of-scale clicks and hide the popup,
    * so I basically want a g_signal_connect_after_always(), but I can't
    * find that, so we do this complex 'first-call-parent-then-do-actual-
-   * action' thingy... */
-  gtk_grab_add (priv->dock);
+   * action' thingy...
+   */
+  gtk_grab_add (button->priv->dock);
 
   return res;
 }
@@ -1256,7 +1401,7 @@ gtk_scale_button_update_icon (GtkScaleBu
     }
 
   range = GTK_RANGE (priv->scale);
-  adj = gtk_range_get_adjustment (range);
+  adj = priv->adjustment;
   value = gtk_scale_button_get_value (button);
 
   /* The 2-icons special case */
@@ -1303,10 +1448,14 @@ gtk_scale_button_update_icon (GtkScaleBu
 static void
 gtk_scale_button_scale_value_changed (GtkRange *range)
 {
-  GtkScaleButtonScale *scale = GTK_SCALE_BUTTON_SCALE (range);
-  GtkScaleButton *button = scale->button;
+  GtkScaleButton *button;
   gdouble value;
 
+  if (GTK_IS_SCALE_BUTTON_VSCALE (range))
+    button = GTK_SCALE_BUTTON_VSCALE (range)->button;
+  else
+    button = GTK_SCALE_BUTTON_HSCALE (range)->button;
+
   value = gtk_range_get_value (range);
 
   gtk_scale_button_update_icon (button);
