Index: src/orca/orca.py
===================================================================
--- src/orca/orca.py	(revision 2337)
+++ src/orca/orca.py	(working copy)
@@ -667,13 +667,27 @@
 
     keyboardEvent = KeyboardEvent(event)
 
-    # See if this is one of our special Orca modifiers (e.g., "Insert")
+    # See if this is one of our special Orca modifiers (e.g.,
+    # "Insert"). We can run into situations where there is a different
+    # keysym emitted for the modifier (e.g., KP_Insert ad KP_0 are
+    # bound to the same key), so we also check for all possible
+    # keysyms bound to a key.  [[[TODO: WDW - this can be a bit risky
+    # in the event that a keysym is bound to more than one key.]]]
     #
+    # [[[TODO: WDW - Note that just looking at the keycode should
+    # suffice, but there is a "feature" in the Java Access Bridge
+    # where it chooses to emit Java platform-independent keycodes
+    # instead of the keycodes for the base platform:
+    #
+    # http://bugzilla.gnome.org/show_bug.cgi?id=106004
+    # http://bugzilla.gnome.org/show_bug.cgi?id=318615
+    # ]]]
+    #
     orcaModifierKeys = settings.orcaModifierKeys
-    orcaModifierKeycodes = []
+    allPossibleKeysyms = []
     for keysym in orcaModifierKeys:
-        orcaModifierKeycodes.append(keybindings.getKeycode(keysym))
-    isOrcaModifier = orcaModifierKeycodes.count(keyboardEvent.hw_code) > 0
+        allPossibleKeysyms.extend(keybindings.getAllKeysyms(keysym))
+    isOrcaModifier = allPossibleKeysyms.count(keyboardEvent.event_string) > 0
 
     if event.type == atspi.Accessibility.KEY_PRESSED_EVENT:
         # Key presses always interrupt speech.
Index: src/orca/keybindings.py
===================================================================
--- src/orca/keybindings.py	(revision 2337)
+++ src/orca/keybindings.py	(working copy)
@@ -42,8 +42,53 @@
 
 from orca_i18n import _           # for gettext support
 
+_keysymsCache = {}
 _keycodeCache = {}
 
+def getAllKeysyms(keysym):
+    """Given a keysym, find all other keysyms associated with the key
+    that is mapped to the given keysym.  This allows us, for example,
+    to determine that the key bound to KP_Insert is also bound to KP_0."""
+
+    if not _keysymsCache.has_key(keysym):
+        # The keysym itself is always part of the list.
+        #
+        _keysymsCache[keysym] = [keysym]
+
+        # Find the numerical value of the keysym
+        #
+        keyval = gtk.gdk.keyval_from_name(keysym)
+
+        if keyval != 0:
+            # Find the keycodes for the keysym.  Since a keysym
+            # can be associated with more than one key, we'll shoot
+            # for the keysym that's in group 0, regardless of shift
+            # level (each entry is of the form [keycode, group,
+            # level]).
+            #
+            keymap = gtk.gdk.keymap_get_default()
+            entries = keymap.get_entries_for_keyval(keyval)
+            keycode = 0
+            if entries:
+                for entry in entries:
+                    if entry[1] == 0:  # group = 0
+                        keycode = entry[0]
+                        break
+
+            # Find the keysyms bound to the keycode.  These are what
+            # we are looking for.
+            #
+            if keycode != 0:
+                entries = keymap.get_entries_for_keycode(keycode)
+                if entries:
+                    for entry in entries:
+                        keyval = entry[0]
+                        name = gtk.gdk.keyval_name(keyval)
+                        if name and (name != keysym):
+                            _keysymsCache[keysym].append(name)
+
+    return _keysymsCache[keysym]
+
 def getKeycode(keysym):
     """Converts an XKeysym string (e.g., 'KP_Enter') to a keycode that
     should match the event.hw_code for key events.
