[Xfce4-commits] <xfce4-mixer:gber/improvements> Keep the sound card and controls in sync between the mixer and xfconf

Guido Berhoerster noreply at xfce.org
Fri Sep 21 17:18:20 CEST 2012


Updating branch refs/heads/gber/improvements
         to e44805b64256bf4c62820c30576e3e1953ffc35d (commit)
       from 0e3a152d919a492a84972dab0ab82ca89ba085ea (commit)

commit e44805b64256bf4c62820c30576e3e1953ffc35d
Author: Guido Berhoerster <guido+xfce at berhoerster.name>
Date:   Fri Sep 21 12:00:36 2012 +0200

    Keep the sound card and controls in sync between the mixer and xfconf
    
    Also apply changes in the controls dialog instantly to the mixer window.

 NEWS                                     |    1 +
 configure.in.in                          |    1 +
 libxfce4mixer/Makefile.am                |    2 +
 libxfce4mixer/libxfce4mixer.c            |   19 ++
 libxfce4mixer/libxfce4mixer.h            |    5 +
 libxfce4mixer/xfce-mixer-preferences.c   |  308 ++++++++++++++----------------
 libxfce4mixer/xfce-mixer-preferences.h   |   12 +-
 xfce4-mixer/xfce-mixer-controls-dialog.c |  181 ++++++++++--------
 xfce4-mixer/xfce-mixer-controls-dialog.h |    6 +-
 xfce4-mixer/xfce-mixer-window.c          |  189 ++++++++++++++-----
 xfce4-mixer/xfce-mixer.c                 |   24 ++-
 11 files changed, 443 insertions(+), 305 deletions(-)

diff --git a/NEWS b/NEWS
index 59ff72e..f2e2825 100644
--- a/NEWS
+++ b/NEWS
@@ -25,6 +25,7 @@
 - Add global keyboard shortcuts for raising and lowering the volume as well as
   muting (bug #5314).
 - Set the main window to normal rather than dialog type (bug #7623).
+- Keep the sound card and controls in sync between the mixer and xfconf.
 
 
 4.8.0
diff --git a/configure.in.in b/configure.in.in
index d0175e3..cbefa48 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -91,6 +91,7 @@ dnl *** Check for required packages ***
 dnl ***********************************
 XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.24.0])
 XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.24.0])
+XDT_CHECK_PACKAGE([DBUS_GLIB], [dbus-glib-1], [0.84])
 XDT_CHECK_PACKAGE([GST_PLUGINS_BASE], [gstreamer-plugins-base-0.10], [0.10.23])
 XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.20.0])
 XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.10.0])
diff --git a/libxfce4mixer/Makefile.am b/libxfce4mixer/Makefile.am
index 399bb2d..8f44cd4 100644
--- a/libxfce4mixer/Makefile.am
+++ b/libxfce4mixer/Makefile.am
@@ -30,6 +30,7 @@ libxfce4mixer_la_CFLAGS = 						\
 	$(LIBXFCE4UTIL_CFLAGS)						\
 	$(LIBXFCE4UI_CFLAGS)						\
 	$(XFCONF_CFLAGS)						\
+	$(DBUS_GLIB_CFLAGS)						\
 	$(GST_PLUGINS_BASE_CFLAGS)
 
 libxfce4mixer_la_LDFLAGS =						\
@@ -42,6 +43,7 @@ libxfce4mixer_la_LIBADD =						\
 	$(LIBXFCE4UTIL_LIBS)						\
 	$(LIBXFCE4UI_LIBS)						\
 	$(XFCONF_LIBS)							\
+	$(DBUS_GLIB_LIBS)						\
 	$(GST_PLUGINS_BASE_LIBS)					\
 	-lgstaudio-0.10							\
 	-lgstinterfaces-0.10
diff --git a/libxfce4mixer/libxfce4mixer.c b/libxfce4mixer/libxfce4mixer.c
index b25ecc5..7bb9293 100644
--- a/libxfce4mixer/libxfce4mixer.c
+++ b/libxfce4mixer/libxfce4mixer.c
@@ -25,6 +25,8 @@
 
 #include <glib.h>
 
+#include <dbus/dbus-glib.h>
+
 #include <gst/audio/mixerutils.h>
 #include <gst/interfaces/mixer.h>
 
@@ -350,3 +352,20 @@ xfce_mixer_utf8_cmp (const gchar *s1, const gchar *s2)
   return g_utf8_collate (s1, s2);
 }
 
+
+
+GType
+xfce_mixer_value_array_get_type (void)
+{
+  static volatile gsize type__volatile = 0;
+  GType                 type;
+
+  if (g_once_init_enter (&type__volatile))
+    {
+      type = dbus_g_type_get_collection ("GPtrArray", G_TYPE_VALUE);
+      g_once_init_leave (&type__volatile, type);
+    }
+
+  return type__volatile;
+}
+
diff --git a/libxfce4mixer/libxfce4mixer.h b/libxfce4mixer/libxfce4mixer.h
index 41f5816..187db3f 100644
--- a/libxfce4mixer/libxfce4mixer.h
+++ b/libxfce4mixer/libxfce4mixer.h
@@ -24,6 +24,8 @@
 
 #include <glib.h>
 
+#include <dbus/dbus-glib.h>
+
 #include <gst/interfaces/mixer.h>
 
 #include "xfce-mixer-preferences.h"
@@ -31,6 +33,8 @@
 #include "xfce-mixer-track-combo.h"
 #include "xfce-mixer-track-type.h"
 
+#define XFCE_MIXER_TYPE_VALUE_ARRAY (xfce_mixer_value_array_get_type ())
+
 G_BEGIN_DECLS;
 
 void           xfce_mixer_init                   (void);
@@ -52,6 +56,7 @@ gint           xfce_mixer_get_max_volume         (gint          *volumes,
                                                   gint           num_channels);
 int            xfce_mixer_utf8_cmp               (const gchar   *s1,
                                                   const gchar   *s2);
+GType          xfce_mixer_value_array_get_type   (void);
 
 G_END_DECLS;
 
