[orca] Create a dedicated object:state-changed callback for the "busy" state
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] Create a dedicated object:state-changed callback for the "busy" state
- Date: Mon, 4 Nov 2013 18:18:35 +0000 (UTC)
commit faefeb9fad0b5399f973d96457afe0ad619fea55
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Mon Nov 4 13:17:35 2013 -0500
Create a dedicated object:state-changed callback for the "busy" state
src/orca/script_utilities.py | 7 +-
src/orca/scripts/apps/Thunderbird/script.py | 22 +---
src/orca/scripts/default.py | 6 +
src/orca/scripts/toolkits/Gecko/script.py | 165 +++++++++++--------------
src/orca/scripts/toolkits/WebKitGtk/script.py | 30 ++---
5 files changed, 105 insertions(+), 125 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 912591a..7c5720a 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -607,8 +607,13 @@ class Utilities:
except (LookupError, RuntimeError):
pass
+ try:
+ parentRole = obj.parent.getRole()
+ except:
+ parentRole = None
+
# egg-list-box, e.g. privacy panel in gnome-control-center
- if not displayedText and obj.parent.getRole() == pyatspi.ROLE_LIST_BOX:
+ if not displayedText and parentRole == pyatspi.ROLE_LIST_BOX:
labels = self.unrelatedLabels(obj, onlyShowing=False)
displayedText = " ".join(map(self.displayedText, labels))
diff --git a/src/orca/scripts/apps/Thunderbird/script.py b/src/orca/scripts/apps/Thunderbird/script.py
index 4085b4d..345ccb1 100644
--- a/src/orca/scripts/apps/Thunderbird/script.py
+++ b/src/orca/scripts/apps/Thunderbird/script.py
@@ -426,22 +426,14 @@ class Script(Gecko.Script):
Gecko.Script.locusOfFocusChanged(self, event,
oldLocusOfFocus, newLocusOfFocus)
- def onStateChanged(self, event):
- """Called whenever an object's state changes.
+ def onBusyChanged(self, event):
+ """Callback for object:state-changed:busy accessibility events."""
- Arguments:
- - event: the Event
- """
-
- if event.type.startswith("object:state-changed:busy"):
- if event.source.getRole() == pyatspi.ROLE_DOCUMENT_FRAME \
- and not event.detail1:
- self._messageLoaded = True
- if self.inDocumentContent():
- self._presentMessage(event.source)
- return
-
- default.Script.onStateChanged(self, event)
+ obj = event.source
+ if obj.getRole() == pyatspi.ROLE_DOCUMENT_FRAME and not event.detail1:
+ self._messageLoaded = True
+ if self.inDocumentContent():
+ self._presentMessage(obj)
def onStateFocused(self, event):
"""Called whenever an object's state changes focus.
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index 8e4e47f..524fd96 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -529,6 +529,8 @@ class Script(script.Script):
self.onChildrenChanged
listeners["object:state-changed:active"] = \
self.onStateChanged
+ listeners["object:state-changed:busy"] = \
+ self.onBusyChanged
listeners["object:state-changed:focused"] = \
self.onStateChanged
listeners["object:state-changed:showing"] = \
@@ -2261,6 +2263,10 @@ class Script(script.Script):
[orca_state.locusOfFocus.parent,
orca_state.locusOfFocus.getIndexInParent()]
+ def onBusyChanged(self, event):
+ """Callback for object:state-changed:busy accessibility events."""
+ pass
+
def onChildrenChanged(self, event):
"""Called when a child node has changed.
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index 231d420..996113c 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -447,8 +447,6 @@ class Script(default.Script):
self.onStateChanged
listeners["object:state-changed:indeterminate"] = \
self.onStateChanged
- listeners["object:state-changed:busy"] = \
- self.onStateChanged
listeners["object:children-changed"] = \
self.onChildrenChanged
listeners["object:text-changed:insert"] = \
@@ -1170,6 +1168,80 @@ class Script(default.Script):
default.Script.onSelectionChanged(self, event)
+ def onBusyChanged(self, event):
+ """Callback for object:state-changed:busy accessibility events."""
+
+ try:
+ obj = event.source
+ role = obj.getRole()
+ name = obj.name
+ except:
+ return
+ if role != pyatspi.ROLE_DOCUMENT_FRAME:
+ return
+
+ # The event is for the changing contents of the help frame as the user
+ # navigates from topic to topic in the list on the left. Ignore this.
+ if orca_state.locusOfFocus \
+ and orca_state.locusOfFocus.getRole() == pyatspi.ROLE_LIST_ITEM \
+ and not self.inDocumentContent(orca_state.locusOfFocus):
+ return
+
+ finishedLoading = False
+ if event.detail1:
+ self._loadingDocumentContent = True
+ message = messages.PAGE_LOADING_START
+ elif name:
+ message = messages.PAGE_LOADING_END_NAMED % name
+ finishedLoading = True
+ else:
+ message = messages.PAGE_LOADING_END
+ finishedLoading = True
+
+ if not _settingsManager.getSetting('onlySpeakDisplayedText'):
+ self.presentMessage(message)
+
+ if not finishedLoading:
+ return
+
+ # Store the document frame otherwise the first time it gains focus (e.g.
+ # the first time the user arrows off of a link into non-focusable text),
+ # onFocused will start chatting unnecessarily.
+ self._currentFrame = obj
+
+ # First try to figure out where the caret is on the newly loaded page.
+ # If it is on an editable object (e.g., a text entry), then present just
+ # that object. Otherwise, force the caret to the top of the page and
+ # start a SayAll from that position.
+ [obj, characterOffset] = self.getCaretContext()
+ atTop = False
+ if not obj:
+ self.clearCaretContext()
+ [obj, characterOffset] = self.getCaretContext()
+ atTop = True
+ if not obj:
+ return
+ if not atTop and not obj.getState().contains(pyatspi.STATE_FOCUSABLE):
+ self.clearCaretContext()
+ [obj, characterOffset] = self.getCaretContext()
+ if not obj:
+ return
+
+ # For braille, we just show the current line containing the caret. For
+ # speech, however, we will start a Say All operation if the caret is in
+ # an unfocusable area (e.g., it's not in a text entry area such as
+ # Google's search text entry or a link that we just returned to by
+ # pressing the back button). Otherwise, we'll just speak the line that
+ # the caret is on.
+ self.updateBraille(obj)
+ if obj.getState().contains(pyatspi.STATE_FOCUSABLE):
+ speech.speak(self.speechGenerator.generateSpeech(obj))
+ elif not script_settings.sayAllOnLoad:
+ self.speakContents(
+ self.getLineContentsAtOffset(obj, characterOffset))
+ elif _settingsManager.getSetting('enableSpeech'):
+ self.sayAll(None)
+
def onChildrenChanged(self, event):
"""Called when a child node has changed. In particular, we are looking
for addition events often associated with Javascipt insertion. One such
@@ -1411,95 +1483,6 @@ class Script(default.Script):
speech.speak(self.speechGenerator.getLocalizedRoleName(\
event.source, pyatspi.ROLE_AUTOCOMPLETE))
- # We care when the document frame changes it's busy state. That
- # means it has started/stopped loading content.
- #
- if event.type.startswith("object:state-changed:busy"):
- if event.source \
- and (event.source.getRole() == pyatspi.ROLE_DOCUMENT_FRAME):
-
- finishedLoading = False
- if orca_state.locusOfFocus \
- and (orca_state.locusOfFocus.getRole() \
- == pyatspi.ROLE_LIST_ITEM) \
- and not self.inDocumentContent(orca_state.locusOfFocus):
- # The event is for the changing contents of the help
- # frame as the user navigates from topic to topic in
- # the list on the left. Ignore this.
- #
- return
-
- elif event.detail1:
- self._loadingDocumentContent = True
- message = messages.PAGE_LOADING_START
-
- elif event.source.name:
- message = messages.PAGE_LOADING_END_NAMED % event.source.name
- finishedLoading = True
-
- else:
- message = messages.PAGE_LOADING_END
- finishedLoading = True
-
- if not _settingsManager.getSetting('onlySpeakDisplayedText'):
- self.presentMessage(message)
-
- if finishedLoading:
- # Store the document frame otherwise the first time it
- # gains focus (e.g. the first time the user arrows off
- # of a link into non-focusable text), onStateFocused
- # will start chatting unnecessarily.
- #
- self._currentFrame = event.source
-
- # We first try to figure out where the caret is on
- # the newly loaded page. If it is on an editable
- # object (e.g., a text entry), then we present just
- # that object. Otherwise, we force the caret to the
- # top of the page and start a SayAll from that position.
- #
- [obj, characterOffset] = self.getCaretContext()
- atTop = False
- if not obj:
- self.clearCaretContext()
- [obj, characterOffset] = self.getCaretContext()
- atTop = True
-
- # If we found nothing, then don't do anything. Otherwise
- # determine if we should do a SayAll or not.
- #
- if not obj:
- return
- elif not atTop \
- and not obj.getState().contains(\
- pyatspi.STATE_FOCUSABLE):
- self.clearCaretContext()
- [obj, characterOffset] = self.getCaretContext()
- if not obj:
- return
-
- # For braille, we just show the current line
- # containing the caret. For speech, however, we
- # will start a Say All operation if the caret is
- # in an unfocusable area (e.g., it's not in a text
- # entry area such as Google's search text entry
- # or a link that we just returned to by pressing
- # the back button). Otherwise, we'll just speak the
- # line that the caret is on.
- #
- self.updateBraille(obj)
-
- if obj.getState().contains(pyatspi.STATE_FOCUSABLE):
- speech.speak(self.speechGenerator.generateSpeech(obj))
- elif not script_settings.sayAllOnLoad:
- self.speakContents(\
- self.getLineContentsAtOffset(obj,
- characterOffset))
- elif _settingsManager.getSetting('enableSpeech'):
- self.sayAll(None)
-
- return
-
default.Script.onStateChanged(self, event)
def onStateFocused(self, event):
diff --git a/src/orca/scripts/toolkits/WebKitGtk/script.py b/src/orca/scripts/toolkits/WebKitGtk/script.py
index 6fe0a22..e8838fc 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/script.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/script.py
@@ -85,8 +85,6 @@ class Script(default.Script):
self.onDocumentLoadComplete
listeners["document:load-stopped"] = \
self.onDocumentLoadStopped
- listeners["object:state-changed:busy"] = \
- self.onStateChanged
return listeners
@@ -294,27 +292,23 @@ class Script(default.Script):
default.Script.onFocus(self, event)
- def onStateChanged(self, event):
- """Called whenever an object's state changes.
+ def onBusyChanged(self, event):
+ """Callback for object:state-changed:busy accessibility events."""
- Arguments:
- - event: the Event
- """
-
- if not event.type.startswith("object:state-changed:busy"):
- default.Script.onStateChanged(self, event)
+ obj = event.source
+ try:
+ role = obj.getRole()
+ name = obj.name
+ except:
return
- if not event.source \
- or event.source.getRole() != pyatspi.ROLE_DOCUMENT_FRAME \
- or not self._isBrowser:
+ if role != pyatspi.ROLE_DOCUMENT_FRAME or not self._isBrowser:
return
if event.detail1:
self.presentMessage(messages.PAGE_LOADING_START)
- elif event.source.name:
- self.presentMessage(
- messages.PAGE_LOADING_END_NAMED % event.source.name)
+ elif name:
+ self.presentMessage(messages.PAGE_LOADING_END_NAMED % name)
else:
self.presentMessage(messages.PAGE_LOADING_END)
@@ -599,11 +593,11 @@ class Script(default.Script):
document = utils.findAncestor(
obj, lambda x: x.getRole() == pyatspi.ROLE_DOCUMENT_FRAME)
- if not document:
+ if not document or document.getState().contains(pyatspi.STATE_BUSY):
return
allTextObjs = utils.findAllDescendants(
- document, lambda x: 'Text' in utils.listInterfaces(x))
+ document, lambda x: x and 'Text' in utils.listInterfaces(x))
allTextObjs = allTextObjs[allTextObjs.index(obj):len(allTextObjs)]
textObjs = [x for x in allTextObjs if x.parent not in allTextObjs]
if not textObjs:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]