Index: src/orca/scripts/gedit.py
===================================================================
--- src/orca/scripts/gedit.py	(revision 2367)
+++ src/orca/scripts/gedit.py	(working copy)
@@ -509,7 +509,7 @@
         #
         if event.source.role == rolenames.ROLE_STATUSBAR \
            and self.isFocusOnFindDialog() \
-           and orca_state.lastInputEvent.event_string == "Return" \
+           and orca_state.lastNonModifierKeyEvent.event_string == "Return" \
            and event.source.name == _("Phrase not found"):
                 debug.println(self.debugLevel,
                               "gedit.onNameChanged - phrase not found.")
@@ -564,7 +564,7 @@
         # we've just found.
         #
         if self.isFocusOnFindDialog() \
-           and orca_state.lastInputEvent.event_string == "Return":
+           and orca_state.lastNonModifierKeyEvent.event_string == "Return":
             debug.println(self.debugLevel, "gedit.onCaretMoved - find dialog.")
 
             allComboBoxes = self.findByRole(orca_state.locusOfFocus.app,
Index: src/orca/scripts/gcalctool.py
===================================================================
--- src/orca/scripts/gcalctool.py	(revision 2367)
+++ src/orca/scripts/gcalctool.py	(working copy)
@@ -159,7 +159,7 @@
                                    input_event.KeyboardEvent)):
                 return
 
-            if (orca_state.lastInputEvent.event_string == "space") \
-                   or (orca_state.lastInputEvent.event_string == "Return") \
-                   or (orca_state.lastInputEvent.event_string == "="):
+            if (orca_state.lastNonModifierKeyEvent.event_string == "space") \
+                   or (orca_state.lastNonModifierKeyEvent.event_string == "Return") \
+                   or (orca_state.lastNonModifierKeyEvent.event_string == "="):
                 speech.speak(contents)
Index: src/orca/scripts/gnome-terminal.py
===================================================================
--- src/orca/scripts/gnome-terminal.py	(revision 2367)
+++ src/orca/scripts/gnome-terminal.py	(working copy)
@@ -82,7 +82,7 @@
         if orca_state.lastInputEvent \
                and isinstance(orca_state.lastInputEvent,
                               input_event.KeyboardEvent):
-            event_string = orca_state.lastInputEvent.event_string
+            event_string = orca_state.lastNonModifierKeyEvent.event_string
         else:
             event_string = None
 
@@ -152,7 +152,7 @@
         matchFound = False
         speakThis = False
         if isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent):
-            keyString = orca_state.lastInputEvent.event_string
+            keyString = orca_state.lastNonModifierKeyEvent.event_string
 
             controlPressed = orca_state.lastInputEvent.modifiers \
                              & (1 << atspi.Accessibility.MODIFIER_CONTROL)
Index: src/orca/scripts/acroread.py
===================================================================
--- src/orca/scripts/acroread.py	(revision 2367)
+++ src/orca/scripts/acroread.py	(working copy)
@@ -372,7 +372,7 @@
             debug.println(self.debugLevel, "acroread: Drawing area bug")
             lastKey = None
             try:
-                lastKey = orca_state.lastInputEvent.event_string
+                lastKey = orca_state.lastNonModifierKeyEvent.event_string
             except:
                 pass
             LOFIndex = orca_state.locusOfFocus.index
@@ -628,7 +628,7 @@
         else:
             text = obj.text
             offset = text.caretOffset
-            lastKey = orca_state.lastInputEvent.event_string
+            lastKey = orca_state.lastNonModifierKeyEvent.event_string
 
             if lastKey == "Right":
                 penultimateWord = orca_state.lastWord
Index: src/orca/scripts/Evolution.py
===================================================================
--- src/orca/scripts/Evolution.py	(revision 2367)
+++ src/orca/scripts/Evolution.py	(working copy)
@@ -683,7 +683,7 @@
             justDeleted = False
             if isinstance(orca_state.lastInputEvent,
                           input_event.KeyboardEvent):
-                string = orca_state.lastInputEvent.event_string
+                string = orca_state.lastNonModifierKeyEvent.event_string
                 if string == "Delete":
                     justDeleted = True
 
@@ -1248,7 +1248,7 @@
                 orca_state.lastInputEvent.__dict__.has_key("event_string")):
             return False
 
-        lastKey = orca_state.lastInputEvent.event_string
+        lastKey = orca_state.lastNonModifierKeyEvent.event_string
         if lastKey != "Left" and lastKey != "Right":
             return False
 
@@ -1382,7 +1382,7 @@
         # 
         if isinstance(orca_state.lastInputEvent,
                       input_event.KeyboardEvent):
