diff --git a/data/keyboards/geometry/compact.xml b/data/keyboards/geometry/compact.xml
index 128e047c..f8dc5afe 100644
--- a/data/keyboards/geometry/compact.xml
+++ b/data/keyboards/geometry/compact.xml
@@ -3,51 +3,51 @@
   
   
     
-      
-      
-      
-      
-      
-      
-      
-      
-      
-      
+      
+      
+      
+      
+      
+      
+      
+      
+      
+      
     
   
   
     
-      
-      
-      
-      
-      
-      
-      
-      
-      
+      
+      
+      
+      
+      
+      
+      
+      
+      
     
   
   
     
-      
-      
-      
-      
-      
-      
-      
-      
-      
+      
+      
+      
+      
+      
+      
+      
+      
+      
     
   
   
   
diff --git a/data/keyboards/symbols/us.xml b/data/keyboards/symbols/us.xml
index db6ef5f1..66d8f0ba 100644
--- a/data/keyboards/symbols/us.xml
+++ b/data/keyboards/symbols/us.xml
@@ -1,276 +1,180 @@
 
 
-  
-    Escape
-  
-  
-    F1
-  
-  
-    F2
-  
-  
-    F3
-  
-  
-    F4
-  
-  
-    F5
-  
-  
-    F6
-  
-  
-    F7
-  
-  
-    F8
-  
-  
-    F9
-  
-  
-    F10
-  
-  
-    F11
-  
-  
-    F12
-  
-  
-    backspace
-  
-  
-    Tab
-    ISO_Left_Tab
-  
-  
+  
     q
     Q
     1
     asciitilde
   
-  
+  
     w
     W
     2
     quoteleft
   
-  
+  
     e
     E
     3
     bar
   
-  
+  
     r
     R
     4
     middledot
   
-  
+  
     t
     T
     5
   
-  
+  
     y
     Y
     6
   
-  
+  
     u
     U
     7
   
-  
+  
     i
     I
     8
   
-  
+  
     o
     O
     9
   
-  
+  
     p
     P
     0
   
-  
-    bracketleft
-    braceleft
-  
-  
-    bracketright
-    braceright
-  
-  
-    backslash
-    bar
-  
-  
-    show-numbers
-    show-numbers
-    show-letters
-    show-letters
-  
-  
+  
     a
     A
     at
     copyright
   
-  
+  
     s
     S
     numbersign
     registeredtrademark
   
-  
+  
     d
     D
     dollar
     poundsign
   
-  
+  
     f
     F
     percent
     €
   
-  
+  
     g
     G
     ampersand
     yensign
   
-  
+  
     h
     H
     minus
     asciicircum
   
-  
+  
     j
     J
     plus
     degreesign
   
-  
+  
     k
     K
     parenleft
     braceleft
   
-  
+  
     l
     L
     parenright
     braceright
   
-  
-    semicolon
-    colon
-  
-  
-    quoteright
-    quotedbl
-  
-  
+  
     Return
   
-  
+  
     Shift_L
     Shift_L
     Shift_L
     Shift_L
   
-  
+  
     z
     Z
     comma
     backslash
   
-  
+  
     x
     X
     quotedbl
     slash
   
-  
+  
     c
     C
     quoteright
     less
   
-  
+  
     v
     V
     colon
     greater
   
-  
+  
     b
     B
     semicolon
     equal
   
-  
+  
     n
     N
     exclam
     bracketleft
   
-  
+  
     m
     M
     question
     bracketright
   
-  
-    comma
-    less
-  
-  
+  
     period
   
-  
-    slash
-    question
+  
+    show-numbers
+    show-numbers
+    show-letters
+    show-letters
   
-  
-    Shift_R
-  
-  
-    cycle-keyboard
-  
-  
+  
     preferences
   
-  
-    Control_L
-  
-  
-    Alt_L
-    Meta_L
-  
-  
+  
     space
   
-  
-    Left
-  
-  
-    Up
-  
-  
-    Down
-  
-  
-    Right
+  
+    backspace
   
 
diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c
index dfe03662..4a7229c0 100644
--- a/eek/eek-keyboard.c
+++ b/eek/eek-keyboard.c
@@ -74,7 +74,7 @@ struct _EekKeyboardPrivate
     GList *pressed_keys;
     GList *locked_keys;
     GArray *outline_array;
-    GHashTable *keycodes;
+    GHashTable *names;
 
     /* modifiers dynamically assigned at run time */
     EekModifierType num_lock_mask;
