def activate(self):
        """Called when this presentation manager is activated."""

        self._listenerCounts = {}
        self._knownScripts   = {}
        self._knownAppSettings = {}
        self._oldAppSettings = None
        self._defaultScript  = None

        self._restoreAppStates()

        self.setActiveScript(self._getScript(None))

        # Tell BrlTTY which commands we care about.
        #
        braille.setupKeyRanges(orca_state.activeScript.brailleBindings.keys())

        self._registerEventListener("window:activate")
        self._registerEventListener("window:deactivate")
        self._registerEventListener("object:children-changed:remove")

        win = orca_state.activeScript.findActiveWindow()
        if win:
            # Generate a fake window activation event so the application
            # can tell the user about itself.
            #
            e = atspi.Event()
            e.source   = win._acc
            e.type     = "window:activate"
            e.detail1  = 0
            e.detail2  = 0
            e.any_data = None
            self._enqueueEvent(e)
Пример #2
0
    def activate(self):
        """Called when this presentation manager is activated."""

        self._listenerCounts = {}
        self._knownScripts = {}
        self._knownAppSettings = {}
        self._oldAppSettings = None
        self._defaultScript = None

        self._restoreAppStates()

        self.setActiveScript(self._getScript(None))

        # Tell BrlTTY which commands we care about.
        #
        braille.setupKeyRanges(orca_state.activeScript.brailleBindings.keys())

        self._registerEventListener("window:activate")
        self._registerEventListener("window:deactivate")
        self._registerEventListener("object:children-changed:remove")

        win = orca_state.activeScript.findActiveWindow()
        if win:
            # Generate a fake window activation event so the application
            # can tell the user about itself.
            #
            e = atspi.Event()
            e.source = win._acc
            e.type = "window:activate"
            e.detail1 = 0
            e.detail2 = 0
            e.any_data = None
            self._enqueueEvent(e)
Пример #3
0
    def activate(self):
        """Called when this presentation manager is activated."""

        global _scriptManager
        _scriptManager = getattr(orca, "_scriptManager")

        # Tell BrlTTY which commands we care about.
        #
        braille.setupKeyRanges(orca_state.activeScript.brailleBindings.keys())

        self._registerListener("window:activate")
        self._registerListener("window:deactivate")
        self._registerListener("object:children-changed")
        self._registerListener("mouse:button")