-            string = orca_state.lastInputEvent.event_string
+            string = orca_state.lastNonModifierKeyEvent.event_string
             if string == "Delete":
                 rolesList = [rolenames.ROLE_TABLE_CELL, \
                              rolenames.ROLE_TREE_TABLE, \
Index: src/orca/scripts/StarOffice.py
===================================================================
--- src/orca/scripts/StarOffice.py	(revision 2367)
+++ src/orca/scripts/StarOffice.py	(working copy)
@@ -1900,7 +1900,7 @@
                 weToggledIt = event.source.component.contains(x, y, 0)
 
             elif isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent):
-                keyString = orca_state.lastInputEvent.event_string
+                keyString = orca_state.lastNonModifierKeyEvent.event_string
                 navKeys = ["Up", "Down", "Page_Up", "Page_Down", "Home", "End"]
                 wasCommand = orca_state.lastInputEvent.modifiers \
                              & (1 << atspi.Accessibility.MODIFIER_CONTROL \
@@ -1931,7 +1931,7 @@
             #
             event_string = None
             if isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent):
-                event_string = orca_state.lastInputEvent.event_string
+                event_string = orca_state.lastNonModifierKeyEvent.event_string
             if (event_string == "Up" or event_string == "Down") and \
                event.source.parent == self.lastCell and \
                event.source.parent.childCount > 1:
@@ -2091,7 +2091,7 @@
         if event.source.role == rolenames.ROLE_PARAGRAPH and \
            event.source.parent.role == rolenames.ROLE_TABLE_CELL and \
            event.source.state.count(atspi.Accessibility.STATE_FOCUSED):
-            event_string = orca_state.lastInputEvent.event_string
+            event_string = orca_state.lastNonModifierKeyEvent.event_string
 
             # If we are moving up and down, and we are speaking-by-cell
             # (as opposed to by-row), then speak the cell name. Otherwise
@@ -2178,7 +2178,7 @@
                 orca_state.lastInputEvent.__dict__.has_key("event_string")):
             return False
 
-        lastKey = orca_state.lastInputEvent.event_string
+        lastKey = orca_state.lastNonModifierKeyEvent.event_string
         if lastKey != "Left" and lastKey != "Right":
             return False
 
Index: src/orca/orca.py
===================================================================
--- src/orca/orca.py	(revision 2367)
+++ src/orca/orca.py	(working copy)
@@ -763,6 +763,14 @@
 
     orca_state.lastInputEvent = keyboardEvent
 
+    # If this is a key event for a non-modifier key, save a handle to it.
+    # This is needed to help determine user actions when a multi-key chord 
+    # has been pressed, and we might get the key events in different orders.
+    # See comment #15 of bug #435201 for more details.
+    #
+    if not _isModifierKey(keyboardEvent.event_string):
+        orca_state.lastNonModifierKeyEvent = keyboardEvent
+
     return consumed or isOrcaModifier
 
 ########################################################################
Index: src/orca/default.py
===================================================================
--- src/orca/default.py	(revision 2367)
+++ src/orca/default.py	(working copy)
@@ -1545,7 +1545,7 @@
 
         text = obj.text
         offset = text.caretOffset
-        lastKey = orca_state.lastInputEvent.event_string
+        lastKey = orca_state.lastNonModifierKeyEvent.event_string
         lastWord = orca_state.lastWord
 
         [word, startOffset, endOffset] = \
@@ -1720,7 +1720,7 @@
         mods = orca_state.lastInputEvent.modifiers
         shiftMask = 1 << atspi.Accessibility.MODIFIER_SHIFT
         if (mods & shiftMask) \
-            and orca_state.lastInputEvent.event_string == "Right":
+            and orca_state.lastNonModifierKeyEvent.event_string == "Right":
             startOffset = offset-1
             endOffset = offset
         else:
@@ -1744,14 +1744,14 @@
             (prevChar, character, startOffset, offset, endOffset, settings.speakBlankLines))
 
         # Handle speaking newlines when the right-arrow key is pressed.
-        if orca_state.lastInputEvent.event_string == "Right":
+        if orca_state.lastNonModifierKeyEvent.event_string == "Right":
             if prevChar == "\n":
                 # The cursor is at the beginning of a line.
                 # Speak a newline.
                 speech.speak(chnames.getCharacterName("\n"), voice, False)
 
         # Handle speaking newlines when the left-arrow key is pressed.
-        elif orca_state.lastInputEvent.event_string == "Left":
+        elif orca_state.lastNonModifierKeyEvent.event_string == "Left":
             if character == "\n":
                 # The cursor is at the end of a line.
                 # Speak a newline.
@@ -2359,7 +2359,7 @@
                           input_event.KeyboardEvent):
             return
 