@@ -129,9 +129,9 @@ section_child_added_cb (EekContainer *container,
                         EekElement   *element,
                         EekKeyboard  *keyboard)
 {
-    guint keycode = eek_key_get_keycode (EEK_KEY(element));
-    g_hash_table_insert (keyboard->priv->keycodes,
-                         GUINT_TO_POINTER(keycode),
+    const gchar *name = eek_element_get_name(element);
+    g_hash_table_insert (keyboard->priv->names,
+                         (gpointer)name,
                          element);
 }
 
@@ -140,9 +140,9 @@ section_child_removed_cb (EekContainer *container,
                           EekElement   *element,
                           EekKeyboard  *keyboard)
 {
-    guint keycode = eek_key_get_keycode (EEK_KEY(element));
-    g_hash_table_remove (keyboard->priv->keycodes,
-                         GUINT_TO_POINTER(keycode));
+    const gchar *name = eek_element_get_name(element);
+    g_hash_table_remove (keyboard->priv->names,
+                         name);
 }
 
 static EekSection *
@@ -221,7 +221,7 @@ set_level_from_modifiers (EekKeyboard *self, EekKey *key)
     gint level = priv->old_level & 2;
 
     /* Handle non-emitting keys */
-    if (key && (eek_key_get_keycode(key) == 0)) {
+    if (key) {
         const gchar *name = eek_element_get_name(EEK_ELEMENT(key));
         if (g_strcmp0(name, "ABC123") == 0)
             level ^= 2;
@@ -400,7 +400,7 @@ eek_keyboard_finalize (GObject *object)
     g_list_free_full (priv->locked_keys,
                       (GDestroyNotify) eek_modifier_key_free);
 
-    g_hash_table_destroy (priv->keycodes);
+    g_hash_table_destroy (priv->names);
 
     for (i = 0; i < priv->outline_array->len; i++) {
         EekOutline *outline = &g_array_index (priv->outline_array,
@@ -528,7 +528,7 @@ eek_keyboard_init (EekKeyboard *self)
     self->priv = EEK_KEYBOARD_GET_PRIVATE(self);
     self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE;
     self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline));
-    self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal);
+    self->priv->names = g_hash_table_new (g_str_hash, g_str_equal);
     eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0);
 }
 
@@ -548,20 +548,20 @@ eek_keyboard_create_section (EekKeyboard *keyboard)
 }
 
 /**
- * eek_keyboard_find_key_by_keycode:
+ * eek_keyboard_find_key_by_name:
  * @keyboard: an #EekKeyboard
- * @keycode: a keycode
+ * @name: a key name
  *
- * Find an #EekKey whose keycode is @keycode.
- * Return value: (transfer none): #EekKey whose keycode is @keycode
+ * Find an #EekKey whose name is @name.
+ * Return value: (transfer none): #EekKey whose name is @name
  */
 EekKey *
-eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard,
-                                  guint        keycode)
+eek_keyboard_find_key_by_name (EekKeyboard *keyboard,
+                               const gchar *name)
 {
     g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL);
-    return g_hash_table_lookup (keyboard->priv->keycodes,
-                                GUINT_TO_POINTER(keycode));
+    return g_hash_table_lookup (keyboard->priv->names,
+                                name);
 }
 
 /**
diff --git a/eek/eek-keyboard.h b/eek/eek-keyboard.h
index afe72c27..9091282e 100644
--- a/eek/eek-keyboard.h
+++ b/eek/eek-keyboard.h
@@ -69,8 +69,8 @@ struct _EekKeyboard
 /**
  * EekKeyboardClass:
  * @create_section: virtual function for creating a section
- * @find_key_by_keycode: virtual function for finding a key in the
- * keyboard by keycode
+ * @find_key_by_name: virtual function for finding a key in the
+ * keyboard by name
  * @key_pressed: class handler for #EekKeyboard::key-pressed signal
  * @key_released: class handler for #EekKeyboard::key-released signal
  * @key_locked: class handler for #EekKeyboard::key-locked signal
@@ -89,8 +89,8 @@ struct _EekKeyboardClass
     /*< public >*/
     EekSection *(* create_section)      (EekKeyboard *self);
 
-    EekKey     *(* find_key_by_keycode) (EekKeyboard *self,
-                                         guint        keycode);
+    EekKey     *(* find_key_by_name)    (EekKeyboard *self,
+                                         const gchar *name);
 
     /*< private >*/
     /* obsolete members moved to EekElement */
@@ -155,9 +155,9 @@ EekModifierType     eek_keyboard_get_modifiers
 EekSection         *eek_keyboard_create_section
                                      (EekKeyboard        *keyboard);
 
