[orca] Chromium: Fix bogus presentation of posinset and setsize



commit e5e571811e7ab7d46635f8e63832a8acad8f9e9a
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Tue Feb 9 15:32:40 2021 +0100

    Chromium: Fix bogus presentation of posinset and setsize
    
    Chromium has accessible menu items which are not focusable and therefore
    do not have a posinset and setsize calculated. But they may claim to be
    the selected item when an accessible child is selected (e.g. "zoom" when
    "+" or "-" gains focus. Normally we calculate posinset and setsize when
    the application hasn't provided it. We don't want to do that in the case
    of menu items like "zoom" because our result will not jibe with the
    values of its siblings. Thus if a sibling has a value, assume that the
    missing attributes are missing on purpose.

 src/orca/script_utilities.py                           |  9 ++++++++-
 src/orca/scripts/toolkits/Chromium/script_utilities.py | 18 ++++++++++++++++++
 src/orca/scripts/web/script_utilities.py               |  8 +++++++-
 3 files changed, 33 insertions(+), 2 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 7c83d4b48..d12c96078 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -3873,15 +3873,21 @@ class Utilities:
             debug.println(debug.LEVEL_INFO, msg, True)
             return []
 
-        msg = "INFO: %s reports %i selected children" % (obj, count)
+        msg = "INFO: %s reports %i selected child(ren)" % (obj, count)
         debug.println(debug.LEVEL_INFO, msg, True)
 
         children = []
         for x in range(count):
             child = selection.getSelectedChild(x)
+            msg = "INFO: Child %i: %s" % (x, child)
+            debug.println(debug.LEVEL_INFO, msg, True)
             if not self.isZombie(child):
                 children.append(child)
 
+        if count and not children:
+            msg = "INFO: Selected children not retrieved via selection interface."
+            debug.println(debug.LEVEL_INFO, msg, True)
+
         role = obj.getRole()
         if role == pyatspi.ROLE_MENU and not children:
             pred = lambda x: x and x.getState().contains(pyatspi.STATE_SELECTED)
@@ -5015,6 +5021,7 @@ class Utilities:
             layoutRoles = [pyatspi.ROLE_SEPARATOR, pyatspi.ROLE_TEAROFF_MENU_ITEM]
             isNotLayoutOnly = lambda x: not (self.isZombie(x) or x.getRole() in layoutRoles)
             siblings = list(filter(isNotLayoutOnly, siblings))
+
         if not (siblings and obj in siblings):
             return -1, -1
 
diff --git a/src/orca/scripts/toolkits/Chromium/script_utilities.py 
b/src/orca/scripts/toolkits/Chromium/script_utilities.py
index b4baa9136..2a4f4ef06 100644
--- a/src/orca/scripts/toolkits/Chromium/script_utilities.py
+++ b/src/orca/scripts/toolkits/Chromium/script_utilities.py
@@ -145,6 +145,8 @@ class Utilities(web.Utilities):
             return []
 
         result = super().selectedChildren(obj)
+
+        # The fix for this issue landed in 90.0.4413.0.
         if obj.getRole() == pyatspi.ROLE_MENU and not self.inDocumentContent(obj) and len(result) > 1:
             msg = "CHROMIUM: Browser menu %s claims more than one state-selected child." % obj
             debug.println(debug.LEVEL_INFO, msg, True)
@@ -539,3 +541,19 @@ class Utilities(web.Utilities):
             return True
 
         return False
+
+    def _shouldCalculatePositionAndSetSize(self, obj):
+        # Chromium has accessible menu items which are not focusable and therefore do not
+        # have a posinset and setsize calculated. But they may claim to be the selected
+        # item when an accessible child is selected (e.g. "zoom" when "+" or "-" gains focus.
+        # Normally we calculate posinset and setsize when the application hasn't provided it.
+        # We don't want to do that in the case of menu items like "zoom" because our result
+        # will not jibe with the values of its siblings. Thus if a sibling has a value,
+        # assume that the missing attributes are missing on purpose.
+        for sibling in obj.parent:
+            if self.getPositionInSet(sibling) is not None:
+                msg = "CHROMIUM: %s's sibling %s has posinset." % (obj, sibling)
+                debug.println(debug.LEVEL_INFO, msg, True)
+                return False
+
+        return True
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 0f801e898..acdcc15ef 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -561,6 +561,9 @@ class Utilities(script_utilities.Utilities):
 
         return rv
 
+    def _shouldCalculatePositionAndSetSize(self, obj):
+        return True
+
     def getPositionAndSetSize(self, obj, **args):
         posinset = self.getPositionInSet(obj)
         setsize = self.getSetSize(obj)
@@ -568,7 +571,10 @@ class Utilities(script_utilities.Utilities):
             # ARIA posinset is 1-based
             return posinset - 1, setsize
 
-        return super().getPositionAndSetSize(obj, **args)
+        if self._shouldCalculatePositionAndSetSize(obj):
+            return super().getPositionAndSetSize(obj, **args)
+
+        return -1, -1
 
     def getPositionInSet(self, obj):
         attrs = self.objectAttributes(obj, False)


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