Index: gvc-channel-bar.c
===================================================================
--- gvc-channel-bar.c	(revision 4276)
+++ gvc-channel-bar.c	(working copy)
@@ -394,6 +394,7 @@
                                GdkEventButton *event,
                                GvcChannelBar  *bar)
 {
+        GtkAdjustment *adj;
         gdouble value;
 
         /* HACK: see on_scale_button_press_event() */
@@ -402,14 +403,17 @@
 
         bar->priv->click_lock = FALSE;
 
-        value = gtk_adjustment_get_value (bar->priv->zero_adjustment);
-        gtk_adjustment_set_value (bar->priv->adjustment, value);
+        adj = gtk_range_get_adjustment (GTK_RANGE (widget));
 
+        value = gtk_adjustment_get_value (adj);
+
         /* this means the adjustment moved away from zero and
           therefore we should unmute and set the volume. */
+        if (value > 0)
+                gvc_channel_bar_set_is_muted (bar, FALSE);
+        else
+                gvc_channel_bar_set_is_muted (bar, TRUE);
 
-        gvc_channel_bar_set_is_muted (bar, FALSE);
-
         /* Play a sound! */
         ca_gtk_play_for_widget (GTK_WIDGET (bar), 0,
                                 CA_PROP_EVENT_ID, "audio-volume-change",
@@ -420,32 +424,55 @@
         return FALSE;
 }
 
-static gboolean
-on_scale_scroll_event (GtkWidget      *widget,
-                       GdkEventScroll *event,
-                       GvcChannelBar  *bar)
+gboolean
+gvc_channel_bar_scroll (GvcChannelBar *bar, GdkScrollDirection direction)
 {
+        GtkAdjustment *adj;
         gdouble value;
 
-        value = gtk_adjustment_get_value (bar->priv->adjustment);
+        g_return_val_if_fail (bar != NULL, FALSE);
+        g_return_val_if_fail (GVC_IS_CHANNEL_BAR (bar), FALSE);
 
-        if (event->direction == GDK_SCROLL_UP) {
+        /* FIXME we should handle left/right for horizontal bars */
+        if (direction != GDK_SCROLL_UP && direction != GDK_SCROLL_DOWN)
+                return FALSE;
+
+        adj = gtk_range_get_adjustment (GTK_RANGE (bar->priv->scale));
+        if (adj == bar->priv->zero_adjustment) {
+                if (direction == GDK_SCROLL_UP)
+                        gvc_channel_bar_set_is_muted (bar, FALSE);
+                return TRUE;
+        }
+
+        value = gtk_adjustment_get_value (adj);
+
+        if (direction == GDK_SCROLL_UP) {
                 if (value + ADJUSTMENT_MAX/100.0 > ADJUSTMENT_MAX)
                         value = ADJUSTMENT_MAX;
                 else
                         value = value + ADJUSTMENT_MAX/100.0;
-                gtk_adjustment_set_value (bar->priv->adjustment, value);
-        } else if (event->direction == GDK_SCROLL_DOWN) {
+        } else if (direction == GDK_SCROLL_DOWN) {
                 if (value - ADJUSTMENT_MAX/100.0 < 0)
                         value = 0.0;
                 else
                         value = value - ADJUSTMENT_MAX/100.0;
-                gtk_adjustment_set_value (bar->priv->adjustment, value);
         }
 
+        gvc_channel_bar_set_is_muted (bar, (value == 0.0));
+        adj = gtk_range_get_adjustment (GTK_RANGE (bar->priv->scale));
+        gtk_adjustment_set_value (adj, value);
+
         return TRUE;
 }
 
+static gboolean
+on_scale_scroll_event (GtkWidget      *widget,
+                       GdkEventScroll *event,
+                       GvcChannelBar  *bar)
+{
+        return gvc_channel_bar_scroll (bar, event->direction);
+}
+
 static void
 on_zero_adjustment_value_changed (GtkAdjustment *adjustment,
                                   GvcChannelBar *bar)
Index: gvc-channel-bar.h
===================================================================
--- gvc-channel-bar.h	(revision 4276)
+++ gvc-channel-bar.h	(working copy)
@@ -76,6 +76,9 @@
 void                gvc_channel_bar_set_is_amplified    (GvcChannelBar *bar,
                                                          gboolean amplified);
 
+gboolean            gvc_channel_bar_scroll              (GvcChannelBar *bar,
+                                                         GdkScrollDirection direction);
+
 G_END_DECLS
 
 #endif /* __GVC_CHANNEL_BAR_H */
Index: gvc-stream-status-icon.c
===================================================================
--- gvc-stream-status-icon.c	(revision 4276)
+++ gvc-stream-status-icon.c	(working copy)
@@ -267,37 +267,7 @@
                              GdkEventScroll      *event,
                              GvcStreamStatusIcon *icon)
 {
-        GtkAdjustment *adj;
-
-        adj = GTK_ADJUSTMENT (gvc_channel_bar_get_adjustment (GVC_CHANNEL_BAR (icon->priv->bar)));
-
-        switch (event->direction) {
-        case GDK_SCROLL_UP:
-        case GDK_SCROLL_DOWN: {
-                gdouble volume;
-
-                volume = gtk_adjustment_get_value (adj);
-
-                if (event->direction == GDK_SCROLL_UP) {
-                        volume += adj->step_increment;
-                        if (volume > adj->upper) {
-                                volume = adj->upper;
-                        }
-                } else {
-                        volume -= adj->step_increment;
-                        if (volume < adj->lower) {
-                                volume = adj->lower;
-                        }
-                }
-
-                gtk_adjustment_set_value (adj, volume);
-                return TRUE;
-        }
-        default:
-                break;
-        }
-
-        return FALSE;
+        return gvc_channel_bar_scroll (GVC_CHANNEL_BAR (icon->priv->bar), event->direction);
 }
 
 static void
