[orca] Fix for bgo#592634 - The Gecko script's handling of caret navigation interferes when navigating edit



commit c0fff2e73951d691f649d1fa79d15bfead9f914b
Author: Joanmarie Diggs <joanmarie diggs gmail com>
Date:   Sun Aug 30 02:11:07 2009 -0400

    Fix for bgo#592634 - The Gecko script's handling of caret navigation interferes when navigating editable messages in Thunderbird

 src/orca/scripts/apps/Thunderbird/script.py        |   32 ++++++++++++++++++++
 .../scripts/apps/Thunderbird/speech_generator.py   |   13 ++++++++
 src/orca/scripts/toolkits/Gecko/script.py          |   10 ++++--
 3 files changed, 51 insertions(+), 4 deletions(-)
---
diff --git a/src/orca/scripts/apps/Thunderbird/script.py b/src/orca/scripts/apps/Thunderbird/script.py
index 2364f08..db04247 100644
--- a/src/orca/scripts/apps/Thunderbird/script.py
+++ b/src/orca/scripts/apps/Thunderbird/script.py
@@ -163,6 +163,16 @@ class Script(Gecko.Script):
         - event: the Event
         """
 
+        # Much of the Gecko code is designed to handle Gecko's broken
+        # caret navigation. This is not needed in -- and can sometimes
+        # interfere with our presentation of -- a simple message being
+        # composed by the user. Surely we can count on Thunderbird to
+        # handle navigation in that case.
+        # 
+        if self.isEditableMessage(event.source):
+            self.setCaretContext(event.source, event.detail1)
+            return default.Script.onCaretMoved(self, event)
+
         # Page_Up/Page_Down are not used by Orca. However, users report
         # using these keys in Thunderbird without success. The default
         # script is sometimes rejecting the resulting caret-moved events
@@ -622,3 +632,25 @@ class Script(Gecko.Script):
             pyatspi.clearCache()
 
         return default.Script.toggleFlatReviewMode(self, inputEvent)
+
+    def isEditableMessage(self, obj):
+        """Returns True if this is a editable message."""
+
+        # For now, look specifically to see if this object is the
+        # document frame. If it's not, we cannot be sure how complex
+        # this message is and should let the Gecko code kick in.
+        #
+        if obj \
+           and obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME \
+           and obj.getState().contains(pyatspi.STATE_EDITABLE):
+            return True
+
+        return False
+
+    def useCaretNavigationModel(self, keyboardEvent):
+        """Returns True if we should do our own caret navigation."""
+
+        if self.isEditableMessage(orca_state.locusOfFocus):
+            return False
+
+        return Gecko.Script.useCaretNavigationModel(self, keyboardEvent)
diff --git a/src/orca/scripts/apps/Thunderbird/speech_generator.py b/src/orca/scripts/apps/Thunderbird/speech_generator.py
index dfbaf86..51f1f37 100644
--- a/src/orca/scripts/apps/Thunderbird/speech_generator.py
+++ b/src/orca/scripts/apps/Thunderbird/speech_generator.py
@@ -47,6 +47,19 @@ class SpeechGenerator(Gecko.SpeechGenerator):
     def __init__(self, script):
         Gecko.SpeechGenerator.__init__(self, script)
 
+    def _generateRoleName(self, obj, **args):
+        """Prevents some roles from being spoken."""
+        result = []
+        role = args.get('role', obj.getRole())
+        if role == pyatspi.ROLE_DOCUMENT_FRAME \
+           and obj.getState().contains(pyatspi.STATE_EDITABLE):
+            pass
+        else:
+            result.extend(Gecko.SpeechGenerator._generateRoleName(
+                              self, obj, **args))
+
+        return result
+
     def _generateColumnHeader(self, obj, **args):
         """Returns an array of strings (and possibly voice and audio
         specifications) that represent the column header for an object
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index bc3d412..9c7ff99 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -2525,8 +2525,8 @@ class Script(default.Script):
             # before speaking the character.
             #
             string = text.getText(0, -1)
-            if characterOffset >= len(string) and \
-               obj.getRole() != pyatspi.ROLE_ENTRY:
+            if characterOffset >= len(string) \
+               and not obj.getState().contains(pyatspi.STATE_EDITABLE):
                 print "YIKES in Gecko.sayCharacter!"
                 characterOffset -= 1
 
@@ -2555,7 +2555,8 @@ class Script(default.Script):
             # a call to goNextWord.]]]
             #
             string = text.getText(0, -1)
-            if characterOffset >= len(string):
+            if characterOffset >= len(string) \
+               and not obj.getState().contains(pyatspi.STATE_EDITABLE):
                 print "YIKES in Gecko.sayWord!"
                 characterOffset -= 1
 
@@ -2596,7 +2597,8 @@ class Script(default.Script):
             # a call to goNextLine.]]]
             #
             string = text.getText(0, -1)
-            if characterOffset >= len(string):
+            if characterOffset >= len(string) \
+               and not obj.getState().contains(pyatspi.STATE_EDITABLE):
                 print "YIKES in Gecko.sayLine!"
                 characterOffset -= 1
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]