Index: gnome-settings-daemon-3.4.2/configure.ac
===================================================================
--- gnome-settings-daemon-3.4.2.orig/configure.ac	2012-05-22 21:09:13.285387324 +0200
+++ gnome-settings-daemon-3.4.2/configure.ac	2012-05-22 21:09:13.305387324 +0200
@@ -237,7 +237,7 @@
 dnl - media-keys plugin stuff
 dnl ---------------------------------------------------------------------------
 
-PKG_CHECK_MODULES(MEDIA_KEYS, [gio-unix-2.0 libpulse >= $PA_REQUIRED_VERSION $GUDEV_PKG libpulse-mainloop-glib >= $PA_REQUIRED_VERSION libcanberra libnotify])
+PKG_CHECK_MODULES(MEDIA_KEYS, [gio-unix-2.0 libpulse >= $PA_REQUIRED_VERSION $GUDEV_PKG libpulse-mainloop-glib >= $PA_REQUIRED_VERSION libcanberra gconf-2.0 >= $GCONF_REQUIRED_VERSION libnotify])
 
 dnl ---------------------------------------------------------------------------
 dnl - color
Index: gnome-settings-daemon-3.4.2/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in
===================================================================
--- gnome-settings-daemon-3.4.2.orig/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in	2012-05-15 12:14:45.000000000 +0200
+++ gnome-settings-daemon-3.4.2/data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in	2012-05-22 21:09:13.305387324 +0200
@@ -5,11 +5,6 @@
       <_summary>Activation of this plugin</_summary>
       <_description>Whether this plugin would be activated by gnome-settings-daemon or not</_description>
     </key>
-    <key name="custom-keybindings" type="as">
-      <default>[]</default>
-      <_summary>Custom keybindings</_summary>
-      <_description>List of custom keybindings</_description>
-    </key>
     <key name="calculator" type="s">
       <default>'XF86Calculator'</default>
       <_summary>Launch calculator</_summary>
@@ -176,22 +171,4 @@
       <_description>Binding for the magnifier to zoom out</_description>
     </key>
   </schema>
-
-  <schema gettext-domain="@GETTEXT_PACKAGE@" id="org.gnome.settings-daemon.plugins.media-keys.custom-keybinding">
-    <key name="name" type="s">
-      <default>''</default>
-      <_summary>Name</_summary>
-      <_description>Name of the custom binding</_description>
-    </key>
-    <key name="binding" type="s">
-      <default>''</default>
-      <_summary>Binding</_summary>
-      <_description>Binding for the custom binding</_description>
-    </key>
-    <key name="command" type="s">
-      <default>''</default>
-      <_summary>Command</_summary>
-      <_description>Command to run when the binding is invoked</_description>
-    </key>
-  </schema>
 </schemalist>
Index: gnome-settings-daemon-3.4.2/plugins/media-keys/gsd-media-keys-manager.c
===================================================================
--- gnome-settings-daemon-3.4.2.orig/plugins/media-keys/gsd-media-keys-manager.c	2012-05-22 21:09:12.629387348 +0200
+++ gnome-settings-daemon-3.4.2/plugins/media-keys/gsd-media-keys-manager.c	2012-05-22 21:09:21.917387019 +0200
@@ -39,6 +39,7 @@
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 #include <gio/gdesktopappinfo.h>
+#include <gconf/gconf-client.h>
 
 #ifdef HAVE_GUDEV
 #include <gudev/gudev.h>
@@ -72,7 +73,7 @@
 #define GNOME_KEYRING_DBUS_PATH "/org/gnome/keyring/daemon"
 #define GNOME_KEYRING_DBUS_INTERFACE "org.gnome.keyring.Daemon"
 
-#define CUSTOM_BINDING_SCHEMA SETTINGS_BINDING_DIR ".custom-keybinding"
+#define GCONF_BINDING_DIR "/desktop/gnome/keybindings"
 
 static const gchar introspection_xml[] =
 "<node>"