Пример #4
0
    def activate(self):
        """Called when this presentation manager is activated."""

        global _scriptManager
        _scriptManager = getattr(orca, '_scriptManager')

        # Tell BrlTTY which commands we care about.
        #
        braille.setupKeyRanges(orca_state.activeScript.brailleBindings.keys())

        self._registerListener("window:activate")
        self._registerListener("window:deactivate")
        self._registerListener("object:children-changed:remove")

        win = orca_state.activeScript.utilities.activeWindow()
        if win:
            # Generate a fake window activation event so the application
            # can tell the user about itself.
            #
            class _FakeEvent:
                def __init__(self, source, eventType,
                             detail1, detail2, any_data):
                    self.source = source
                    self.type = eventType
                    self.detail1 = detail1
                    self.detail2 = detail2
                    self.any_data = any_data
                    self.host_application = None

            class _FakeData:
                def __init__(self):
                    pass
                def value(self):
                    return None

            fe = _FakeEvent(win, "window:activate", 0, 0, _FakeData())
            self._enqueue(fe)
    def _processObjectEvent(self, event):
        """Handles all events destined for scripts.

        Arguments:
        - e: an at-spi event.
        """

        debug.printObjectEvent(debug.LEVEL_FINEST, event)

        # [[[TODO: WDW - HACK to prevent gnome-panel from killing
        # itself.  It seems to do so after it issues some tool tip
        # events and Orca attempts to process them.  We're not really
        # doing anything with tool tips right now, so we just ignore
        # them.  Note that this is just a bandaid to the problem.  We
        # should do something better.  Please refer to bug 368626
        # http://bugzilla.gnome.org/show_bug.cgi?id=368626 to follow
        # this problem.]]]
        #
        try:
            if event.source.role == rolenames.ROLE_TOOL_TIP:
                # Check that it's okay to present tool tips. Always present
                # tooltips initiated by the user pressing Control-F1 on the
                # keyboard.
                #
                if isinstance(orca_state.lastInputEvent, \
                              input_event.KeyboardEvent):
                    if not orca_state.lastNonModifierKeyEvent.event_string == "F1":
                        return

                    # Mouse move events don't update orca_state.lastInputEvent
                    # so it's possible the user accidentally nudged the
                    # mouse and generated another tooltip event. If the
                    # current time minus the last keyboard event time is
                    # greater than 0.2 seconds, than just ignore this tooltip
                    # event.
                    #
                    currentTime =  time.time()
                    if (currentTime - orca_state.lastInputEvent.time) > 0.2:
                        return
                elif not settings.presentToolTips:
                    return
        except:
            pass

        # Reclaim (delete) any scripts when desktop children go away.
        # The idea here is that a desktop child is an app. We also
        # generally do not like object:children-changed:remove events,
        # either.
        #
        if event.type.startswith("object:children-changed:remove"):
            if event.source == atspi.Accessible.makeAccessible(
                                   self.registry.desktop):
                self._reclaimScripts()
                self._cleanupCache()
                if settings.debugMemoryUsage:
                    self._cleanupGarbage()
            return

        try:
            # We don't want to touch a defunct object.  It's useless and it
            # can cause hangs.
            #
            if event.source \
               and event.source.state.count(atspi.Accessibility.STATE_DEFUNCT):
                debug.println(debug.LEVEL_FINEST,
                              "IGNORING DEFUNCT OBJECT")
                atspi.Accessible.deleteAccessible(event.source)
                return

            if (not debug.eventDebugFilter) \
                or (debug.eventDebugFilter \
                    and debug.eventDebugFilter.match(event.type)):
                if not event.type.startswith("mouse:"):
                    debug.printDetails(debug.LEVEL_FINEST, "    ", event.source)

        except CORBA.COMM_FAILURE:
            debug.printException(debug.LEVEL_WARNING)
            debug.println(debug.LEVEL_FINEST,
                          "COMM_FAILURE above while processing event: " \
                          + event.type)
        except CORBA.OBJECT_NOT_EXIST:
            debug.printException(debug.LEVEL_WARNING)
            debug.println(debug.LEVEL_WARNING,
                          "OBJECT_NOT_EXIST above while processing event: " \
                          + event.type)
            atspi.Accessible.deleteAccessible(event.source)
            return
        except:
            debug.printException(debug.LEVEL_WARNING)
            return

        if not event.source:
            debug.println(debug.LEVEL_WARNING,
                          "ERROR: received an event with no source.")
            return

        # We can sometimes get COMM_FAILURES even if the object has not
        # gone away.  This happens a lot with the Java access bridge.
        # So...we will try a few times before giving up.
        #
        # [[[TODO: WDW - might want to consider re-introducing the reload
        # feature of scripts somewhere around here.  I pulled it out as
        # part of the big refactor to make scripts object-oriented. Logged
        # as bugzilla bug 319777.]]]
        #
        retryCount = 0
        oldLocusOfFocus = orca_state.locusOfFocus
        try:
            # If we've received a mouse event, then don't try to get
            # event.source.app because the top most parent is of role
            # unknown, which will cause an ERROR message to be displayed.
            # See Orca bug #409731 for more details.
            #
            if not event.type.startswith("mouse:"):
                s = self._getScript(event.source.app)
            else:
                s = orca_state.activeScript
            if not s:
                return
        except:
            s = None
            debug.printException(debug.LEVEL_WARNING)
            debug.println(debug.LEVEL_WARNING,
                          "ERROR: received an event, but Script is None")

        while s and retryCount <= s.commFailureAttemptLimit:
            try:
                if not event.source.state.count( \
                                      atspi.Accessibility.STATE_ICONIFIED):

                    # [[[TODO: WDW - HACK we look for frame that get
                    # focus: as a means to detect active scripts
                    # because yelp does this.  Actually, yelp is a bit
                    # odd in that it calls itself 'yelp' then changes
                    # its application name and id to the Gecko toolkit
                    # in use, and then issues a focus: event on the
                    # main window, which is a frame.]]]
                    #
                    if event.type.startswith("window:activate") \
                       or (event.type.startswith("focus:") \
                           and (event.source.role == rolenames.ROLE_FRAME)):

                        # We'll let someone else decide if it's important
                        # to stop speech or not.
                        #speech.stop()
                        debug.println(debug.LEVEL_FINE, "ACTIVE SCRIPT: " \
                                      + orca_state.activeScript.name)

                        self.setActiveScript(self._getScript(event.source.app))

                        # Load in the application specific settings for the
                        # app for this event (if found).
                        #
                        appSettings = self.loadAppSettings( \
                                                      orca_state.activeScript)

                        # Tell BrlTTY which commands we care about.
                        #
                        braille.setupKeyRanges(\
                            orca_state.activeScript.brailleBindings.keys())

                    s.processObjectEvent(event)
                    if retryCount:
                        debug.println(debug.LEVEL_WARNING,
                                      "  SUCCEEDED AFTER %d TRIES" % retryCount)
                break
            except CORBA.COMM_FAILURE:
                debug.printException(debug.LEVEL_WARNING)
                debug.println(debug.LEVEL_WARNING,
                              "COMM_FAILURE above while processing: " \
                              + event.type)
                retryCount += 1
                if retryCount <= s.commFailureAttemptLimit:
                    # We want the old locus of focus to be reset so
                    # the proper stuff will be spoken if the locus
                    # of focus changed during our last attempt at
                    # handling this event.
                    #
                    orca_state.locusOfFocus = oldLocusOfFocus
                    debug.println(debug.LEVEL_WARNING,
                                  "  TRYING AGAIN (%d)" % retryCount)
                    time.sleep(s.commFailureWaitTime)
                else:
                    debug.println(debug.LEVEL_WARNING,
                                  "  GIVING UP AFTER %d TRIES" \
                                  % (retryCount - 1))
                    atspi.Accessible.deleteAccessible(event.source)
            except:
                debug.printException(debug.LEVEL_WARNING)
                break
