[orca] Web: Stop initially on giant ARIA containers in browse mode



commit ae7fb31e5b4f8f093fb746a6b7d5632c6d99c24b
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Mon Mar 22 13:05:12 2021 +0100

    Web: Stop initially on giant ARIA containers in browse mode
    
    Orca used to not descend certain container roles in browse mode, such
    as menus, toolbars, trees, etc. The reason being we trusted that the
    author would provide focus management for these items and the user
    could access them in focus mode. Unfortunately, we found instances in
    which the author ARIAed up static content with these roles and failed
    to provide any focus management so Orca now descends these items in
    browse mode.
    
    Unfortunately, this change seems to have a side effect of chattiness
    in certain properly-authored content, such as an SVG with ARIA tree-
    related roles, proper names, and optional author-provided navigation.
    
    Because we cannot know programmatically if we have good authoring or
    bad authoring, a reasonable compromise seems to be to initially stop
    at these large containers and present them to the user in browse mode.
    This gives the user the opportunity to manually enter focus mode if
    desired and also eliminates some verbal spew if they remain in browse
    mode.

 src/orca/scripts/web/script_utilities.py | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
---
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 55c930891..6de84eccb 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -1094,7 +1094,7 @@ class Utilities(script_utilities.Utilities):
         self._hasNameAndActionAndNoUsefulChildren[hash(obj)] = rv
         return rv
 
-    def _treatObjectAsWhole(self, obj):
+    def _treatObjectAsWhole(self, obj, offset=None):
         always = [pyatspi.ROLE_CHECK_BOX,
                   pyatspi.ROLE_CHECK_MENU_ITEM,
                   pyatspi.ROLE_LIST_BOX,
@@ -1116,7 +1116,12 @@ class Utilities(script_utilities.Utilities):
             return True
 
         if role in descendable:
-            return self._script.inFocusMode()
+            if self._script.inFocusMode():
+                return True
+
+            # This should cause us to initially stop at the large containers before
+            # allowing the user to drill down into them in browse mode.
+            return offset == -1
 
         if role == pyatspi.ROLE_ENTRY:
             if obj.childCount == 1 and self.isFakePlaceholderForEntry(obj[0]):
@@ -5007,12 +5012,12 @@ class Utilities(script_utilities.Utilities):
                 for i in range(offset + 1, len(allText)):
                     child = self.getChildAtOffset(obj, i)
                     if self._canHaveCaretContext(child):
-                        if self._treatObjectAsWhole(child):
+                        if self._treatObjectAsWhole(child, 0):
                             return child, 0
                         return self.findNextCaretInOrder(child, -1)
                     if allText[i] not in (self.EMBEDDED_OBJECT_CHARACTER, self.ZERO_WIDTH_NO_BREAK_SPACE):
                         return obj, i
-            elif obj.childCount and not self._treatObjectAsWhole(obj):
+            elif obj.childCount and not self._treatObjectAsWhole(obj, offset):
                 return self.findNextCaretInOrder(obj[0], -1)
             elif offset < 0 and not self.isTextBlockElement(obj):
                 return obj, 0
@@ -5073,12 +5078,12 @@ class Utilities(script_utilities.Utilities):
                 for i in range(offset - 1, -1, -1):
                     child = self.getChildAtOffset(obj, i)
                     if self._canHaveCaretContext(child):
-                        if self._treatObjectAsWhole(child):
+                        if self._treatObjectAsWhole(child, 0):
                             return child, 0
                         return self.findPreviousCaretInOrder(child, -1)
                     if allText[i] not in (self.EMBEDDED_OBJECT_CHARACTER, self.ZERO_WIDTH_NO_BREAK_SPACE):
                         return obj, i
-            elif obj.childCount and not self._treatObjectAsWhole(obj):
+            elif obj.childCount and not self._treatObjectAsWhole(obj, offset):
                 return self.findPreviousCaretInOrder(obj[obj.childCount - 1], -1)
             elif offset < 0 and not self.isTextBlockElement(obj):
                 return obj, 0


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