diff --git a/libxfce4mixer/xfce-mixer-preferences.c b/libxfce4mixer/xfce-mixer-preferences.c
index 04aef50..2cb7edb 100644
--- a/libxfce4mixer/xfce-mixer-preferences.c
+++ b/libxfce4mixer/xfce-mixer-preferences.c
@@ -1,6 +1,7 @@
 /* vi:set expandtab sw=2 sts=2: */
 /*-
  * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012 Guido Berhoerster <guido+xfce at berhoerster.name>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,13 +32,13 @@
 #include "xfce-mixer-preferences.h"
 
 
-
 enum
 {
   PROP_0,
   PROP_WINDOW_WIDTH,
   PROP_WINDOW_HEIGHT,
   PROP_SOUND_CARD,
+  PROP_CONTROLS,
   N_PROPERTIES,
 };
 
@@ -54,8 +55,6 @@ static void   xfce_mixer_preferences_set_property      (GObject
                                                         guint                      prop_id,
                                                         const GValue              *value,
                                                         GParamSpec                *pspec);
-static void   xfce_mixer_preferences_load              (XfceMixerPreferences      *preferences);
-static void   xfce_mixer_preferences_store             (XfceMixerPreferences      *preferences);
 
 
 
@@ -69,9 +68,15 @@ struct _XfceMixerPreferences
   GObject        __parent__;
 
   XfconfChannel *channel;
-  GHashTable    *controls;
 
-  GValue         values[N_PROPERTIES];
+  gint           window_width;
+  gint           window_height;
+
+  gchar         *sound_card;
+
+  GPtrArray     *controls;
+
+  gulong         sound_cards_property_bind_id;
 };
 
 
@@ -145,6 +150,14 @@ xfce_mixer_preferences_class_init (XfceMixerPreferencesClass *klass)
                                                         "sound-card",
                                                         NULL,
                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+  g_object_class_install_property (gobject_class, 
+                                   PROP_CONTROLS,
+                                   g_param_spec_boxed ("controls",
+                                                       "controls",
+                                                       "controls",
+                                                       XFCE_MIXER_TYPE_VALUE_ARRAY,
+                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
 
 
@@ -152,14 +165,20 @@ xfce_mixer_preferences_class_init (XfceMixerPreferencesClass *klass)
 static void
 xfce_mixer_preferences_init (XfceMixerPreferences *preferences)
 {
-    preferences->channel = xfconf_channel_get ("xfce4-mixer");
-    preferences->controls = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_strfreev);
+  preferences->channel = xfconf_channel_get ("xfce4-mixer");
 
-    xfconf_g_property_bind (preferences->channel, "/window-width", G_TYPE_INT, G_OBJECT (preferences), "window-width");
-    xfconf_g_property_bind (preferences->channel, "/window-height", G_TYPE_INT, G_OBJECT (preferences), "window-height");
-    xfconf_g_property_bind (preferences->channel, "/sound-card", G_TYPE_STRING, G_OBJECT (preferences), "sound-card");
+  preferences->window_width = 1;
+  preferences->window_height = 1;
 
-    xfce_mixer_preferences_load (preferences);
+  preferences->sound_card = NULL;
+
+  preferences->controls = g_ptr_array_new ();
+
+  preferences->sound_cards_property_bind_id = 0UL;
+
+  xfconf_g_property_bind (preferences->channel, "/window-width", G_TYPE_INT, G_OBJECT (preferences), "window-width");
+  xfconf_g_property_bind (preferences->channel, "/window-height", G_TYPE_INT, G_OBJECT (preferences), "window-height");
+  xfconf_g_property_bind (preferences->channel, "/sound-card", G_TYPE_STRING, G_OBJECT (preferences), "sound-card");
 }
 
 
@@ -169,7 +188,17 @@ xfce_mixer_preferences_finalize (GObject *object)
 {
   XfceMixerPreferences *preferences = XFCE_MIXER_PREFERENCES (object);
 
-  g_hash_table_unref (preferences->controls);
+  if (preferences->sound_card != NULL)
+    {
+      g_free (preferences->sound_card);
+      preferences->sound_card = NULL;
+    }
+
+  if (preferences->controls != NULL)
+    {
+      xfconf_array_free (preferences->controls);
+      preferences->controls = NULL;
+    }
 
   (*G_OBJECT_CLASS (xfce_mixer_preferences_parent_class)->finalize) (object);
 }
@@ -183,14 +212,25 @@ xfce_mixer_preferences_get_property (GObject    *object,
                                      GParamSpec *pspec)
 {
   XfceMixerPreferences *preferences = XFCE_MIXER_PREFERENCES (object);
-  GValue               *src;
 
-  src = preferences->values + prop_id;
-
-  if (G_LIKELY (G_IS_VALUE (src)))
-    g_value_copy (src, value);
-  else
-    g_param_value_set_default (pspec, value);
+  switch (prop_id)
+    {
+    case PROP_WINDOW_WIDTH:
+      g_value_set_int (value, preferences->window_width);
+      break;
+    case PROP_WINDOW_HEIGHT:
+      g_value_set_int (value, preferences->window_height);
+      break;
+    case PROP_SOUND_CARD:
+      g_value_set_string (value, preferences->sound_card);
+      break;
+    case PROP_CONTROLS:
+      g_value_set_boxed (value, preferences->controls);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 
@@ -202,18 +242,75 @@ xfce_mixer_preferences_set_property (GObject      *object,
                                      GParamSpec   *pspec)
 {
   XfceMixerPreferences *preferences = XFCE_MIXER_PREFERENCES (object);
-  GValue               *dest;
-
-  dest = preferences->values + prop_id;
+  gchar                *sound_cards_property_name;
+  GPtrArray            *controls;
+  guint                 i;
+  GValue               *element;
+  GValue               *control;
 
-  if (G_UNLIKELY (!G_IS_VALUE (dest)))
+  switch (prop_id)
     {
-      g_value_init (dest, pspec->value_type);
-      g_param_value_set_default (pspec, dest);
-    }
+    case PROP_WINDOW_WIDTH:
+      preferences->window_width = g_value_get_int (value);
+      break;
+    case PROP_WINDOW_HEIGHT:
+      preferences->window_height = g_value_get_int (value);
+      break;
+    case PROP_SOUND_CARD:
+      /* Freeze "notify" signals since the "controls" property is also manipulated */
+      g_object_freeze_notify (object);
+
+      g_free (preferences->sound_card);
+      preferences->sound_card = g_value_dup_string (value);
+
+      /* Remove the previous binding */
+      if (preferences->sound_cards_property_bind_id > 0)
+        {
+          xfconf_g_property_unbind (preferences->sound_cards_property_bind_id);
+          preferences->sound_cards_property_bind_id = 0UL;
+        }
+
+      /* Make sure the "controls" property is reset */
+      g_object_set (object, "controls", NULL, NULL);
 
