[orca] Make presentation of the status bar fully generator-based
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] Make presentation of the status bar fully generator-based
- Date: Fri, 8 May 2020 23:23:32 +0000 (UTC)
commit 761aa5f40b5d72bb9819f110b71a0bbe2837e7bc
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Fri May 8 19:14:15 2020 -0400
Make presentation of the status bar fully generator-based
* When the command to speak the status bar is given, also generate
and display braille
* When a status bar claims focus (which it now can in, at least,
VSCode) present the status bar items in speech and braille
* Generate end-of-line indicators for braille labels, if the user
has that setting enabled. This causes status bar labels in apps
like LibreOffice Writer to not be a bunch of disjointed text.
And we normally display the end-of-line indicator for text
objects anyway.
* Harmonize link presentation between speech and braille. This
not only makes presentation consistent, but it eliminates things
like non-printable / private-use-area characters from showing
up in the braille of the status bar of (at least) VSCode.
src/orca/braille_generator.py | 18 ++++++++++++++++++
src/orca/formatting.py | 18 +++++++++++-------
src/orca/generator.py | 14 +++++++++++++-
src/orca/script_utilities.py | 10 +++++++++-
src/orca/scripts/default.py | 7 ++++++-
src/orca/speech_generator.py | 7 -------
6 files changed, 57 insertions(+), 17 deletions(-)
---
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
index d323e8968..131311a00 100644
--- a/src/orca/braille_generator.py
+++ b/src/orca/braille_generator.py
@@ -345,6 +345,24 @@ class BrailleGenerator(generator.Generator):
return result
+ def _generateStatusBar(self, obj, **args):
+ statusBar = self._script.utilities.statusBar(obj)
+ if not statusBar:
+ return []
+
+ items = self._script.utilities.statusBarItems(obj)
+ if not items:
+ return []
+
+ result = []
+ for child in items:
+ childResult = self.generate(child, includeContext=False)
+ if childResult:
+ result.extend(childResult)
+ result.append(braille.Region(" "))
+
+ return result
+
def _generateListBoxItemWidgets(self, obj, **args):
widgetRoles = [pyatspi.ROLE_CHECK_BOX,
pyatspi.ROLE_COMBO_BOX,
diff --git a/src/orca/formatting.py b/src/orca/formatting.py
index 81ae2cac9..d1af3f8fa 100644
--- a/src/orca/formatting.py
+++ b/src/orca/formatting.py
@@ -450,13 +450,16 @@ formatting = {
},
pyatspi.ROLE_STATIC: {
'unfocused': '(displayedText or name) + roleName',
- },
+ },
+ pyatspi.ROLE_STATUS_BAR: {
+ 'focused': 'labelAndName + roleName',
+ 'unfocused': 'labelAndName + roleName + pause + statusBar',
+ },
'ROLE_SWITCH': {
'focused': 'switchState',
'unfocused': 'labelOrName + roleName + switchState + availability + ' + MNEMONIC + ' +
accelerator',
'basicWhereAmI': 'labelOrName + roleName + switchState'
},
-
pyatspi.ROLE_TABLE: {
'focused': 'leaving or (labelAndName + pause + table)',
'unfocused': 'labelAndName + pause + table',
@@ -661,13 +664,10 @@ formatting = {
asString(labelAndName + value + roleName + required))]',
},
pyatspi.ROLE_LABEL: {
- 'focused': '[Text(obj, asString(labelAndName))]',
- 'unfocused': '[Text(obj, asString(labelAndName))]'
+ 'unfocused': BRAILLE_TEXT
},
pyatspi.ROLE_LINK: {
- 'unfocused': '[Link(obj, asString(currentLineText)\
- or asString(displayedText)\
- or asString(name))] \
+ 'unfocused': '[Link(obj, asString(name or displayedText))] \
+ (roleName and [Region(" " + asString(roleName))])',
},
pyatspi.ROLE_LIST: {
@@ -777,6 +777,10 @@ formatting = {
+ (required and [Region(" " + asString(required))] or [])\
+ (readOnly and [Region(" " + asString(readOnly))] or [])'
},
+ pyatspi.ROLE_STATUS_BAR: {
+ 'unfocused': '[Component(obj, asString(labelOrName + roleName))]\
+ + [Region(" ")] + statusBar',
+ },
'ROLE_SWITCH' : {
'unfocused': '[Component(obj,\
asString((labelOrName or description) + roleName),\
diff --git a/src/orca/generator.py b/src/orca/generator.py
index b8e350f92..94f1964cd 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -287,6 +287,13 @@ class Generator:
# Subclasses must override this.
return []
+ def _fallBackOnDescriptionForName(self, obj, **args):
+ role = args.get('role', obj.getRole())
+ if role == pyatspi.ROLE_LABEL:
+ return False
+
+ return True
+
def _generateName(self, obj, **args):
"""Returns an array of strings for use by speech and braille that
represent the name of the object. If the object is directly
@@ -306,7 +313,7 @@ class Generator:
name = obj.name
if name:
result.append(name)
- else:
+ elif self._fallBackOnDescriptionForName(obj, **args):
try:
description = obj.description
except (LookupError, RuntimeError):
@@ -438,6 +445,11 @@ class Generator:
result.append(label)
return result
+ def generateStatusBar(self, obj, **args):
+ """Returns an array of strings that represent a status bar."""
+
+ return self._generateStatusBar(obj, **args)
+
#####################################################################
# #
# Image information #
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 1e041ad8a..b19e4bf4d 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -2102,6 +2102,9 @@ class Utilities:
if objects:
return objects
+ if role == pyatspi.ROLE_LABEL and not (root.name or self.queryNonEmptyText(root)):
+ return []
+
containers = [pyatspi.ROLE_CANVAS,
pyatspi.ROLE_FILLER,
pyatspi.ROLE_IMAGE,
@@ -2200,7 +2203,12 @@ class Utilities:
if not (obj and obj.getRole() == pyatspi.ROLE_STATUS_BAR):
return []
- return self.getOnScreenObjects(obj)
+ items = self._script.pointOfReference.get('statusBarItems')
+ if not items:
+ items = self.getOnScreenObjects(obj)
+ self._script.pointOfReference['statusBarItems'] = items
+
+ return items
def statusBar(self, obj):
"""Returns the status bar in the window which contains obj.
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index 36f560eb7..e92c0db87 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -1246,7 +1246,12 @@ class Script(script.Script):
frame, dialog = self.utilities.frameAndDialog(obj)
if frame:
- speech.speak(self.speechGenerator.generateStatusBar(frame))
+ statusbar = self.utilities.statusBar(frame)
+ if statusbar:
+ self.pointOfReference['statusBarItems'] = None
+ self.presentObject(statusbar)
+ self.pointOfReference['statusBarItems'] = None
+
infobar = self.utilities.infoBar(frame)
if infobar:
speech.speak(self.speechGenerator.generateSpeech(infobar))
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index 52512ff8e..65978b43d 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -2336,13 +2336,6 @@ class SpeechGenerator(generator.Generator):
return result
- def generateStatusBar(self, obj, **args):
- """Returns an array of strings (and possibly voice and audio
- specifications) that represent the status bar of the window
- containing the object.
- """
- return self._generateStatusBar(obj, **args)
-
def generateTitle(self, obj, **args):
"""Returns an array of strings (and possibly voice and audio
specifications) that represent the title of the window, obj.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]