diff --git a/src/orca/scripts/apps/Thunderbird/script.py b/src/orca/scripts/apps/Thunderbird/script.py
index c8e2ec6..2086ad3 100644
--- a/src/orca/scripts/apps/Thunderbird/script.py
+++ b/src/orca/scripts/apps/Thunderbird/script.py
@@ -619,6 +619,17 @@ class Script(Gecko.Script):
             self.sayAll(None)
         self._messageLoaded = False
 
+    def sayCharacter(self, obj):
+        """Speaks the character at the current caret position."""
+
+        if self.isEditableMessage(obj):
+            text = self.utilities.queryNonEmptyText(obj)
+            if text and text.caretOffset + 1 >= text.characterCount:
+                default.Script.sayCharacter(self, obj)
+                return
+
+        Gecko.Script.sayCharacter(self, obj)
+
     def getBottomOfFile(self):
         """Returns the object and last caret offset at the bottom of the
         document frame. Overridden here to handle editable messages.
diff --git a/src/orca/scripts/apps/Thunderbird/speech_generator.py b/src/orca/scripts/apps/Thunderbird/speech_generator.py
index 13f7b59..ba6839f 100644
--- a/src/orca/scripts/apps/Thunderbird/speech_generator.py
+++ b/src/orca/scripts/apps/Thunderbird/speech_generator.py
@@ -47,6 +47,18 @@ class SpeechGenerator(Gecko.SpeechGenerator):
     def __init__(self, script):
         Gecko.SpeechGenerator.__init__(self, script)
 
+    def _generateName(self, obj, **args):
+        """Returns an array of strings for use by speech and braille that
+        represent the name of the object. Overridden here because we do
+        not always want to treat displayed text as the name."""
+
+        result = []
+        if not self._script.isEditableMessage(obj):
+            result.extend(Gecko.SpeechGenerator._generateName(
+                    self, obj, **args))
+
+        return result
+
     def _generateRoleName(self, obj, **args):
         """Prevents some roles from being spoken."""
         result = []