-  if (G_LIKELY (g_param_values_cmp (pspec, value, dest) != 0))
-    g_value_copy (value, dest);
+      if (preferences->sound_card != NULL)
+        {
+          /* Bind to the property corresponding to the new sound card */
+          sound_cards_property_name = g_strdup_printf ("/sound-cards/%s", preferences->sound_card);
+          preferences->sound_cards_property_bind_id = xfconf_g_property_bind (preferences->channel, sound_cards_property_name, XFCE_MIXER_TYPE_VALUE_ARRAY, G_OBJECT (preferences), "controls");
+          g_free (sound_cards_property_name);
+        }
+
+      g_object_thaw_notify (object);
+      break;
+    case PROP_CONTROLS:
+      if (preferences->controls != NULL)
+        xfconf_array_free (preferences->controls);
+
+      controls = g_value_get_boxed (value);
+      if (controls != NULL)
+        {
+          preferences->controls = g_ptr_array_sized_new (controls->len);
+          for (i = 0; i < controls->len; ++i)
+            {
+              element = (GValue *) g_ptr_array_index (controls, i);
+
+              /* Filter out invalid value types */
+              if (G_VALUE_HOLDS_STRING (element))
+                {
+                  control = g_value_init (g_new0 (GValue, 1), G_TYPE_STRING);
+                  g_value_copy (element, control);
+                  g_ptr_array_add (preferences->controls, control);
+                }
+            }
+        }
+      else
+        preferences->controls = g_ptr_array_new ();
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
 }
 
 
@@ -236,166 +333,51 @@ xfce_mixer_preferences_get (void)
 
 
 
-static void
-xfce_mixer_preferences_load_controls (const gchar          *property_name,
-                                      const GValue         *value,
-                                      XfceMixerPreferences *preferences)
-{
-  gchar **controls;
-  gchar  *card_name;
-
-  g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences));
-  g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel));
-
-  if (G_UNLIKELY ((card_name = g_strrstr (property_name, "/")) == NULL))
-    return;
-
-  /* Remove the leading slash */
-  card_name = card_name + 1;
-
-  /* Read controls for this card */
-  controls = xfconf_channel_get_string_list (preferences->channel, property_name);
-
-  if (G_LIKELY (controls != NULL))
-    {
-      /* Store controls in the hash table */
-      g_hash_table_insert (preferences->controls, g_strdup (card_name), controls);
-    }
-}
-
-
-
-static void 
-xfce_mixer_preferences_load (XfceMixerPreferences *preferences)
-{
-  GHashTable *properties;
-
-  g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences));
-  g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel));
-
-  properties = xfconf_channel_get_properties (preferences->channel, "/sound-cards");
-
-  if (G_LIKELY (properties != NULL))
-    g_hash_table_foreach (properties, (GHFunc) xfce_mixer_preferences_load_controls, preferences);
-}
-
-
-
-static void
-xfce_mixer_preferences_store_controls (const gchar          *card_name,
-                                       gchar * const        *controls,
-                                       XfceMixerPreferences *preferences)
-{
-  gchar *property_name;
-
-  g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences));
-  g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel));
-
-  property_name = g_strdup_printf ("/sound-cards/%s", card_name);
-
-  if (G_UNLIKELY (controls != NULL))
-    xfconf_channel_set_string_list (preferences->channel, property_name, (const gchar * const *) controls);
-  else
-    xfconf_channel_reset_property (preferences->channel, property_name, TRUE);
-
-  g_free (property_name);
-}
-
-
-
-static void
-xfce_mixer_preferences_update_controls (const gchar          *property_name,
-                                        const GValue         *value,
-                                        XfceMixerPreferences *preferences)
-{
-  g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences));
-  g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel));
-
-  xfconf_channel_reset_property (preferences->channel, property_name, TRUE);
-}
-
-
-
-static void 
-xfce_mixer_preferences_store (XfceMixerPreferences *preferences)
+void
+xfce_mixer_preferences_set_controls (XfceMixerPreferences *preferences,
+                                     GPtrArray            *controls)
 {
-  GHashTable *properties;
-
   g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences));
-  g_return_if_fail (XFCONF_IS_CHANNEL (preferences->channel));
-
-  properties = xfconf_channel_get_properties (preferences->channel, "/sound-cards");
-
-  if (G_LIKELY (properties != NULL))
-    g_hash_table_foreach (properties, (GHFunc) xfce_mixer_preferences_update_controls, preferences);
+  g_return_if_fail (controls != NULL);
 
-  g_hash_table_foreach (preferences->controls, (GHFunc) xfce_mixer_preferences_store_controls, preferences);
+  g_object_set (G_OBJECT (preferences), "controls", controls, NULL);
 }
 
 
 
-gchar * const *
-xfce_mixer_preferences_get_visible_controls (XfceMixerPreferences *preferences,
-                                             GstElement           *card)
+GPtrArray *
+xfce_mixer_preferences_get_controls (XfceMixerPreferences *preferences)
 {
-  const gchar *card_name;
+  GPtrArray *controls;
 
   g_return_val_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences), NULL);
-  g_return_val_if_fail (GST_IS_MIXER (card), NULL);
-
-  card_name = xfce_mixer_get_card_internal_name (card);
-  return (gchar * const *) g_hash_table_lookup (preferences->controls, card_name);
-}
 
+  g_object_get (G_OBJECT (preferences), "controls", &controls, NULL);
 
