[orca] Migrate Nautilus to stop listening to the now-deprecated focus: event



commit 3ff95686e89b99fddd86120d0bc30dd9003226b9
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Sat Nov 2 18:13:10 2013 -0400

    Migrate Nautilus to stop listening to the now-deprecated focus: event

 src/orca/scripts/apps/nautilus/script.py |   64 ++++------------------------
 src/orca/scripts/default.py              |   67 ++++++++++++++++--------------
 2 files changed, 45 insertions(+), 86 deletions(-)
---
diff --git a/src/orca/scripts/apps/nautilus/script.py b/src/orca/scripts/apps/nautilus/script.py
index ee995be..354f2a2 100644
--- a/src/orca/scripts/apps/nautilus/script.py
+++ b/src/orca/scripts/apps/nautilus/script.py
@@ -25,9 +25,6 @@ __date__      = "$Date$"
 __copyright__ = "Copyright (c) 2006-2009 Sun Microsystems Inc."
 __license__   = "LGPL"
 
-import pyatspi
-import orca.debug as debug
-import orca.messages as messages
 import orca.scripts.default as default
 
 ########################################################################
@@ -47,57 +44,14 @@ class Script(default.Script):
 
         default.Script.__init__(self, app)
 
-    def isActivatableEvent(self, event):
-        """Returns True if the given event is one that should cause this
-        script to become the active script.  This is only a hint to
-        the focus tracking manager and it is not guaranteed this
-        request will be honored.  Note that by the time the focus
-        tracking manager calls this method, it thinks the script
-        should become active.  This is an opportunity for the script
-        to say it shouldn't.
-        """
-
-        # Let's make sure we have an active window if focus on an icon
-        # changes. Focus can change when we don't have an an active
-        # window when someone deletes a file from a shell and nautilus
-        # happens to be showing the directory where that file exists.
-        # See bug #568696.  We'll be specific here so as to avoid
-        # looking at the child states for every single event from
-        # nautilus, which happens to be an event-happy application.
-        #
-        if event and event.type == "focus:" \
-           and event.source.getRole() == pyatspi.ROLE_ICON:
-            shouldActivate = False
-            for child in self.app:
-                if child.getState().contains(pyatspi.STATE_ACTIVE):
-                    shouldActivate = True
-                    break
-        else:
-            shouldActivate = True
-
-        if not shouldActivate:
-            debug.println(debug.LEVEL_FINE,
-                          "%s does not want to become active" % self.name)
-
-        return shouldActivate
-
-    def onSelectionChanged(self, event):
-        """Called when an object's selection changes.
-
-        Arguments:
-        - event: the Event
-        """
-
-        try:
-            role = event.source.getRole()
-        except:
-            return
+    def skipObjectEvent(self, event):
+        # NOTE: This is here temporarily as part of the preparation for the
+        # deprecation/removal of accessible "focus:" events. Once the change
+        # has been complete, this method should be removed from this script.
+        if event.type == "focus:":
+            return True
 
-        # We present the selection changes in the layered pane as a result
-        # of the child announcing emitting an event for the state change.
-        # And the default script will update the locusOfFocus to the layered
-        # pane if nothing is selected.
-        if role == pyatspi.ROLE_LAYERED_PANE:
-            return
+        if event.type == "object:state-changed:focused":
+            return False
 
-        default.Script.onSelectionChanged(self, event)
+        return default.Script.skipObjectEvent(self, event)
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index 74037ee..ccb8a0c 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -782,7 +782,6 @@ class Script(script.Script):
                 voice = self.voices[settings.HYPERLINK_VOICE]
             else:
                 voice = self.voices[settings.DEFAULT_VOICE]
-
             utterances = self.speechGenerator.generateSpeech(
                 newLocusOfFocus,
                 priorObj=oldLocusOfFocus)
@@ -2434,45 +2433,31 @@ class Script(script.Script):
         speech.speak(self.speechGenerator.generateSpeech(obj, alreadyFocused=True))
 
     def onSelectionChanged(self, event):
-        """Called when an object's selection changes.
+        """Callback for object:selection-changed accessibility events."""
 
-        Arguments:
-        - event: the Event
-        """
-        if not event or not event.source:
+        obj = event.source
+        state = obj.getState()
+        if state.contains(pyatspi.STATE_MANAGES_DESCENDANTS):
             return
 
+        if not state.contains(pyatspi.STATE_SHOWING):
+            return
+ 
         # Save the event source, if it is a menu or combo box. It will be
         # useful for optimizing componentAtDesktopCoords in the case that
         # the pointer is hovering over a menu item. The alternative is to
         # traverse the application's tree looking for potential moused-over
         # menu items.
-        if event.source.getRole() in (pyatspi.ROLE_COMBO_BOX,
-                                           pyatspi.ROLE_MENU):
-            self.lastSelectedMenu = event.source
-
-        # Avoid doing this with objects that manage their descendants
-        # because they'll issue a descendant changed event.
-        #
-        if event.source.getState().contains(pyatspi.STATE_MANAGES_DESCENDANTS):
-            return
-
-        if event.source.getRole() == pyatspi.ROLE_COMBO_BOX:
-            self.visualAppearanceChanged(event, event.source)
-
-        # We treat selected children as the locus of focus. When the
-        # selection changed we want to update the locus of focus. If
-        # there is no selection, we default the locus of focus to the
-        # containing object.
-        #
-        elif (event.source != orca_state.locusOfFocus) and \
-              event.source.getState().contains(pyatspi.STATE_FOCUSED):
-            newFocus = event.source
-            selectedChildren = self.utilities.selectedChildren(newFocus)
-            if selectedChildren:
-                newFocus = selectedChildren[0]
-
-            orca.setLocusOfFocus(event, newFocus)
+        if obj.getRole() in (pyatspi.ROLE_COMBO_BOX, pyatspi.ROLE_MENU):
+            self.lastSelectedMenu = obj
+
+        # TODO - JD: We need to give more thought to where we look to this
+        # event and where we prefer object:state-changed:selected.
+        selectedChildren = self.utilities.selectedChildren(obj)
+        for child in selectedChildren:
+            if not self.utilities.isLayoutOnly(child):
+                orca.setLocusOfFocus(event, child)
+                break
 
     def onStateChanged(self, event):
         """Called whenever an object's state changes.
@@ -2983,6 +2968,8 @@ class Script(script.Script):
         - event: the Event
         """
 
+        self.pointOfReference = {}
+
         self.windowActivateTime = time.time()
         orca.setLocusOfFocus(event, event.source)
 
@@ -3011,6 +2998,24 @@ class Script(script.Script):
         - event: the Event
         """
 
+        self.pointOfReference = {}
+
+        menuRoles = [pyatspi.ROLE_MENU,
+                     pyatspi.ROLE_MENU_ITEM,
+                     pyatspi.ROLE_CHECK_MENU_ITEM,
+                     pyatspi.ROLE_RADIO_MENU_ITEM]
+
+        # If we get into a popup menu, the parent application will likely
+        # emit a window-deactivate event. But functionally we're still in
+        # the same window. In this case, we do not want to update anything.
+        try:
+            role = orca_state.locusOfFocus.getRole()
+        except:
+            pass
+        else:
+            if role in menuRoles:
+                return
+
         # If we receive a "window:deactivate" event for the object that
         # currently has focus, then stop the current speech output.
         # This is very useful for terminating long speech output from


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