Пример #6
0
    def _processObjectEvent(self, event):
        """Handles all events destined for scripts.

        Arguments:
        - e: an at-spi event.
        """

        debug.printObjectEvent(debug.LEVEL_FINEST, event)

        # [[[TODO: WDW - HACK to prevent gnome-panel from killing
        # itself.  It seems to do so after it issues some tool tip
        # events and Orca attempts to process them.  We're not really
        # doing anything with tool tips right now, so we just ignore
        # them.  Note that this is just a bandaid to the problem.  We
        # should do something better.  Please refer to bug 368626
        # http://bugzilla.gnome.org/show_bug.cgi?id=368626 to follow
        # this problem.]]]
        #
        try:
            if event.source.role == rolenames.ROLE_TOOL_TIP:
                # Check that it's okay to present tool tips. Always present
                # tooltips initiated by the user pressing Control-F1 on the
                # keyboard.
                #
                if isinstance(orca_state.lastInputEvent, \
                              input_event.KeyboardEvent):
                    if not orca_state.lastNonModifierKeyEvent.event_string == "F1":
                        return

                    # Mouse move events don't update orca_state.lastInputEvent
                    # so it's possible the user accidentally nudged the
                    # mouse and generated another tooltip event. If the
                    # current time minus the last keyboard event time is
                    # greater than 0.2 seconds, than just ignore this tooltip
                    # event.
                    #
                    currentTime = time.time()
                    if (currentTime - orca_state.lastInputEvent.time) > 0.2:
                        return
                elif not settings.presentToolTips:
                    return
        except:
            pass

        # Reclaim (delete) any scripts when desktop children go away.
        # The idea here is that a desktop child is an app. We also
        # generally do not like object:children-changed:remove events,
        # either.
        #
        if event.type.startswith("object:children-changed:remove"):
            if event.source == atspi.Accessible.makeAccessible(
                    self.registry.desktop):
                self._reclaimScripts()
                self._cleanupCache()
                if settings.debugMemoryUsage:
                    self._cleanupGarbage()
            return

        try:
            # We don't want to touch a defunct object.  It's useless and it
            # can cause hangs.
            #
            if event.source \
               and event.source.state.count(atspi.Accessibility.STATE_DEFUNCT):
                debug.println(debug.LEVEL_FINEST, "IGNORING DEFUNCT OBJECT")
                atspi.Accessible.deleteAccessible(event.source)
                return

            if (not debug.eventDebugFilter) \
                or (debug.eventDebugFilter \
                    and debug.eventDebugFilter.match(event.type)):
                if not event.type.startswith("mouse:"):
                    debug.printDetails(debug.LEVEL_FINEST, "    ",
                                       event.source)

        except CORBA.COMM_FAILURE:
            debug.printException(debug.LEVEL_WARNING)
            debug.println(debug.LEVEL_FINEST,
                          "COMM_FAILURE above while processing event: " \
                          + event.type)
        except CORBA.OBJECT_NOT_EXIST:
            debug.printException(debug.LEVEL_WARNING)
            debug.println(debug.LEVEL_WARNING,
                          "OBJECT_NOT_EXIST above while processing event: " \
                          + event.type)
            atspi.Accessible.deleteAccessible(event.source)
            return
        except:
            debug.printException(debug.LEVEL_WARNING)
            return

        if not event.source:
            debug.println(debug.LEVEL_WARNING,
                          "ERROR: received an event with no source.")
            return

        # We can sometimes get COMM_FAILURES even if the object has not
        # gone away.  This happens a lot with the Java access bridge.
        # So...we will try a few times before giving up.
        #
        # [[[TODO: WDW - might want to consider re-introducing the reload
        # feature of scripts somewhere around here.  I pulled it out as
        # part of the big refactor to make scripts object-oriented. Logged
        # as bugzilla bug 319777.]]]
        #
        retryCount = 0
        oldLocusOfFocus = orca_state.locusOfFocus
        try:
            # If we've received a mouse event, then don't try to get
            # event.source.app because the top most parent is of role
            # unknown, which will cause an ERROR message to be displayed.
            # See Orca bug #409731 for more details.
            #
            if not event.type.startswith("mouse:"):
                s = self._getScript(event.source.app)
            else:
                s = orca_state.activeScript
            if not s:
                return
        except:
            s = None
            debug.printException(debug.LEVEL_WARNING)
            debug.println(debug.LEVEL_WARNING,
                          "ERROR: received an event, but Script is None")

        while s and retryCount <= s.commFailureAttemptLimit:
            try:
                if not event.source.state.count( \
                                      atspi.Accessibility.STATE_ICONIFIED):

                    # [[[TODO: WDW - HACK we look for frame that get
                    # focus: as a means to detect active scripts
                    # because yelp does this.  Actually, yelp is a bit
                    # odd in that it calls itself 'yelp' then changes
                    # its application name and id to the Gecko toolkit
                    # in use, and then issues a focus: event on the
                    # main window, which is a frame.]]]
                    #
                    if event.type.startswith("window:activate") \
                       or (event.type.startswith("focus:") \
                           and (event.source.role == rolenames.ROLE_FRAME)):

                        # We'll let someone else decide if it's important
                        # to stop speech or not.
                        #speech.stop()
                        debug.println(debug.LEVEL_FINE, "ACTIVE SCRIPT: " \
                                      + orca_state.activeScript.name)

                        self.setActiveScript(self._getScript(event.source.app))

                        # Load in the application specific settings for the
                        # app for this event (if found).
                        #
                        appSettings = self.loadAppSettings( \
                                                      orca_state.activeScript)

                        # Tell BrlTTY which commands we care about.
                        #
                        braille.setupKeyRanges(\
                            orca_state.activeScript.brailleBindings.keys())

                    s.processObjectEvent(event)
                    if retryCount:
                        debug.println(
                            debug.LEVEL_WARNING,
                            "  SUCCEEDED AFTER %d TRIES" % retryCount)
                break
            except CORBA.COMM_FAILURE:
                debug.printException(debug.LEVEL_WARNING)
                debug.println(debug.LEVEL_WARNING,
                              "COMM_FAILURE above while processing: " \
                              + event.type)
                retryCount += 1
                if retryCount <= s.commFailureAttemptLimit:
                    # We want the old locus of focus to be reset so
                    # the proper stuff will be spoken if the locus
                    # of focus changed during our last attempt at
                    # handling this event.
                    #
                    orca_state.locusOfFocus = oldLocusOfFocus
                    debug.println(debug.LEVEL_WARNING,
                                  "  TRYING AGAIN (%d)" % retryCount)
                    time.sleep(s.commFailureWaitTime)
                else:
                    debug.println(debug.LEVEL_WARNING,
                                  "  GIVING UP AFTER %d TRIES" \
                                  % (retryCount - 1))
                    atspi.Accessible.deleteAccessible(event.source)
            except:
                debug.printException(debug.LEVEL_WARNING)
                break