-
-void
-xfce_mixer_preferences_set_visible_controls (XfceMixerPreferences *preferences,
-                                             GstElement           *card,
-                                             gchar * const        *controls)
-{
-  const gchar *card_name;
-  g_return_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences));
-  g_return_if_fail (GST_IS_MIXER (card));
-
-  card_name = xfce_mixer_get_card_internal_name (card);
-  g_hash_table_insert (preferences->controls, g_strdup (card_name), g_strdupv ((gchar **) controls));
-  xfce_mixer_preferences_store (preferences);
+  return controls;
 }
 
 
 
 gboolean
 xfce_mixer_preferences_get_control_visible (XfceMixerPreferences *preferences,
-                                            GstElement           *card,
-                                            GstMixerTrack        *track)
+                                            const gchar          *track_label)
 {
-  gchar * const *controls;
-  const gchar   *card_name;
   gboolean       visible = FALSE;
-  gchar         *label;
-  gint           i;
+  guint          i;
 
   g_return_val_if_fail (IS_XFCE_MIXER_PREFERENCES (preferences), FALSE);
-  g_return_val_if_fail (GST_IS_MIXER (card), FALSE);
-  g_return_val_if_fail (GST_IS_MIXER_TRACK (track), FALSE);
+  g_return_val_if_fail (preferences->controls != NULL, FALSE);
 
-  g_object_get (track, "label", &label, NULL);
-
-  card_name = xfce_mixer_get_card_internal_name (card);
-  controls = g_hash_table_lookup (preferences->controls, card_name);
-
-  if (G_LIKELY (controls != NULL))
+  for (i = 0; i < preferences->controls->len; ++i)
     {
-      for (i = 0; controls != NULL && controls[i] != NULL; ++i)
-        if (g_utf8_collate (controls[i], label) == 0)
-          {
-            visible = TRUE;
-            break;
-          }
+      if (xfce_mixer_utf8_cmp (g_value_get_string (g_ptr_array_index (preferences->controls, i)), track_label) == 0)
+        {
+          visible = TRUE;
+          break;
+        }
     }
 
-  g_free (label);
-
   return visible;
 }
+
diff --git a/libxfce4mixer/xfce-mixer-preferences.h b/libxfce4mixer/xfce-mixer-preferences.h
index 70ff50e..c4aa5c8 100644
--- a/libxfce4mixer/xfce-mixer-preferences.h
+++ b/libxfce4mixer/xfce-mixer-preferences.h
@@ -1,6 +1,7 @@
 /* vi:set expandtab sw=2 sts=2: */
 /*-
  * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012 Guido Berhoerster <guido+xfce at berhoerster.name>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,14 +42,11 @@ typedef struct _XfceMixerPreferences      XfceMixerPreferences;
 GType                 xfce_mixer_preferences_get_type             (void) G_GNUC_CONST;
 
 XfceMixerPreferences *xfce_mixer_preferences_get                  (void);
-gchar * const        *xfce_mixer_preferences_get_visible_controls (XfceMixerPreferences *preferences,
-                                                                   GstElement           *card);
-void                  xfce_mixer_preferences_set_visible_controls (XfceMixerPreferences *preferences,
-                                                                   GstElement           *card,
-                                                                   gchar * const        *controls);
+void                  xfce_mixer_preferences_set_controls         (XfceMixerPreferences *preferences,
+                                                                   GPtrArray            *controls);
+GPtrArray            *xfce_mixer_preferences_get_controls         (XfceMixerPreferences *preferences);
 gboolean              xfce_mixer_preferences_get_control_visible  (XfceMixerPreferences *preferences,
-                                                                   GstElement           *card,
-                                                                   GstMixerTrack        *track);
+                                                                   const gchar          *track_label);
 
 G_END_DECLS;
 
diff --git a/xfce4-mixer/xfce-mixer-controls-dialog.c b/xfce4-mixer/xfce-mixer-controls-dialog.c
index b9b851b..baa5c38 100644
--- a/xfce4-mixer/xfce-mixer-controls-dialog.c
+++ b/xfce4-mixer/xfce-mixer-controls-dialog.c
@@ -1,6 +1,7 @@
 /* vi:set expandtab sw=2 sts=2: */
 /*-
  * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012 Guido Berhoerster <guido+xfce at berhoerster.name>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,6 +28,7 @@
 
 #include <libxfce4util/libxfce4util.h>
 #include <libxfce4ui/libxfce4ui.h>
+#include <xfconf/xfconf.h>
 
 #include "libxfce4mixer/libxfce4mixer.h"
 
@@ -47,6 +49,7 @@ static void   xfce_mixer_controls_dialog_finalize             (GObject
 static void   xfce_mixer_controls_dialog_response             (GtkDialog                    *dialog,
                                                                gint                          response_id);
 static void   xfce_mixer_controls_dialog_create_contents      (XfceMixerControlsDialog      *dialog);
+static void   xfce_mixer_controls_dialog_update_preferences   (XfceMixerControlsDialog      *dialog);
 static void   xfce_mixer_controls_dialog_control_toggled      (GtkCellRendererToggle        *renderer,
                                                                gchar                        *path,
                                                                XfceMixerControlsDialog      *dialog);
@@ -66,6 +69,7 @@ struct _XfceMixerControlsDialog
   XfceMixerPreferences *preferences;
   GstElement           *card;
 
+  GtkWidget            *frame;
   GtkListStore         *store;
 };
 
@@ -130,6 +134,10 @@ xfce_mixer_controls_dialog_init (XfceMixerControlsDialog *dialog)
 
   dialog->preferences = xfce_mixer_preferences_get ();
 
+  dialog->card = NULL;
+
+  dialog->frame = NULL;
+
   gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 350);
   gtk_window_set_icon_name (GTK_WINDOW (dialog), "preferences-desktop");
   gtk_window_set_title (GTK_WINDOW (dialog), _("Select Controls"));
@@ -163,59 +171,11 @@ xfce_mixer_controls_dialog_finalize (GObject *object)
 
 
 
-static gboolean
-xfce_mixer_controls_dialog_collect_visible_controls (GtkTreeModel *model,
-                                                     GtkTreePath  *path,
-                                                     GtkTreeIter  *iter,
-                                                     GList       **controls)
-{
-  gboolean visible;
-  gchar   *name;
-
-  gtk_tree_model_get (model, iter, VISIBLE_COLUMN, &visible, NAME_COLUMN, &name, -1);
-
-  if (G_LIKELY (visible && name != NULL))
-    *controls = g_list_append (*controls, name);
-
-  return FALSE;
-}
-
-
-
 static void
 xfce_mixer_controls_dialog_response (GtkDialog *dialog,
                                      gint       response_id)
 {
-  XfceMixerControlsDialog *mixer_dialog = XFCE_MIXER_CONTROLS_DIALOG (dialog);
-  XfceMixerPreferences    *preferences;
-  GList                   *visible_controls = NULL;
-  gchar                  **controls;
-  guint                    i;
-
-  gtk_tree_model_foreach (GTK_TREE_MODEL (mixer_dialog->store), 
-                          (GtkTreeModelForeachFunc) xfce_mixer_controls_dialog_collect_visible_controls,
-                          &visible_controls);
-
-  preferences = xfce_mixer_preferences_get ();
-
-  if (G_LIKELY (g_list_length (visible_controls) > 0))
-    {
-      controls = g_new0 (gchar *, g_list_length (visible_controls) + 1);
-      controls[g_list_length (visible_controls)] = NULL;
-
-      for (i = 0; i < g_list_length (visible_controls); ++i)
-        controls[i] = (gchar *) g_list_nth (visible_controls, i)->data;
-
-      xfce_mixer_preferences_set_visible_controls (preferences, mixer_dialog->card, controls);
-
-      g_strfreev (controls);
-    }
-  else
-    xfce_mixer_preferences_set_visible_controls (preferences, mixer_dialog->card, NULL);
-
-  g_object_unref (preferences);
-
-  g_list_free (visible_controls);
+  xfce_mixer_controls_dialog_update_preferences (XFCE_MIXER_CONTROLS_DIALOG (dialog));
 }
 
 
@@ -227,6 +187,7 @@ xfce_mixer_controls_dialog_new (XfceMixerWindow *window)
 
   dialog = g_object_new (TYPE_XFCE_MIXER_CONTROLS_DIALOG, NULL);
   dialog->parent = window;
+
   dialog->card = xfce_mixer_window_get_active_card (window);
 
   gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (dialog->parent));
@@ -241,30 +202,23 @@ xfce_mixer_controls_dialog_new (XfceMixerWindow *window)
 static void
 xfce_mixer_controls_dialog_create_contents (XfceMixerControlsDialog *dialog)
 {
-  XfceMixerPreferences *preferences;
   GtkTreeViewColumn    *column;
   GtkCellRenderer      *renderer;
-  GstElement           *card;
-  const GList          *iter;
-  GtkTreeIter           tree_iter;
   GtkWidget            *view;
-  GtkWidget            *frame;
   GtkWidget            *scrollwin;
-  gchar                *label;
-  gboolean              visible;
 
   dialog->store = gtk_list_store_new (2, G_TYPE_BOOLEAN, G_TYPE_STRING);
 
-  frame = gtk_frame_new (NULL);
-  gtk_container_set_border_width (GTK_CONTAINER (frame), 6);
-  gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
-  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), frame);
-  gtk_widget_show (frame);
+  dialog->frame = gtk_frame_new (NULL);
+  gtk_container_set_border_width (GTK_CONTAINER (dialog->frame), 6);
+  gtk_frame_set_shadow_type (GTK_FRAME (dialog->frame), GTK_SHADOW_NONE);
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), dialog->frame);
+  gtk_widget_show (dialog->frame);
 
   scrollwin = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_IN);
-  gtk_container_add (GTK_CONTAINER (frame), scrollwin);
+  gtk_container_add (GTK_CONTAINER (dialog->frame), scrollwin);
   gtk_widget_show (scrollwin);
 
   view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog->store));
@@ -282,29 +236,85 @@ xfce_mixer_controls_dialog_create_contents (XfceMixerControlsDialog *dialog)
   column = gtk_tree_view_column_new_with_attributes ("Control", renderer, "text", NAME_COLUMN, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
 
+  xfce_mixer_controls_dialog_update_dialog (dialog);
+}
+
+
+
+void
+xfce_mixer_controls_dialog_update_dialog (XfceMixerControlsDialog *dialog)
+{
+  XfceMixerPreferences *preferences;
+  const GList          *iter;
+  gchar                *track_label;
+  gboolean              visible;
+  GtkTreeIter           tree_iter;
+
+  /* Clear the list before recreating it below */
+  gtk_list_store_clear (dialog->store);
+
+  if (G_UNLIKELY (!GST_IS_MIXER (dialog->card)))
+    return;
+
   preferences = xfce_mixer_preferences_get ();