@@ -115,7 +116,7 @@
         MediaKeyType key_type;
         const char *settings_key;
         const char *hard_coded;
-        char *custom_path;
+        char *gconf_dir;
         char *custom_command;
         Key *key;
 } MediaKey;
@@ -134,9 +135,10 @@
 
         GtkWidget       *dialog;
         GSettings       *settings;
-        GHashTable      *custom_settings;
 
         GPtrArray       *keys;
+        GConfClient     *gconf;
+        guint            gconf_id;
 
         /* HighContrast theme settings */
         GSettings       *interface_settings;
@@ -174,9 +176,6 @@
 static void     gsd_media_keys_manager_init        (GsdMediaKeysManager      *media_keys_manager);
 static void     gsd_media_keys_manager_finalize    (GObject                  *object);
 static void     register_manager                   (GsdMediaKeysManager      *manager);
-static void     custom_binding_changed             (GSettings           *settings,
-                                                    const char          *settings_key,
-                                                    GsdMediaKeysManager *manager);
 G_DEFINE_TYPE (GsdMediaKeysManager, gsd_media_keys_manager, G_TYPE_OBJECT)
 
 static gpointer manager_object = NULL;
@@ -333,7 +332,7 @@
 {
         if (key == NULL)
                 return;
-        g_free (key->custom_path);
+        g_free (key->gconf_dir);
         g_free (key->custom_command);
         free_key (key->key);
         g_free (key);
@@ -499,12 +498,13 @@
 		return g_settings_get_string (manager->priv->settings, key->settings_key);
 	else if (key->hard_coded != NULL)
 		return g_strdup (key->hard_coded);
-	else if (key->custom_path != NULL) {
-                GSettings *settings;
+	else if (key->gconf_dir != NULL) {
+		char *entry, *str;
 
-                settings = g_hash_table_lookup (manager->priv->custom_settings,
-                                                key->custom_path);
-		return g_settings_get_string (settings, "binding");
+		entry = g_strdup_printf ("%s/binding", key->gconf_dir);
+		str = gconf_client_get_string (manager->priv->gconf, entry, NULL);
+		g_free (entry);
+		return str;
 	} else
 		g_assert_not_reached ();
 }
@@ -550,10 +550,6 @@
         int      i;
         gboolean need_flush = TRUE;
 
-	/* handled in gsettings_custom_changed_cb() */
-        if (g_str_equal (settings_key, "custom-keybindings"))
-		return;
-
         gdk_error_trap_push ();
 
         /* Find the key that was modified */
@@ -578,159 +574,144 @@
                 g_warning ("Grab failed for some keys, another application may already have access the them.");
 }
 
