Index: src/orca/scripts/Evolution.py
===================================================================
--- src/orca/scripts/Evolution.py	(revision 3434)
+++ src/orca/scripts/Evolution.py	(working copy)
@@ -673,6 +673,27 @@
             obj.queryText().setCaretOffset(context.currentOffset)
             orca.setLocusOfFocus(None, obj, False)
 
+    def presentMessageLine(self, obj, newLocusOfFocus):
+        """Speak/braille the line at the current text caret offset.
+        """
+
+        [string, caretOffset, startOffset] = self.getTextLineAtCaret(obj)
+        self.updateBraille(newLocusOfFocus)
+        if settings.enableSpeechIndentation:
+            self.speakTextIndentation(obj, string)
+        line = self.adjustForRepeats(string)
+
+        if self.speakNewLine(obj):
+            speech.speak(chnames.getCharacterName("\n"), None, False)
+
+        if self.speakBlankLine(obj):
+            # Translators: "blank" is a short word to mean the
+            # user has navigated to an empty line.
+            #
+            speech.speak(_("blank"), None, False)
+        else:
+            speech.speak(line, None, False)
+
     def sayAll(self, inputEvent):
         """Speak all the text associated with the text object that has
            focus. We have to define our own method here because Evolution
@@ -749,31 +770,18 @@
 
         rolesList = [pyatspi.ROLE_TEXT, \
                      pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_UNKNOWN]
+                     pyatspi.ROLE_UNKNOWN, \
+                     pyatspi.ROLE_PANEL, \
+                     pyatspi.ROLE_SCROLL_PANE, \
+                     pyatspi.ROLE_FILLER, \
+                     pyatspi.ROLE_SPLIT_PANE]
         if self.isDesiredFocusedItem(event.source, rolesList):
             debug.println(self.debugLevel,
                           "evolution.locusOfFocusChanged - mail view: " \
                           + "current message pane: " \
                           + "individual lines of text.")
 
-            [string, caretOffset, startOffset] = \
-                self.getTextLineAtCaret(event.source)
-            self.updateBraille(newLocusOfFocus)
-            if settings.enableSpeechIndentation:
-                self.speakTextIndentation(event.source, string)
-            line = self.adjustForRepeats(string)
-
-            if self.speakNewLine(event.source):
-                speech.speak(chnames.getCharacterName("\n"), None, False)
-
-            if self.speakBlankLine(event.source):
-                # Translators: "blank" is a short word to mean the
-                # user has navigated to an empty line.
-                #
-                speech.speak(_("blank"), None, False)
-            else:
-                speech.speak(line, None, False)
-
+            self.presentMessageLine(event.source, newLocusOfFocus)
             return
 
 
@@ -1276,26 +1284,36 @@
 
         rolesList = [pyatspi.ROLE_TEXT, \
                      pyatspi.ROLE_PANEL, \
+                     pyatspi.ROLE_UNKNOWN, \
                      pyatspi.ROLE_PANEL, \
-                     pyatspi.ROLE_SCROLL_PANE]
+                     pyatspi.ROLE_SCROLL_PANE, \
+                     pyatspi.ROLE_FILLER, \
+                     pyatspi.ROLE_PANEL]
         if self.isDesiredFocusedItem(event.source, rolesList):
             debug.println(self.debugLevel,
                           "evolution.locusOfFocusChanged - mail " \
                           + "compose window: message area.")
 
+            # We are getting extra (bogus?) "focus:" events from Evolution
+            # when we type the first character at the beginning of a line.
+            # If the last input event was a keyboard event and the parent
+            # of the locusOfFocus and the event.source are the same, and 
+            # the last key pressed wasn't a navigation key, then just 
+            # ignore it. See bug #490317 for more details.
+            #
+            if isinstance(orca_state.lastInputEvent, input_event.KeyboardEvent):
+                if self.isSameObject(event.source.parent,
+                                     orca_state.locusOfFocus.parent):
+                    lastKey = orca_state.lastNonModifierKeyEvent.event_string
+                    if lastKey not in \
+                           ["Left", "Right", "Up", "Down", "Home", "End"]:
+                        return
+
             self.message_panel = event.source.parent.parent
 
-            if self.speakNewLine(event.source):
-                speech.speak(chnames.getCharacterName("\n"), None, False)
+            self.presentMessageLine(event.source, newLocusOfFocus)
+            return
 
-
-            if self.speakBlankLine(event.source):
-                # Translators: "blank" is a short word to mean the
-                # user has navigated to an empty line.
-                #
-                speech.speak(_("blank"), None, False)
-
-
         # 9) Spell Checking Dialog
         #
         # This works in conjunction with code in section 8). Check to see if