-EekKey             *eek_keyboard_find_key_by_keycode
+EekKey             *eek_keyboard_find_key_by_name
                                      (EekKeyboard        *keyboard,
-                                      guint               keycode);
+                                      const gchar        *name);
 
 guint               eek_keyboard_add_outline
                                      (EekKeyboard        *keyboard,
diff --git a/eek/eek-section.c b/eek/eek-section.c
index 5a04619c..4743bfed 100644
--- a/eek/eek-section.c
+++ b/eek/eek-section.c
@@ -124,7 +124,8 @@ on_unlocked (EekKey     *key,
 
 static EekKey *
 eek_section_real_create_key (EekSection *self,
-                             guint       keycode,
+                             const gchar *name,
+                             gint        keycode,
                              gint        column_index,
                              gint        row_index)
 {
@@ -142,6 +143,7 @@ eek_section_real_create_key (EekSection *self,
         row->num_columns = column_index + 1;
 
     key = g_object_new (EEK_TYPE_KEY,
+                        "name", name,
                         "keycode", keycode,
                         "column", column_index,
                         "row", row_index,
@@ -463,6 +465,7 @@ eek_section_get_row (EekSection     *section,
 /**
  * eek_section_create_key:
  * @section: an #EekSection
+ * @name: a name
  * @keycode: a keycode
  * @column: the column index of the key
  * @row: the row index of the key
@@ -473,12 +476,14 @@ eek_section_get_row (EekSection     *section,
  */
 EekKey *
 eek_section_create_key (EekSection *section,
-                        guint       keycode,
+                        const gchar *name,
+                        gint        keycode,
                         gint        column,
                         gint        row)
 {
     g_return_val_if_fail (EEK_IS_SECTION(section), NULL);
     return EEK_SECTION_GET_CLASS(section)->create_key (section,
+                                                       name,
                                                        keycode,
                                                        column,
                                                        row);
diff --git a/eek/eek-section.h b/eek/eek-section.h
index f4335ade..50baac80 100644
--- a/eek/eek-section.h
+++ b/eek/eek-section.h
@@ -62,7 +62,8 @@ struct _EekSectionClass
                                      EekOrientation *orientation);
 
     EekKey *(* create_key)          (EekSection     *self,
-                                     guint           keycode,
+                                     const gchar    *name,
+                                     gint            keycode,
                                      gint            row,
                                      gint            column);
 
@@ -99,7 +100,8 @@ void    eek_section_get_row              (EekSection     *section,
                                           EekOrientation *orientation);
 
 EekKey *eek_section_create_key           (EekSection     *section,
-                                          guint           keycode,
+                                          const gchar    *name,
+                                          gint            keycode,
                                           gint            column,
                                           gint            row);
 
diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c
index 158b58bf..0c4edc8a 100644
--- a/eek/eek-xml-layout.c
+++ b/eek/eek-xml-layout.c
@@ -249,6 +249,7 @@ struct _GeometryParseData {
     gchar *name;
     EekOutline outline;
     gchar *oref;
+    gint keycode;
 
     GHashTable *key_oref_hash;
     GHashTable *oref_outline_hash;
@@ -271,6 +272,7 @@ geometry_parse_data_new (EekKeyboard *keyboard)
                                g_str_equal,
                                g_free,
                                (GDestroyNotify)eek_outline_free);
+    data->keycode = 1;
     return data;
 }
 
@@ -396,29 +398,23 @@ geometry_start_element_callback (GMarkupParseContext *pcontext,
     }
 
     if (g_strcmp0 (element_name, "key") == 0) {
-        guint keycode;
 
         attribute = get_attribute (attribute_names, attribute_values,
-                                   "keycode");
+                                   "name");
         if (attribute == NULL) {
             g_set_error (error,
                          G_MARKUP_ERROR,
                          G_MARKUP_ERROR_MISSING_ATTRIBUTE,
-                         "no \"keycode\" attribute for \"key\"");
+                         "no \"name\" attribute for \"key\"");
             return;
         }
-        keycode = strtoul (attribute, NULL, 10);
 
         data->key = eek_section_create_key (data->section,
-                                            keycode,
+                                            g_strdup (attribute),
+                                            data->keycode++,
                                             data->num_columns,
                                             data->num_rows - 1);
 
-        attribute = get_attribute (attribute_names, attribute_values,
-                                   "name");
-        if (attribute != NULL)
-            eek_element_set_name (EEK_ELEMENT(data->key), attribute);
-
         attribute = get_attribute (attribute_names, attribute_values,
                                    "oref");
         if (attribute == NULL) {
@@ -622,28 +618,25 @@ symbols_start_element_callback (GMarkupParseContext *pcontext,
         return;
 
     if (g_strcmp0 (element_name, "key") == 0) {
-        guint keycode;
 
         attribute = get_attribute (attribute_names, attribute_values,
-                                   "keycode");
+                                   "name");
         if (attribute == NULL) {
             g_set_error (error,
                          G_MARKUP_ERROR,
                          G_MARKUP_ERROR_MISSING_ATTRIBUTE,
-                         "no \"keycode\" attribute for \"key\"");
+                         "no \"name\" attribute for \"key\"");
             return;
         }
-        keycode = strtoul (attribute, NULL, 10);
 
-        data->key = eek_keyboard_find_key_by_keycode (data->keyboard,
-                                                      keycode);
-        /*if (data->key == NULL) {
+        data->key = eek_keyboard_find_key_by_name (data->keyboard,
+                                                   attribute);
+        if (data->key == NULL) {
             g_set_error (error,
                          G_MARKUP_ERROR,
                          G_MARKUP_ERROR_INVALID_CONTENT,
-                         "no such keycode %u", keycode);
-            return;
-        }*/
+                         "no such key %s", attribute);
+        }
 
         attribute = get_attribute (attribute_names, attribute_values,
                                    "groups");