-  card = xfce_mixer_window_get_active_card (dialog->parent);
 
-  if (G_LIKELY (card != NULL))
+  for (iter = gst_mixer_list_tracks (GST_MIXER (dialog->card));
+       iter != NULL;
+       iter = g_list_next (iter))
     {
-      for (iter = gst_mixer_list_tracks (GST_MIXER (dialog->card)); 
-           iter != NULL; 
-           iter = g_list_next (iter))
-        {
-          visible = xfce_mixer_preferences_get_control_visible (preferences, dialog->card, iter->data);
+      g_object_get (GST_MIXER_TRACK (iter->data), "label", &track_label, NULL);
+
+      visible = xfce_mixer_preferences_get_control_visible (preferences, track_label);
+
+      gtk_list_store_append (dialog->store, &tree_iter);
+      gtk_list_store_set (dialog->store, &tree_iter,
+                        VISIBLE_COLUMN, visible,
+                        NAME_COLUMN, track_label,
+                        -1);
+
+      g_free (track_label);
+    }
+
+  g_object_unref (preferences);
+}
+
+
 
-          g_object_get (GST_MIXER_TRACK (iter->data), "label", &label, NULL, NULL);
+static void
+xfce_mixer_controls_dialog_update_preferences (XfceMixerControlsDialog *dialog)
+{
+  XfceMixerPreferences  *preferences;
+  GPtrArray             *controls;
+  GtkTreeModel          *model;
+  GtkTreeIter            iter;
+  gboolean               visible;
+  GValue                *name;
 
-          gtk_list_store_append (dialog->store, &tree_iter);
-          gtk_list_store_set (dialog->store, &tree_iter, 
-                              VISIBLE_COLUMN, visible, 
-                              NAME_COLUMN, label, 
-                              -1);
+  preferences = xfce_mixer_preferences_get ();
 
-          g_free (label);
+  controls = g_ptr_array_new ();
+
+  model = GTK_TREE_MODEL (dialog->store);
+  if (gtk_tree_model_get_iter_first (model, &iter))
+    {
+      do
+        {
+          gtk_tree_model_get (model, &iter, VISIBLE_COLUMN, &visible, -1);
+
+          if (visible)
+            {
+              name = g_new0 (GValue, 1);
+              gtk_tree_model_get_value (model, &iter, NAME_COLUMN, name);
+              g_ptr_array_add (controls, name);
+            }
         }
+      while (gtk_tree_model_iter_next(model, &iter));
     }
 
+  xfce_mixer_preferences_set_controls (preferences, controls);
+
+  xfconf_array_free (controls);
+
   g_object_unref (preferences);
 }
 
