[orca] Handle changes in Gtk+ 3.20 combo boxes



commit 0ec934979032bccc254c89141e2ff3adb53c26ce
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Mon Apr 4 22:03:04 2016 -0400

    Handle changes in Gtk+ 3.20 combo boxes

 src/orca/scripts/toolkits/gtk/script.py           |   19 ++++++++
 src/orca/scripts/toolkits/gtk/script_utilities.py |   48 ++++++++++++++++++++-
 2 files changed, 66 insertions(+), 1 deletions(-)
---
diff --git a/src/orca/scripts/toolkits/gtk/script.py b/src/orca/scripts/toolkits/gtk/script.py
index b1c3fed..52fa6cd 100644
--- a/src/orca/scripts/toolkits/gtk/script.py
+++ b/src/orca/scripts/toolkits/gtk/script.py
@@ -42,6 +42,21 @@ class Script(default.Script):
     def getUtilities(self):
         return Utilities(self)
 
+    def deactivate(self):
+        """Called when this script is deactivated."""
+
+        self.utilities.clearCachedObjects()
+        super().deactivate()
+
+    def locusOfFocusChanged(self, event, oldFocus, newFocus):
+        """Handles changes of focus of interest to the script."""
+
+        if self.utilities.isToggleDescendantOfComboBox(newFocus):
+            isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
+            newFocus = pyatspi.findAncestor(newFocus, isComboBox) or newFocus
+
+        super().locusOfFocusChanged(event, oldFocus, newFocus)
+
     def onActiveDescendantChanged(self, event):
         """Callback for object:active-descendant-changed accessibility events."""
 
@@ -198,6 +213,10 @@ class Script(default.Script):
     def onSelectionChanged(self, event):
         """Callback for object:selection-changed accessibility events."""
 
+        if self.utilities.isComboBoxWithToggleDescendant(event.source):
+            super().onSelectionChanged(event)
+            return
+
         role = event.source.getRole()
         if role == pyatspi.ROLE_COMBO_BOX \
            and not event.source.getState().contains(pyatspi.STATE_FOCUSED):
diff --git a/src/orca/scripts/toolkits/gtk/script_utilities.py 
b/src/orca/scripts/toolkits/gtk/script_utilities.py
index aadd7dc..27eb79b 100644
--- a/src/orca/scripts/toolkits/gtk/script_utilities.py
+++ b/src/orca/scripts/toolkits/gtk/script_utilities.py
@@ -35,7 +35,13 @@ import orca.orca_state as orca_state
 class Utilities(script_utilities.Utilities):
 
     def __init__(self, script):
-        script_utilities.Utilities.__init__(self, script)
+        super().__init__(script)
+        self._isComboBoxWithToggleDescendant = {}
+        self._isToggleDescendantOfComboBox = {}
+
+    def clearCachedObjects(self):
+        self._isComboBoxWithToggleDescendant = {}
+        self._isToggleDescendantOfComboBox = {}
 
     def displayedText(self, obj):
         displayedText = script_utilities.Utilities.displayedText(self, obj)
@@ -50,6 +56,46 @@ class Utilities(script_utilities.Utilities):
         self._script.generatorCache[self.DISPLAYED_TEXT][obj] = displayedText
         return displayedText
 
+    def isComboBoxWithToggleDescendant(self, obj):
+        if not (obj and obj.getRole() == pyatspi.ROLE_COMBO_BOX):
+            return False
+
+        rv = self._isComboBoxWithToggleDescendant.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        isToggle = lambda x: x and x.getRole() == pyatspi.ROLE_TOGGLE_BUTTON
+
+        for child in obj:
+            if child.getRole() != pyatspi.ROLE_FILLER:
+                continue
+
+            toggle = pyatspi.findDescendant(child, isToggle)
+            rv = toggle is not None
+            if toggle:
+                self._isToggleDescendantOfComboBox[hash(toggle)] = True
+                break
+
+        self._isComboBoxWithToggleDescendant[hash(obj)] = rv
+        return rv
+
+    def isToggleDescendantOfComboBox(self, obj):
+        if not (obj and obj.getRole() == pyatspi.ROLE_TOGGLE_BUTTON):
+            return False
+
+        rv = self._isToggleDescendantOfComboBox.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        isComboBox = lambda x: x and x.getRole() == pyatspi.ROLE_COMBO_BOX
+        comboBox = pyatspi.findAncestor(obj, isComboBox)
+        if comboBox:
+            self._isComboBoxWithToggleDescendant[hash(comboBox)] = True
+
+        rv = comboBox is not None
+        self._isToggleDescendantOfComboBox[hash(obj)] = rv
+        return rv
+
     def isSearchEntry(self, obj, focusedOnly=False):
         # Another example of why we need subrole support in ATK and AT-SPI2.
         try:


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