[orca/gnome-3-22] Improve filtering out of non-showing menu items in flat review



commit 1fae2025b6894ff0b3bc8f4a51aa0ca65e9a0977
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Wed Sep 7 17:04:30 2016 -0400

    Improve filtering out of non-showing menu items in flat review

 src/orca/script_utilities.py                       |   78 +++++++++++++++++++-
 .../keystrokes/firefox/ui_role_menu_flat_review.py |    4 +
 2 files changed, 78 insertions(+), 4 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index f9233fd..97e180b 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -97,6 +97,7 @@ class Utilities:
 
         self._script = script
         self._clipboardHandlerId = None
+        self._selectedMenuBarMenu = {}
 
     #########################################################################
     #                                                                       #
@@ -1594,6 +1595,60 @@ class Utilities:
 
         return True
 
+    def selectedMenuBarMenu(self, menubar):
+        try:
+            role = menubar.getRole()
+        except:
+            msg = "ERROR: Exception getting role of %s" % menubar
+            debug.println(debug.LEVEL_INFO, msg, True)
+            return None
+
+        if role != pyatspi.ROLE_MENU_BAR:
+            return None
+
+        if "Selection" in pyatspi.listInterfaces(menubar):
+            selected = self.selectedChildren(menubar)
+            if selected:
+                return selected[0]
+            return None
+
+        for menu in menubar:
+            try:
+                menu.clearCache()
+                state = menu.getState()
+            except:
+                msg = "ERROR: Exception getting state of %s" % menu
+                debug.println(debug.LEVEL_INFO, msg, True)
+                continue
+
+            if state.contains(pyatspi.STATE_EXPANDED) \
+               or state.contains(pyatspi.STATE_SELECTED):
+                return menu
+
+        return None
+
+    def isInOpenMenuBarMenu(self, obj):
+        if not obj:
+            return False
+
+        isMenuBar = lambda x: x and x.getRole() == pyatspi.ROLE_MENU_BAR
+        menubar = pyatspi.findAncestor(obj, isMenuBar)
+        if menubar is None:
+            return False
+
+        selectedMenu = self._selectedMenuBarMenu.get(hash(menubar))
+        if selectedMenu is None:
+            selectedMenu = self.selectedMenuBarMenu(menubar)
+
+        if not selectedMenu:
+            return False
+
+        inSelectedMenu = lambda x: x == selectedMenu
+        if inSelectedMenu(obj):
+            return True
+
+        return pyatspi.findAncestor(obj, inSelectedMenu) is not None
+
     def getOnScreenObjects(self, root, extents=None):
         if not self.isOnScreen(root, extents):
             return []
@@ -1611,6 +1666,13 @@ class Utilities:
         if role == pyatspi.ROLE_COMBO_BOX:
             return [root]
 
+        if role == pyatspi.ROLE_MENU_BAR:
+            self._selectedMenuBarMenu[hash(root)] = self.selectedMenuBarMenu(root)
+
+        if root.parent.getRole() == pyatspi.ROLE_MENU_BAR \
+           and not self.isInOpenMenuBarMenu(root):
+            return [root]
+
         if extents is None:
             try:
                 component = root.queryComponent()
@@ -1635,6 +1697,9 @@ class Utilities:
         for child in root:
             objects.extend(self.getOnScreenObjects(child, extents))
 
+        if role == pyatspi.ROLE_MENU_BAR:
+            self._selectedMenuBarMenu[hash(root)] = None
+
         if objects:
             return objects
 
@@ -3739,8 +3804,9 @@ class Utilities:
     def isShowingAndVisible(self, obj):
         try:
             state = obj.getState()
+            role = obj.getRole()
         except:
-            msg = "ERROR: Exception getting state of %s" % obj
+            msg = "ERROR: Exception getting state and role of %s" % obj
             debug.println(debug.LEVEL_INFO, msg, True)
             return False
 
@@ -3752,9 +3818,13 @@ class Utilities:
         # seems to be present in multiple toolkits, so it's either being
         # inherited (e.g. from Gtk in Firefox Chrome, LO, Eclipse) or it
         # may be an AT-SPI2 bug. For now, handling it here.
-        isMenuBar = lambda x: x and x.getRole() == pyatspi.ROLE_MENU_BAR
-        result = pyatspi.findAncestor(obj, isMenuBar) is not None
-        if result:
+        menuRoles = [pyatspi.ROLE_MENU,
+                     pyatspi.ROLE_MENU_ITEM,
+                     pyatspi.ROLE_CHECK_MENU_ITEM,
+                     pyatspi.ROLE_RADIO_MENU_ITEM,
+                     pyatspi.ROLE_SEPARATOR]
+
+        if role in menuRoles and self.isInOpenMenuBarMenu(obj):
             msg = "HACK: Treating %s as showing and visible" % obj
             debug.println(debug.LEVEL_INFO, msg, True)
             return True
diff --git a/test/keystrokes/firefox/ui_role_menu_flat_review.py 
b/test/keystrokes/firefox/ui_role_menu_flat_review.py
index 9bd655f..2ee23b6 100644
--- a/test/keystrokes/firefox/ui_role_menu_flat_review.py
+++ b/test/keystrokes/firefox/ui_role_menu_flat_review.py
@@ -19,6 +19,8 @@ sequence.append(utils.AssertPresentationAction(
      "SPEECH OUTPUT: 'View menu'",
      "SPEECH OUTPUT: 'Toolbars menu.'"]))
 
+sequence.append(PauseAction(3000))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("Down"))
 sequence.append(utils.AssertPresentationAction(
@@ -27,6 +29,8 @@ sequence.append(utils.AssertPresentationAction(
      "     VISIBLE:  'Sidebar menu', cursor=1",
      "SPEECH OUTPUT: 'Sidebar menu.'"]))
 
+sequence.append(PauseAction(3000))
+
 sequence.append(utils.StartRecordingAction())
 sequence.append(KeyComboAction("KP_8"))
 sequence.append(utils.AssertPresentationAction(


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