@@ -328,5 +338,24 @@ xfce_mixer_controls_dialog_control_toggled (GtkCellRendererToggle   *renderer,
   else
     gtk_list_store_set (dialog->store, &iter, VISIBLE_COLUMN, FALSE, -1);
 
+  xfce_mixer_controls_dialog_update_preferences (dialog);
+
   g_free (name);
 }
+
+
+
+void
+xfce_mixer_controls_dialog_set_soundcard (XfceMixerControlsDialog *dialog,
+                                          GstElement              *card)
+{
+  g_return_if_fail (IS_XFCE_MIXER_CONTROLS_DIALOG (dialog));
+  g_return_if_fail (GST_IS_MIXER (card));
+
+  dialog->card = card;
+
+  /* Recreate contents corresponding to the new card */
+  gtk_widget_destroy (dialog->frame);
+  xfce_mixer_controls_dialog_create_contents (dialog);
+}
+
diff --git a/xfce4-mixer/xfce-mixer-controls-dialog.h b/xfce4-mixer/xfce-mixer-controls-dialog.h
index 11b1130..739e95a 100644
--- a/xfce4-mixer/xfce-mixer-controls-dialog.h
+++ b/xfce4-mixer/xfce-mixer-controls-dialog.h
@@ -1,6 +1,7 @@
 /* vi:set expandtab sw=2 sts=2: */
 /*-
  * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012 Guido Berhoerster <guido+xfce at berhoerster.name>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,7 +38,10 @@ typedef struct _XfceMixerControlsDialog      XfceMixerControlsDialog;
 
 GType      xfce_mixer_controls_dialog_get_type (void) G_GNUC_CONST;
 
-GtkWidget *xfce_mixer_controls_dialog_new      (XfceMixerWindow *parent);
+GtkWidget *xfce_mixer_controls_dialog_new           (XfceMixerWindow         *parent);
+void       xfce_mixer_controls_dialog_set_soundcard (XfceMixerControlsDialog *dialog,
+                                                     GstElement              *card);
+void       xfce_mixer_controls_dialog_update_dialog (XfceMixerControlsDialog *dialog);
 
 G_END_DECLS;
 
diff --git a/xfce4-mixer/xfce-mixer-window.c b/xfce4-mixer/xfce-mixer-window.c
index 11ecf1d..a21afd6 100644
--- a/xfce4-mixer/xfce-mixer-window.c
+++ b/xfce4-mixer/xfce-mixer-window.c
@@ -1,6 +1,7 @@
 /* vi:set expandtab sw=2 sts=2: */
 /*-
  * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012 Guido Berhoerster <guido+xfce at berhoerster.name>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,21 +38,27 @@
 
 
 
-static void     xfce_mixer_window_class_init             (XfceMixerWindowClass *klass);
-static void     xfce_mixer_window_init                   (XfceMixerWindow      *window);
-static void     xfce_mixer_window_dispose                (GObject              *object);
-static void     xfce_mixer_window_finalize               (GObject              *object);
-static void     xfce_mixer_window_soundcard_changed      (XfceMixerCardCombo   *combo,
-                                                          GstElement           *card,
-                                                          XfceMixerWindow      *window);
-static void     xfce_mixer_window_action_select_controls (GtkAction            *action,
-                                                          XfceMixerWindow      *window);
-static void     xfce_mixer_window_close                  (GtkAction            *action,
-                                                          XfceMixerWindow      *window);
-static gboolean xfce_mixer_window_closed                 (GtkWidget            *window,
-                                                          GdkEvent             *event,
-                                                          XfceMixerWindow      *mixer_window);
-static void     xfce_mixer_window_update_contents        (XfceMixerWindow      *window);
+static void     xfce_mixer_window_class_init                  (XfceMixerWindowClass *klass);
+static void     xfce_mixer_window_init                        (XfceMixerWindow      *window);
+static void     xfce_mixer_window_dispose                     (GObject              *object);
+static void     xfce_mixer_window_finalize                    (GObject              *object);
+static void     xfce_mixer_window_soundcard_changed           (XfceMixerCardCombo   *combo,
+                                                               GstElement           *card,
+                                                               XfceMixerWindow      *window);
+static void     xfce_mixer_window_soundcard_property_changed  (XfceMixerWindow      *window,
+                                                               GParamSpec           *pspec,
+                                                               GObject              *object);
+static void     xfce_mixer_window_action_select_controls      (GtkAction            *action,
+                                                               XfceMixerWindow      *window);
+static void     xfce_mixer_window_controls_property_changed   (XfceMixerWindow *window,
+                                                               GParamSpec      *pspec,
+                                                               GObject         *object);
+static void     xfce_mixer_window_close                       (GtkAction            *action,
+                                                               XfceMixerWindow      *window);
+static gboolean xfce_mixer_window_closed                      (GtkWidget            *window,
+                                                               GdkEvent             *event,
+                                                               XfceMixerWindow      *mixer_window);
+static void     xfce_mixer_window_update_contents             (XfceMixerWindow      *window);
 
 
 
@@ -75,6 +82,8 @@ struct _XfceMixerWindow
   GtkWidget            *mixer;
 
   GtkWidget            *select_controls_button;
+
+  GtkWidget            *controls_dialog;
 };
 
 
@@ -152,15 +161,30 @@ xfce_mixer_window_init (XfceMixerWindow *window)
   GtkWidget     *vbox;
   GtkWidget     *hbox;
   GtkWidget     *bbox;
-  gchar         *active_card = NULL;
+  gchar         *card_name;
+  GstElement    *card;
   gchar         *title;
   guint          i;
   gint           width;
   gint           height;
 
+  window->mixer = NULL;
+
+  window->controls_dialog = NULL;
+
   window->preferences = xfce_mixer_preferences_get ();
 
-  g_object_get (window->preferences, "window-width", &width, "window-height", &height, "sound-card", &active_card, NULL);
+  g_object_get (window->preferences, "window-width", &width, "window-height", &height, "sound-card", &card_name, NULL);
+  if (card_name != NULL)
+    card = xfce_mixer_get_card (card_name);
+  else
+    {
+      card = xfce_mixer_get_default_card ();
+
+      if (GST_IS_MIXER (card))
+        g_object_set (window->preferences, "sound-card", xfce_mixer_get_card_internal_name (card), NULL);
+    }
+  g_free (card_name);
 
   /* Configure the main window */
   gtk_window_set_type_hint (GTK_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
@@ -207,8 +231,8 @@ xfce_mixer_window_init (XfceMixerWindow *window)
   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
   gtk_widget_show (label);
 
-  window->soundcard_combo = xfce_mixer_card_combo_new (xfce_mixer_get_card (active_card));
-  g_signal_connect (window->soundcard_combo, "soundcard-changed", G_CALLBACK (xfce_mixer_window_soundcard_changed), window);
+  window->soundcard_combo = xfce_mixer_card_combo_new (card);
+  g_signal_connect (G_OBJECT (window->soundcard_combo), "soundcard-changed", G_CALLBACK (xfce_mixer_window_soundcard_changed), window);
   gtk_container_add (GTK_CONTAINER (hbox), window->soundcard_combo);
   gtk_widget_show (window->soundcard_combo);
 
@@ -238,10 +262,12 @@ xfce_mixer_window_init (XfceMixerWindow *window)
   gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, TRUE, 0);
   gtk_widget_show (button);
 