-        string = orca_state.lastInputEvent.event_string
+        string = orca_state.lastNonModifierKeyEvent.event_string
         mods = orca_state.lastInputEvent.modifiers
         isControlKey = mods & (1 << atspi.Accessibility.MODIFIER_CONTROL)
         isShiftKey = mods & (1 << atspi.Accessibility.MODIFIER_SHIFT)
@@ -2525,7 +2525,7 @@
                             input_event.KeyboardEvent)):
             return
 
-        string = orca_state.lastInputEvent.event_string
+        string = orca_state.lastNonModifierKeyEvent.event_string
         text = event.source.text
         if string == "BackSpace":
             # Speak the character that has just been deleted.
@@ -2615,7 +2615,7 @@
         #
         speakThis = False
         if isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent):
-            keyString = orca_state.lastInputEvent.event_string
+            keyString = orca_state.lastNonModifierKeyEvent.event_string
             wasAutoComplete = (event.source.role == rolenames.ROLE_TEXT and \
                                event.source.text.getNSelections())
             wasCommand = orca_state.lastInputEvent.modifiers \
@@ -2752,7 +2752,7 @@
                 elif orca_state.locusOfFocus \
                     and isinstance(orca_state.lastInputEvent,
                                    input_event.KeyboardEvent) \
-                    and (orca_state.lastInputEvent.event_string == "F1"):
+                    and (orca_state.lastNonModifierKeyEvent.event_string == "F1"):
                     self.updateBraille(orca_state.locusOfFocus)
                     speech.speakUtterances(self.speechGenerator.getSpeech(
                         orca_state.locusOfFocus,
@@ -5377,7 +5377,7 @@
         # Control-Shift-End:  speak "document selected from cursor position".
         #
         if isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent):
-            eventStr = orca_state.lastInputEvent.event_string
+            eventStr = orca_state.lastNonModifierKeyEvent.event_string
             mods = orca_state.lastInputEvent.modifiers
         else:
             eventStr = None
Index: src/orca/focus_tracking_presenter.py
===================================================================
--- src/orca/focus_tracking_presenter.py	(revision 2367)
+++ src/orca/focus_tracking_presenter.py	(working copy)
@@ -424,7 +424,7 @@
                 #
                 if isinstance(orca_state.lastInputEvent, \
                               input_event.KeyboardEvent):
-                    if not orca_state.lastInputEvent.event_string == "F1":
+                    if not orca_state.lastNonModifierKeyEvent.event_string == "F1":
                         return
 
                     # Mouse move events don't update orca_state.lastInputEvent
Index: src/orca/Gecko.py
===================================================================
--- src/orca/Gecko.py	(revision 2367)
+++ src/orca/Gecko.py	(working copy)
@@ -2209,7 +2209,7 @@
         #
         if isinstance(orca_state.lastInputEvent,
                       input_event.KeyboardEvent):
-            string = orca_state.lastInputEvent.event_string
+            string = orca_state.lastNonModifierKeyEvent.event_string
             mods = orca_state.lastInputEvent.modifiers
             if (string == "Left") or (string == "Right"):
                 [obj, characterOffset] = self.caretContext
Index: src/orca/orca_state.py
===================================================================
--- src/orca/orca_state.py	(revision 2367)
+++ src/orca/orca_state.py	(working copy)
@@ -52,6 +52,10 @@
 capturingKeys   = False
 lastCapturedKey = None
 
+# The last non-modifier key event received.
+#
+lastNonModifierKeyEvent = None
+
 # The InputEvent instance representing the last input event.  This is
 # set each time a mouse, keyboard or braille event is received.
 #
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 2367)
+++ ChangeLog	(working copy)
@@ -1,3 +1,26 @@
+2007-05-10  Rich Burridge <rich.burridge@sun.com>
+
+        * src/orca/scripts/gedit.py:
+          src/orca/scripts/gcalctool.py:
+          src/orca/scripts/gnome-terminal.py:
+          src/orca/scripts/acroread.py:
+          src/orca/scripts/Evolution.py:
+          src/orca/scripts/StarOffice.py:
+          src/orca/orca.py:
+          src/orca/default.py:
+          src/orca/focus_tracking_presenter.py:
+          src/orca/Gecko.py:
+          src/orca/orca_state.py:
+          Hopefully fixed the "no speech" problem related to bug #435201, 
+          because we were getting the key events in a different order. 
+          We now save a handle to the last non-modifier key event in
+          orca_state.lastNonModifierKeyEvent, and use that in
+          _presentTextAtNewCaretPosition() to check what type of modified
+          key event we currently have.
+
+          Note that there were numerous other places where a similar
+          problem could have existed.
+
 2007-05-09  Joanmarie Diggs <j-diggs@comcast.net>
 
         * src/orca/Gecko.py: More work on bug #423427 – Need to add