-static MediaKey *
-media_key_new_for_path (GsdMediaKeysManager *manager,
-			char                *path)
+static char *
+entry_get_string (GConfEntry *entry)
 {
-        GSettings *settings;
-        char *command, *binding;
-        MediaKey *key;
-
-        g_debug ("media_key_new_for_path: %s", path);
-
-	settings = g_hash_table_lookup (manager->priv->custom_settings, path);
-	if (settings == NULL) {
-		settings = g_settings_new_with_path (CUSTOM_BINDING_SCHEMA, path);
-
-		g_signal_connect (settings, "changed",
-				  G_CALLBACK (custom_binding_changed), manager);
-		g_hash_table_insert (manager->priv->custom_settings,
-				     g_strdup (path), settings);
-	}
-
-        command = g_settings_get_string (settings, "command");
-        binding = g_settings_get_string (settings, "binding");
+        GConfValue *value = gconf_entry_get_value (entry);
 
-        if (*command == '\0' && *binding == '\0') {
-                g_debug ("Key binding (%s) is incomplete", path);
-                g_free (command);
-                g_free (binding);
+        if (value == NULL || value->type != GCONF_VALUE_STRING) {
                 return NULL;
         }
-        g_free (binding);
 
-        key = g_new0 (MediaKey, 1);
-        key->key_type = CUSTOM_KEY;
-        key->custom_path = g_strdup (path);
-        key->custom_command = command;
-
-        return key;
+        return g_strdup (gconf_value_get_string (value));
 }
 
-static void
-update_custom_binding (GsdMediaKeysManager *manager,
-                       char                *path)
+static MediaKey *
+media_key_new_for_gconf (GsdMediaKeysManager *manager,
+			 char                *dir)
 {
+        GSList *list, *l;
+        char *action, *binding;
         MediaKey *key;
-        int i;
 
-        /* Remove the existing key */
-        for (i = 0; i < manager->priv->keys->len; i++) {
-                key = g_ptr_array_index (manager->priv->keys, i);
-
-                if (key->custom_path == NULL)
-                        continue;
-                if (strcmp (key->custom_path, path) == 0) {
-                        g_debug ("Removing custom key binding %s", path);
-                        if (key->key) {
-                                gdk_error_trap_push ();
-
-                                grab_key_unsafe (key->key,
-                                                 FALSE,
-                                                 manager->priv->screens);
-
-                                gdk_flush ();
-                                if (gdk_error_trap_pop ())
-                                        g_warning ("Ungrab failed for custom key '%s'", path);
-                        }
-                        g_ptr_array_remove_index_fast (manager->priv->keys, i);
-                        break;
+        /* Get entries for this binding */
+        list = gconf_client_all_entries (manager->priv->gconf, dir, NULL);
+        action = NULL;
+        binding = NULL;
+
+        for (l = list; l != NULL; l = l->next) {
+                GConfEntry *entry = l->data;
+                char *key_name;
+
+                key_name = g_path_get_basename (gconf_entry_get_key (entry));
+
+                if (key_name == NULL) {
+                        /* ignore entry */
+                } else if (strcmp (key_name, "action") == 0) {
+                        action = entry_get_string (entry);
+                } else if (strcmp (key_name, "binding") == 0) {
+                        binding = entry_get_string (entry);
                 }
-        }
 
-        /* And create a new one! */
-        key = media_key_new_for_path (manager, path);
-        if (key) {
-                g_debug ("Adding new custom key binding %s", path);
-                g_ptr_array_add (manager->priv->keys, key);
-
-                gdk_error_trap_push ();
+                g_free (key_name);
+                gconf_entry_free (entry);
+        }
 
-                grab_media_key (key, manager);
+        g_slist_free (list);
 
-                gdk_flush ();
-                if (gdk_error_trap_pop ())
-                        g_warning ("Grab failed for custom key '%s'",
-                                   key->custom_path);
+        if (action == NULL && binding == NULL) {
+                g_debug ("Key binding (%s) is incomplete", dir);
+                return NULL;
         }
-}
-
-static void
-custom_binding_changed (GSettings           *settings,
-                        const char          *settings_key,
-                        GsdMediaKeysManager *manager)
-{
-        char *path;
+        g_free (binding);
 
-        if (strcmp (settings_key, "name") == 0)
-                return; /* we don't care */
+        key = g_new0 (MediaKey, 1);
+        key->key_type = CUSTOM_KEY;
+        key->gconf_dir = dir;
+        key->custom_command = action;
 
-        g_object_get (settings, "path", &path, NULL);
-        update_custom_binding (manager, path);
-        g_free (path);
+        return key;
 }
 
 static void
-gsettings_custom_changed_cb (GSettings           *settings,
-                             const char          *settings_key,
-                             GsdMediaKeysManager *manager)
+gconf_changed_cb (GConfClient         *client,
+                  guint                cnxn_id,
+                  GConfEntry          *entry,
+                  GsdMediaKeysManager *manager)
 {
-        char **bindings;
-        int i, j, n_bindings;
-
-        bindings = g_settings_get_strv (settings, settings_key);
-        n_bindings = g_strv_length (bindings);
-
-        /* Handle additions */
-        for (i = 0; i < n_bindings; i++) {
-                if (g_hash_table_lookup (manager->priv->custom_settings,
-                                         bindings[i]))
-                        continue;
-                update_custom_binding (manager, bindings[i]);
-        }
+	char *gconf_key, **key_elems;
+	int      i;
+	MediaKey *key;
 
-        /* Handle removals */
-        for (i = 0; i < manager->priv->keys->len; i++) {
-                gboolean found = FALSE;
-                MediaKey *key = g_ptr_array_index (manager->priv->keys, i);
-                if (key->key_type != CUSTOM_KEY)
-                        continue;
+	g_return_if_fail (entry != NULL);
+	g_return_if_fail (entry->key[0] == '/');
 
-                for (j = 0; j < n_bindings && !found; j++)
-                        found = strcmp (bindings[j], key->custom_path) == 0;
+	/* Look for the dir that changed, thus the MediaKey */
+	key_elems = g_strsplit (entry->key + 1, "/", -1);
+	if (key_elems == NULL ||
+	    (g_strv_length (key_elems) != 4 &&
+	     g_strv_length (key_elems) != 5)) {
+		g_warning ("Unexpected GConf notification for key '%s'", entry->key);
+		g_strfreev (key_elems);
+		return;
+	}
 
-                if (found)
-                        continue;
+	if (g_strv_length (key_elems) == 5 &&
+	    g_str_equal (key_elems[4], "binding") == FALSE &&
+	    g_str_equal (key_elems[4], "action") == FALSE) {
+		g_debug ("Not interested in notification for key '%s'", entry->key);
+		g_strfreev (key_elems);
+		return;
+	}
+	gconf_key = g_strdup_printf ("/%s/%s/%s/%s",
+				     key_elems[0],
+				     key_elems[1],
+				     key_elems[2],
+				     key_elems[3]);
+	g_strfreev (key_elems);
+
+	g_debug ("Got notification for key '%s' (dir: '%s')",
+		 entry->key, gconf_key);
+
+	/* Remove the existing key */
+	for (i = 0; i < manager->priv->keys->len; i++) {
+		key = g_ptr_array_index (manager->priv->keys, i);
 
-                if (key->key) {
-                        gdk_error_trap_push ();
+		if (key->gconf_dir == NULL)
+			continue;
+		if (strcmp (key->gconf_dir, gconf_key) == 0) {
+			if (key->key) {
+				gdk_error_trap_push ();
+
+				grab_key_unsafe (key->key, FALSE, manager->priv->screens);
+
+				gdk_flush ();
+				if (gdk_error_trap_pop ())
+					g_warning ("Ungrab failed for GConf key '%s'", gconf_key);
+			}
+			g_ptr_array_remove_index_fast (manager->priv->keys, i);
+			break;
+		}
+	}
 
-                        grab_key_unsafe (key->key,
-                                         FALSE,
-                                         manager->priv->screens);
-
-                        gdk_flush ();
-                        if (gdk_error_trap_pop ())
-                                g_warning ("Ungrab failed for custom key '%s'", key->custom_path);
-                }
-                g_hash_table_remove (manager->priv->custom_settings,
-                                     key->custom_path);
-                g_ptr_array_remove_index_fast (manager->priv->keys, i);
-                --i; /* make up for the removed key */
-        }
-        g_strfreev (bindings);
+	/* And create a new one! */
+	key = media_key_new_for_gconf (manager, gconf_key);
+	if (key) {
+		g_ptr_array_add (manager->priv->keys, key);
+
+		gdk_error_trap_push ();
+
+		grab_media_key (key, manager);
+
+		gdk_flush ();
+		if (gdk_error_trap_pop ())
+			g_warning ("Grab failed for GConf key '%s'", key->gconf_dir);
+	} else {
+		g_free (gconf_key);
+	}
 }
 
+
 static void
 add_key (GsdMediaKeysManager *manager, guint i)
 {
@@ -749,8 +730,8 @@
 static void
 init_kbd (GsdMediaKeysManager *manager)
 {
-        char **custom_paths;
         int i;
+        GSList *list, *l;
 
         gnome_settings_profile_start (NULL);
 
@@ -770,23 +751,20 @@
         }
 
         /* Custom shortcuts */
-        custom_paths = g_settings_get_strv (manager->priv->settings,
-                                            "custom-keybindings");
-
-        for (i = 0; i < g_strv_length (custom_paths); i++) {
+        list = gconf_client_all_dirs (manager->priv->gconf, GCONF_BINDING_DIR, NULL);
+        for (l = list; l != NULL; l = l->next) {
                 MediaKey *key;
 
-                g_debug ("Setting up custom keybinding %s", custom_paths[i]);
-
-                key = media_key_new_for_path (manager, custom_paths[i]);
+                key = media_key_new_for_gconf (manager, l->data);
                 if (!key) {
+                        g_free (l->data);
                         continue;
                 }
                 g_ptr_array_add (manager->priv->keys, key);
 
                 grab_media_key (key, manager);
         }
-        g_strfreev (custom_paths);
+        g_slist_free (list);
 
         gdk_flush ();
         if (gdk_error_trap_pop ())
@@ -946,7 +924,6 @@
 
         volume_monitor = g_volume_monitor_get ();
 
-
         /* Find the best drive to eject */
         fav_drive = NULL;
         score = NO_SCORE;
@@ -2277,12 +2254,15 @@
         manager->priv->settings = g_settings_new (SETTINGS_BINDING_DIR);
         g_signal_connect (G_OBJECT (manager->priv->settings), "changed",
                           G_CALLBACK (gsettings_changed_cb), manager);
-        g_signal_connect (G_OBJECT (manager->priv->settings), "changed::custom-keybindings",
-                          G_CALLBACK (gsettings_custom_changed_cb), manager);
 
-        manager->priv->custom_settings =
-          g_hash_table_new_full (g_str_hash, g_str_equal,
-                                 g_free, g_object_unref);
+        manager->priv->gconf = gconf_client_get_default ();
+        gconf_client_add_dir (manager->priv->gconf, GCONF_BINDING_DIR, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+        manager->priv->gconf_id = gconf_client_notify_add (manager->priv->gconf,
+                                                           GCONF_BINDING_DIR,
+                                                           (GConfClientNotifyFunc) gconf_changed_cb,
+                                                           manager,
+                                                           NULL,
+                                                           NULL);
 
         /* Sound events */
         ca_context_create (&manager->priv->ca);
@@ -2508,6 +2488,17 @@
                 gdk_error_trap_pop_ignored ();
         }
 
+        if (priv->gconf_id) {
+                gconf_client_remove_dir (priv->gconf, GCONF_BINDING_DIR, NULL);
+                gconf_client_notify_remove (priv->gconf, priv->gconf_id);
+                priv->gconf_id = 0;
+        }
+
+        if (priv->gconf) {
+                g_object_unref (priv->gconf);
+                priv->gconf = NULL;
+        }
+
         if (priv->screens != NULL) {
                 g_slist_free (priv->screens);
                 priv->screens = NULL;
Index: gnome-settings-daemon-3.4.2/plugins/media-keys/test-media-keys.c
===================================================================
--- gnome-settings-daemon-3.4.2.orig/plugins/media-keys/test-media-keys.c	2012-05-15 12:14:49.000000000 +0200
+++ gnome-settings-daemon-3.4.2/plugins/media-keys/test-media-keys.c	2012-05-22 21:09:13.313387323 +0200
@@ -41,8 +41,6 @@
         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
         textdomain (GETTEXT_PACKAGE);
 
-	g_setenv ("G_MESSAGES_DEBUG", "all", TRUE);
-
         error = NULL;
         if (! gtk_init_with_args (&argc, &argv, NULL, NULL, NULL, &error)) {
                 fprintf (stderr, "%s", error->message);