+  g_signal_connect_swapped (G_OBJECT (window->preferences), "notify::sound-card", G_CALLBACK (xfce_mixer_window_soundcard_property_changed), window);
+
+  g_signal_connect_swapped (G_OBJECT (window->preferences), "notify::controls", G_CALLBACK (xfce_mixer_window_controls_property_changed), window);
+
   /* Re-generate mixer controls for the active sound card */
   xfce_mixer_window_update_contents (window);
-
-  g_free (active_card);
 }
 
 
@@ -279,36 +305,70 @@ xfce_mixer_window_soundcard_changed (XfceMixerCardCombo *combo,
                                      GstElement         *card,
                                      XfceMixerWindow    *window)
 {
-  gchar *title;
-
   g_return_if_fail (IS_XFCE_MIXER_CARD_COMBO (combo));
   g_return_if_fail (IS_XFCE_MIXER_WINDOW (window));
   g_return_if_fail (GST_IS_MIXER (card));
 
-  title = g_strdup_printf ("%s - %s", _("Audio Mixer"), xfce_mixer_get_card_display_name (card));
-  gtk_window_set_title (GTK_WINDOW (window), title);
-  g_free (title);
+  /* Remember the card for next time */
+  g_signal_handlers_block_by_func (G_OBJECT (window->preferences), G_CALLBACK (xfce_mixer_window_soundcard_property_changed), window);
+  g_object_set (G_OBJECT (window->preferences), "sound-card", xfce_mixer_get_card_internal_name (card), NULL);
+  g_signal_handlers_unblock_by_func (G_OBJECT (window->preferences), G_CALLBACK (xfce_mixer_window_soundcard_property_changed), window);
 
-  /* Destroy the current mixer */
-  if (G_LIKELY (window->mixer != NULL))
-    gtk_widget_destroy (gtk_bin_get_child (GTK_BIN (window->mixer_frame)));
+  /* Re-generate mixer controls for the active sound card */
+  xfce_mixer_window_update_contents (window);
 
-  DBG ("card = %s", xfce_mixer_get_card_internal_name (card));
+  /* Update the controls dialog */
+  if (window->controls_dialog != NULL)
+    xfce_mixer_controls_dialog_set_soundcard (XFCE_MIXER_CONTROLS_DIALOG (window->controls_dialog), card);
+}
 
-  xfce_mixer_select_card (card);
 
-  /* Create a new XfceMixer for the active sound card */
-  window->mixer = xfce_mixer_new (card);
 
-  /* Add the XfceMixer to the window */
-  gtk_container_add (GTK_CONTAINER (window->mixer_frame), window->mixer);
-  gtk_widget_show (window->mixer);
+static void
+xfce_mixer_window_soundcard_property_changed (XfceMixerWindow *window,
+                                              GParamSpec      *pspec,
+                                              GObject         *object)
+{
+  gchar       *new_card_name;
+  GstElement  *new_card = NULL;
+  GstElement  *old_card;
 
-  /* Make the "Select Controls..." button sensitive */
-  gtk_widget_set_sensitive (window->select_controls_button, TRUE);
+  g_return_if_fail (IS_XFCE_MIXER_WINDOW (window));
+  g_return_if_fail (G_IS_OBJECT (object));
 
-  /* Remember the card for next time */
-  g_object_set (G_OBJECT (window->preferences), "sound-card", xfce_mixer_get_card_internal_name (card), NULL);
+  g_object_get (object, "sound-card", &new_card_name, NULL);
+  if (new_card_name != NULL)
+    new_card = xfce_mixer_get_card (new_card_name);
+  g_free (new_card_name);
+
+  /* If the new card is not valid reset it to the default */
+  if (!GST_IS_MIXER (new_card))
+    {
+      new_card = xfce_mixer_get_default_card ();
+
+      if (GST_IS_MIXER (new_card))
+        g_object_set (object, "sound-card", xfce_mixer_get_card_internal_name (new_card), NULL);
+
+      return;
+    }
+
+  old_card = xfce_mixer_card_combo_get_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo));
+
+  /* Only update if different from the active card */
+  if (new_card != old_card)
+    {
+      /* Update the combobox */
+      g_signal_handlers_block_by_func (G_OBJECT (window->soundcard_combo), G_CALLBACK (xfce_mixer_window_soundcard_changed), window);
+      xfce_mixer_card_combo_set_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo), new_card);
+      g_signal_handlers_unblock_by_func (G_OBJECT (window->soundcard_combo), G_CALLBACK (xfce_mixer_window_soundcard_changed), window);
+
+      /* Re-generate mixer controls for the active sound card */
+      xfce_mixer_window_update_contents (window);
+
+      /* Update the controls dialog */
+      if (window->controls_dialog != NULL)
+        xfce_mixer_controls_dialog_set_soundcard (XFCE_MIXER_CONTROLS_DIALOG (window->controls_dialog), new_card);
+    }
 }
 
 
