--- a/src/games-controls.c
+++ b/src/games-controls.c
@@ -25,8 +25,12 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#include "gnibbles.h"
 #include "games-controls.h"
 
+extern GSettings *worm_settings[NUMWORMS];
+extern GtkWidget *window;
+
 enum {
   CONFKEY_COLUMN = 0,
   LABEL_COLUMN,
@@ -61,6 +65,8 @@
   GtkTreePath *path;
   GtkTreeIter iter;
   char *conf_key = NULL;
+  gboolean valid = TRUE;
+  int i = 0;
 
   path = gtk_tree_path_new_from_string (path_string);
   if (!path)
@@ -78,9 +84,38 @@
   if (!conf_key)
     return;
 
+  if (g_settings_get_int (list->priv->settings, conf_key) == keyval) {
+    g_free (conf_key);
+    return;
+  }
+
+  /* Duplicate key check */
+  for (i = 0; i < NUMWORMS; i++) {
+    if (g_settings_get_int (worm_settings[i], "key-up") == keyval ||
+        g_settings_get_int (worm_settings[i], "key-down") == keyval ||
+        g_settings_get_int (worm_settings[i], "key-left") == keyval ||
+        g_settings_get_int (worm_settings[i], "key-right") == keyval) {
+      valid = FALSE;
+      
+      GtkWidget *dialog;
+
+      dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW(window),
+      GTK_DIALOG_DESTROY_WITH_PARENT,
+      GTK_MESSAGE_WARNING,
+      GTK_BUTTONS_OK,
+      "<span weight=\"bold\" size=\"larger\">%s</span>",
+      _("The shortcut you selected is already assigned."));
+
+      gtk_dialog_run (GTK_DIALOG(dialog));
+      gtk_widget_destroy (dialog);
+      break;
+    }
+  }
+
   /* Note: the model is updated in the conf notification callback */
   /* FIXME: what to do with the modifiers? */
-  g_settings_set_int (list->priv->settings, conf_key, keyval);
+  if (valid)
+    g_settings_set_int (list->priv->settings, conf_key, keyval);
   g_free (conf_key);
 }
 