@@ -317,14 +377,27 @@ static void
 xfce_mixer_window_action_select_controls (GtkAction       *action,
                                           XfceMixerWindow *window)
 {
-  GtkWidget     *dialog;
+  g_return_if_fail (window->controls_dialog == NULL);
 
-  dialog = xfce_mixer_controls_dialog_new (window);
+  window->controls_dialog = xfce_mixer_controls_dialog_new (window);
+
+  gtk_dialog_run (GTK_DIALOG (window->controls_dialog));
+  gtk_widget_destroy (window->controls_dialog);
+  window->controls_dialog = NULL;
+}
 
-  gtk_dialog_run (GTK_DIALOG (dialog));
-  gtk_widget_destroy (dialog);
 
+
+static void
+xfce_mixer_window_controls_property_changed (XfceMixerWindow *window,
+                                             GParamSpec      *pspec,
+                                             GObject         *object)
+{
   xfce_mixer_window_update_contents (window);
+
+  /* Update the controls dialog */
+  if (window->controls_dialog != NULL)
+    xfce_mixer_controls_dialog_update_dialog (XFCE_MIXER_CONTROLS_DIALOG (window->controls_dialog));
 }
 
 
@@ -369,13 +442,33 @@ xfce_mixer_window_get_active_card (XfceMixerWindow *window)
 static void
 xfce_mixer_window_update_contents (XfceMixerWindow *window)
 {
-  GstElement *card;
+  gchar       *title;
+  GstElement  *card;
 
   g_return_if_fail (IS_XFCE_MIXER_WINDOW (window));
 
   card = xfce_mixer_card_combo_get_active_card (XFCE_MIXER_CARD_COMBO (window->soundcard_combo));
 
-  /* Kind of a hack to regenerate the mixer controls */
-  if (G_LIKELY (GST_IS_MIXER (card)))
-    xfce_mixer_window_soundcard_changed (XFCE_MIXER_CARD_COMBO (window->soundcard_combo), card, window);
+  if (G_UNLIKELY (!GST_IS_MIXER (card)))
+    return;
+
+  title = g_strdup_printf ("%s - %s", _("Audio Mixer"), xfce_mixer_get_card_display_name (card));
+  gtk_window_set_title (GTK_WINDOW (window), title);
+  g_free (title);
+
+  /* Destroy the current mixer */
+  if (G_LIKELY (window->mixer != NULL))
+    gtk_widget_destroy (window->mixer);
+
+  xfce_mixer_select_card (card);
+
+  /* Create a new XfceMixer for the active sound card */
+  window->mixer = xfce_mixer_new (card);
+
+  /* Add the XfceMixer to the window */
+  gtk_container_add (GTK_CONTAINER (window->mixer_frame), window->mixer);
+  gtk_widget_show (window->mixer);
+
+  /* Make the "Select Controls..." button sensitive */
+  gtk_widget_set_sensitive (window->select_controls_button, TRUE);
 }
diff --git a/xfce4-mixer/xfce-mixer.c b/xfce4-mixer/xfce-mixer.c
index 26cb625..f61a87e 100644
--- a/xfce4-mixer/xfce-mixer.c
+++ b/xfce4-mixer/xfce-mixer.c
@@ -1,6 +1,7 @@
 /* vi:set expandtab sw=2 sts=2: */
 /*-
  * Copyright (c) 2008 Jannis Pohlmann <jannis at xfce.org>
+ * Copyright (c) 2012 Guido Berhoerster <guido+xfce at berhoerster.name>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -165,7 +166,7 @@ xfce_mixer_constructed (GObject *object)
   GtkWidget            *last_separator[4] = { NULL, NULL, NULL, NULL };
   GtkWidget            *label1;
   GtkWidget            *label2;
-  gchar                *label;
+  gchar                *track_label;
   guint                 num_children[4] = { 0, 0, 0, 0 };
   gint                  i;
 
@@ -203,14 +204,17 @@ xfce_mixer_constructed (GObject *object)
     {
       track = iter->data;
 
-      if (!xfce_mixer_preferences_get_control_visible (preferences, mixer->card, track))
-        continue;
+      g_object_get (GST_MIXER_TRACK (track), "label", &track_label, NULL);
+
+      if (!xfce_mixer_preferences_get_control_visible (preferences, track_label))
+        {
+          g_free (track_label);
+          continue;
+        }
 
       /* Determine the type of the mixer track */
       type = xfce_mixer_track_type_new (track);
 
-      g_object_get (GST_MIXER_TRACK (track), "label", &label, NULL);
-
       switch (type) 
         {
         case XFCE_MIXER_TRACK_TYPE_PLAYBACK:
@@ -229,7 +233,7 @@ xfce_mixer_constructed (GObject *object)
           num_children[0]++;
 
           /* Add the track to the hash table */
-          g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget);
+          g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
           break;
 
         case XFCE_MIXER_TRACK_TYPE_CAPTURE:
@@ -248,7 +252,7 @@ xfce_mixer_constructed (GObject *object)
           num_children[1]++;
 
           /* Add the track to the hash table */
-          g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget);
+          g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
           break;
 
         case XFCE_MIXER_TRACK_TYPE_SWITCH:
@@ -258,7 +262,7 @@ xfce_mixer_constructed (GObject *object)
           num_children[2]++;
 
           /* Add the track to the hash table */
-          g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget);
+          g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
           break;
 
         case XFCE_MIXER_TRACK_TYPE_OPTIONS:
@@ -268,11 +272,11 @@ xfce_mixer_constructed (GObject *object)
           num_children[3]++;
 
           /* Add the track to the hash table */
-          g_hash_table_insert (mixer->widgets, g_strdup (label), track_widget);
+          g_hash_table_insert (mixer->widgets, g_strdup (track_label), track_widget);
           break;
         }
 
-      g_free (label);
+      g_free (track_label);
     }
 
   /* Append tab or destroy all its widgets - depending on the contents of each tab */


More information about the Xfce4-commits mailing list