[orca] Create a general (non-app-specific) terminal script
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] Create a general (non-app-specific) terminal script
- Date: Tue, 23 Aug 2016 08:49:07 +0000 (UTC)
commit 5a6703107310060ac9e4b0d0bee92240aa8ac017
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Tue Aug 23 04:36:36 2016 -0400
Create a general (non-app-specific) terminal script
Also work around several issues we're seeing in the accessible text
support of VTE.
configure.ac | 4 +-
src/orca/generator.py | 5 -
src/orca/input_event.py | 5 +
src/orca/script_manager.py | 36 +++++-
src/orca/script_utilities.py | 55 +-------
src/orca/scripts/Makefile.am | 2 +-
src/orca/scripts/apps/Makefile.am | 1 -
src/orca/scripts/apps/__init__.py | 1 -
src/orca/scripts/apps/gnome-terminal/Makefile.am | 5 -
src/orca/scripts/apps/gnome-terminal/script.py | 107 ---------------
src/orca/scripts/default.py | 39 +-----
src/orca/scripts/terminal/Makefile.am | 8 +
.../{apps/gnome-terminal => terminal}/__init__.py | 8 +-
src/orca/scripts/terminal/braille_generator.py | 38 +++++
src/orca/scripts/terminal/script.py | 144 ++++++++++++++++++++
src/orca/scripts/terminal/script_utilities.py | 110 +++++++++++++++
src/orca/scripts/terminal/speech_generator.py | 38 +++++
src/orca/scripts/toolkits/gtk/script.py | 5 -
18 files changed, 393 insertions(+), 218 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a0979d6..230f6ff 100644
--- a/configure.ac
+++ b/configure.ac
@@ -106,7 +106,6 @@ src/orca/scripts/apps/gnome-panel/Makefile
src/orca/scripts/apps/gnome-screensaver-dialog/Makefile
src/orca/scripts/apps/gnome-search-tool/Makefile
src/orca/scripts/apps/gnome-shell/Makefile
-src/orca/scripts/apps/gnome-terminal/Makefile
src/orca/scripts/apps/gnome-window-properties/Makefile
src/orca/scripts/apps/gtk-window-decorator/Makefile
src/orca/scripts/apps/Instantbird/Makefile
@@ -122,8 +121,9 @@ src/orca/scripts/apps/soffice/Makefile
src/orca/scripts/apps/SeaMonkey/Makefile
src/orca/scripts/apps/Thunderbird/Makefile
src/orca/scripts/apps/xfwm4/Makefile
-src/orca/scripts/toolkits/Makefile
+src/orca/scripts/terminal/Makefile
src/orca/scripts/web/Makefile
+src/orca/scripts/toolkits/Makefile
src/orca/scripts/toolkits/Gecko/Makefile
src/orca/scripts/toolkits/J2SE-access-bridge/Makefile
src/orca/scripts/toolkits/clutter/Makefile
diff --git a/src/orca/generator.py b/src/orca/generator.py
index 38a38ba..cf193ad 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -387,11 +387,6 @@ class Generator:
role = args.get('role', obj.getRole())
- # The text in the description is the same as the text in the page
- # tab and similar to (and sometimes the same as) the prompt.
- if role == pyatspi.ROLE_TERMINAL:
- return []
-
# Unity Panel Service menubar items are labels which claim focus and
# have an accessible description of the text + underscore symbol used
# to create the mnemonic. We'll work around that here for now.
diff --git a/src/orca/input_event.py b/src/orca/input_event.py
index d0fb0f2..e4a79c6 100644
--- a/src/orca/input_event.py
+++ b/src/orca/input_event.py
@@ -458,6 +458,11 @@ class KeyboardEvent(InputEvent):
return keynames.getKeyName(self.event_string)
+ def getObject(self):
+ """Returns the object believed to be associated with this key event."""
+
+ return self._obj
+
def _getUserHandler(self):
# TODO - JD: This should go away once plugin support is in place.
try:
diff --git a/src/orca/script_manager.py b/src/orca/script_manager.py
index 131868c..0b408ba 100644
--- a/src/orca/script_manager.py
+++ b/src/orca/script_manager.py
@@ -37,6 +37,7 @@ class ScriptManager:
debug.println(debug.LEVEL_INFO, 'SCRIPT MANAGER: Initializing', True)
self.appScripts = {}
self.toolkitScripts = {}
+ self.customScripts = {}
self._appModules = apps.__all__
self._toolkitModules = toolkits.__all__
self._defaultScript = None
@@ -62,8 +63,6 @@ class ScriptManager:
'gnome-calculator': 'gcalctool',
'marco': 'metacity',
'Nereid': 'Banshee',
- 'vte': 'gnome-terminal',
- 'gnome-terminal-server': 'gnome-terminal',
'mate-notification-daemon': 'notification-daemon',
}
@@ -90,6 +89,7 @@ class ScriptManager:
self.setActiveScript(None, "deactivate")
self.appScripts = {}
self.toolkitScripts = {}
+ self.customScripts = {}
debug.println(debug.LEVEL_INFO, 'SCRIPT MANAGER: Deactivated', True)
def getModuleName(self, app):
@@ -139,6 +139,17 @@ class ScriptManager:
return name
+ def _scriptForRole(self, obj):
+ try:
+ role = obj.getRole()
+ except:
+ return ''
+
+ if role == pyatspi.ROLE_TERMINAL:
+ return 'terminal'
+
+ return ''
+
def _newNamedScript(self, app, name):
"""Attempts to locate and load the named module. If successful, returns
a script based on this module."""
@@ -221,9 +232,19 @@ class ScriptManager:
Returns an instance of a Script.
"""
+ customScript = None
appScript = None
toolkitScript = None
+ roleName = self._scriptForRole(obj)
+ if roleName:
+ customScripts = self.customScripts.get(app, {})
+ customScript = customScripts.get(roleName)
+ if not customScript:
+ customScript = self._newNamedScript(app, roleName)
+ customScripts[roleName] = customScript
+ self.customScripts[app] = customScripts
+
objToolkit = self._toolkitForObject(obj)
if objToolkit:
toolkitScripts = self.toolkitScripts.get(app, {})
@@ -247,6 +268,9 @@ class ScriptManager:
debug.println(debug.LEVEL_WARNING, msg, True)
appScript = self.getDefaultScript()
+ if customScript:
+ return customScript
+
# Only defer to the toolkit script for this object if the app script
# is based on a different toolkit.
if toolkitScript \
@@ -301,6 +325,14 @@ class ScriptManager:
for toolkitScript in toolkitScripts.values():
del toolkitScript
+ try:
+ customScripts = self.customScripts.pop(app)
+ except KeyError:
+ pass
+ else:
+ for customScript in customScripts.values():
+ del customScript
+
del app
_manager = ScriptManager()
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 389f0ca..df5c8fa 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -1356,8 +1356,7 @@ class Utilities:
return obj and obj.getRole() in (pyatspi.ROLE_TEXT,
pyatspi.ROLE_ENTRY,
- pyatspi.ROLE_PARAGRAPH,
- pyatspi.ROLE_TERMINAL)
+ pyatspi.ROLE_PARAGRAPH)
@staticmethod
def knownApplications():
@@ -2412,9 +2411,6 @@ class Utilities:
if event.any_data:
return event.any_data
- msg = "ERROR: Broken text insertion event"
- debug.println(debug.LEVEL_INFO, msg, True)
-
try:
role = event.source.getRole()
except:
@@ -2422,6 +2418,9 @@ class Utilities:
debug.println(debug.LEVEL_INFO, msg, True)
role = None
+ msg = "ERROR: Broken text insertion event"
+ debug.println(debug.LEVEL_INFO, msg, True)
+
if role == pyatspi.ROLE_PASSWORD_TEXT:
text = self.queryNonEmptyText(event.source)
if text:
@@ -2626,8 +2625,6 @@ class Utilities:
obj = orca_state.locusOfFocus
role = obj.getRole()
- if role == pyatspi.ROLE_TERMINAL:
- return True
if role == pyatspi.ROLE_PASSWORD_TEXT:
return False
@@ -4102,53 +4099,9 @@ class Utilities:
return role in roles
def treatEventAsTerminalCommand(self, event):
- try:
- role = event.source.getRole()
- except:
- msg = "ERROR: Exception getting role of %s" % event.source
- debug.println(debug.LEVEL_INFO, msg, True)
- return False
-
- if role != pyatspi.ROLE_TERMINAL:
- return False
-
- if self.lastInputEventWasCommand():
- return True
-
- if event.type.startswith("object:text-changed:insert") and event.any_data.strip():
- keyString, mods = self.lastKeyAndModifiers()
- if keyString in ["Return", "Tab", "space", " "]:
- return True
- if mods & keybindings.ALT_MODIFIER_MASK:
- return True
- if len(event.any_data) > 1 and self.lastInputEventWasPrintableKey():
- return True
-
return False
def treatEventAsTerminalNoise(self, event):
- try:
- role = event.source.getRole()
- except:
- msg = "ERROR: Exception getting role of %s" % event.source
- debug.println(debug.LEVEL_INFO, msg, True)
- return False
-
- if role != pyatspi.ROLE_TERMINAL:
- return False
-
- if self.lastInputEventWasCommand():
- return False
-
- if event.type.startswith("object:text-changed:delete") and event.any_data.strip():
- keyString, mods = self.lastKeyAndModifiers()
- if keyString in ["Return", "Tab", "space", " "]:
- return True
- if mods & keybindings.ALT_MODIFIER_MASK:
- return True
- if len(event.any_data) > 1 and self.lastInputEventWasPrintableKey():
- return True
-
return False
def isPresentableTextChangedEventForLocusOfFocus(self, event):
diff --git a/src/orca/scripts/Makefile.am b/src/orca/scripts/Makefile.am
index bd5c6c3..60c4a4a 100644
--- a/src/orca/scripts/Makefile.am
+++ b/src/orca/scripts/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = apps toolkits web
+SUBDIRS = apps toolkits terminal web
orca_python_PYTHON = \
__init__.py \
diff --git a/src/orca/scripts/apps/Makefile.am b/src/orca/scripts/apps/Makefile.am
index c485655..3b1b955 100644
--- a/src/orca/scripts/apps/Makefile.am
+++ b/src/orca/scripts/apps/Makefile.am
@@ -16,7 +16,6 @@ SUBDIRS = \
gnome-screensaver-dialog \
gnome-shell \
gnome-search-tool \
- gnome-terminal \
gnome-window-properties \
gtk-window-decorator \
Instantbird \
diff --git a/src/orca/scripts/apps/__init__.py b/src/orca/scripts/apps/__init__.py
index 38d33e9..95ecd98 100644
--- a/src/orca/scripts/apps/__init__.py
+++ b/src/orca/scripts/apps/__init__.py
@@ -15,7 +15,6 @@ __all__ = ['Banshee',
'gnome-screensaver-dialog',
'gnome-search-tool',
'gnome-shell',
- 'gnome-terminal',
'gnome-window-properties',
'gtk-window-decorator',
'Instantbird',
diff --git a/src/orca/scripts/default.py b/src/orca/scripts/default.py
index 2c34ecf..6f44852 100644
--- a/src/orca/scripts/default.py
+++ b/src/orca/scripts/default.py
@@ -2507,11 +2507,6 @@ class Script(script.Script):
if not self.utilities.isPresentableTextChangedEventForLocusOfFocus(event):
return
- if self.utilities.treatEventAsTerminalNoise(event):
- msg = "DEFAULT: Deletion is believed to be noise"
- debug.println(debug.LEVEL_INFO, msg, True)
- return
-
self.utilities.handleUndoTextEvent(event)
orca.setLocusOfFocus(event, event.source, False)
@@ -2585,9 +2580,6 @@ class Script(script.Script):
if self.utilities.lastInputEventWasCommand():
msg = "DEFAULT: Insertion is believed to be due to command"
debug.println(debug.LEVEL_INFO, msg, True)
- elif self.utilities.treatEventAsTerminalCommand(event):
- msg = "DEFAULT: Insertion is believed to be due to terminal command"
- debug.println(debug.LEVEL_INFO, msg, True)
elif self.utilities.isMiddleMouseButtonTextInsertionEvent(event):
msg = "DEFAULT: Insertion is believed to be due to middle mouse button"
debug.println(debug.LEVEL_INFO, msg, True)
@@ -3472,14 +3464,6 @@ class Script(script.Script):
[lineString, startOffset, endOffset] = \
text.getTextAtOffset(offset, mode)
- # [[[WDW - HACK: well...gnome-terminal sometimes wants to
- # give us outrageous values back from getTextAtOffset
- # (see http://bugzilla.gnome.org/show_bug.cgi?id=343133),
- # so we try to handle it.]]]
- #
- if startOffset < 0:
- break
-
# [[[WDW - HACK: this is here because getTextAtOffset
# tends not to be implemented consistently across toolkits.
# Sometimes it behaves properly (i.e., giving us an endOffset
@@ -3714,25 +3698,7 @@ class Script(script.Script):
if role == pyatspi.ROLE_PASSWORD_TEXT and not event.isLockingKey():
return False
- # Worst. Hack. EVER. We have no reliable way of knowing a password is
- # being entered into a terminal -- other than the fact that the text
- # typed ain't there. As a result, we have to do special things when
- # not in special modes. :( See bgo 668025.
- if role == pyatspi.ROLE_TERMINAL:
- if not event.isPressedKey():
- try:
- text = orca_state.locusOfFocus.queryText()
- o = text.caretOffset
- string = text.getText(o-1, o)
- except:
- pass
- else:
- if not event.event_string in [string, 'space']:
- return False
- elif not (orca_state.learnModeEnabled or event.isLockingKey()):
- return False
-
- elif not event.isPressedKey():
+ if not event.isPressedKey():
return False
braille.displayKeyEvent(event)
@@ -3748,6 +3714,9 @@ class Script(script.Script):
if event.isPrintableKey():
string = event.event_string
+ msg = "DEFAULT: Presenting keyboard event"
+ debug.println(debug.LEVEL_INFO, msg, True)
+
voice = self.speechGenerator.voice(string=string)
speech.speakKeyEvent(event, voice)
return True
diff --git a/src/orca/scripts/terminal/Makefile.am b/src/orca/scripts/terminal/Makefile.am
new file mode 100644
index 0000000..9a2b4a2
--- /dev/null
+++ b/src/orca/scripts/terminal/Makefile.am
@@ -0,0 +1,8 @@
+orca_python_PYTHON = \
+ __init__.py \
+ braille_generator.py \
+ script.py \
+ script_utilities.py \
+ speech_generator.py
+
+orca_pythondir=$(pkgpythondir)/scripts/terminal
diff --git a/src/orca/scripts/apps/gnome-terminal/__init__.py b/src/orca/scripts/terminal/__init__.py
similarity index 78%
rename from src/orca/scripts/apps/gnome-terminal/__init__.py
rename to src/orca/scripts/terminal/__init__.py
index 52f01ef..b616fd0 100644
--- a/src/orca/scripts/apps/gnome-terminal/__init__.py
+++ b/src/orca/scripts/terminal/__init__.py
@@ -1,6 +1,7 @@
# Orca
#
-# Copyright 2005-2008 Sun Microsystems Inc.
+# Copyright 2016 Igalia, S.L.
+# Author: Joanmarie Diggs <jdiggs igalia com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -17,7 +18,8 @@
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
# Boston MA 02110-1301 USA.
-"""Custom script for gnome-terminal."""
-
+from .braille_generator import BrailleGenerator
from .script import Script
+from .speech_generator import SpeechGenerator
+from .script_utilities import Utilities
diff --git a/src/orca/scripts/terminal/braille_generator.py b/src/orca/scripts/terminal/braille_generator.py
new file mode 100644
index 0000000..d52b099
--- /dev/null
+++ b/src/orca/scripts/terminal/braille_generator.py
@@ -0,0 +1,38 @@
+# Orca
+#
+# Copyright 2016 Igalia, S.L.
+# Author: Joanmarie Diggs <jdiggs igalia com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA 02110-1301 USA.
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2016 Igalia, S.L."
+__license__ = "LGPL"
+
+from orca import braille_generator
+
+
+class BrailleGenerator(braille_generator.BrailleGenerator):
+
+ def __init__(self, script):
+ super().__init__(script)
+
+ def _generateDescription(self, obj, **args):
+ # The text in the description is the same as the text in the page
+ # tab and similar to (and sometimes the same as) the prompt.
+ return []
diff --git a/src/orca/scripts/terminal/script.py b/src/orca/scripts/terminal/script.py
new file mode 100644
index 0000000..66f33a7
--- /dev/null
+++ b/src/orca/scripts/terminal/script.py
@@ -0,0 +1,144 @@
+# Orca
+#
+# Copyright 2016 Igalia, S.L.
+# Author: Joanmarie Diggs <jdiggs igalia com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA 02110-1301 USA.
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2016 Igalia, S.L."
+__license__ = "LGPL"
+
+from orca import debug
+from orca import orca
+from orca import orca_state
+from orca import speech
+from orca.scripts import default
+
+from .braille_generator import BrailleGenerator
+from .speech_generator import SpeechGenerator
+from .script_utilities import Utilities
+
+
+class Script(default.Script):
+
+ def __init__(self, app):
+ super().__init__(app)
+ self.presentIfInactive = False
+
+ def deactivate(self):
+ """Called when this script is deactivated."""
+
+ self.utilities.clearCache()
+ super().deactivate()
+
+ def getBrailleGenerator(self):
+ """Returns the braille generator for this script."""
+
+ return BrailleGenerator(self)
+
+ def getSpeechGenerator(self):
+ """Returns the speech generator for this script."""
+
+ return SpeechGenerator(self)
+
+ def getUtilities(self):
+ """Returns the utilites for this script."""
+
+ return Utilities(self)
+
+ def locusOfFocusChanged(self, event, oldFocus, newFocus):
+ """Handles changes of focus of interest to the script."""
+
+ super().locusOfFocusChanged(event, oldFocus, newFocus)
+
+ def onCaretMoved(self, event):
+ """Callback for object:text-caret-moved accessibility events."""
+
+ super().onCaretMoved(event)
+
+ def onFocus(self, event):
+ """Callback for focus: accessibility events."""
+
+ # https://bugzilla.gnome.org/show_bug.cgi?id=748311
+ orca.setLocusOfFocus(event, event.source)
+
+ def onTextDeleted(self, event):
+ """Callback for object:text-changed:delete accessibility events."""
+
+ if self.utilities.treatEventAsTerminalNoise(event):
+ msg = "TERMINAL: Deletion is believed to be noise"
+ debug.println(debug.LEVEL_INFO, msg, True)
+ return
+
+ super().onTextDeleted(event)
+
+ def onTextInserted(self, event):
+ """Callback for object:text-changed:insert accessibility events."""
+
+ if not self.utilities.treatEventAsTerminalCommand(event):
+ super().onTextInserted(event)
+ return
+
+ msg = "TERMINAL: Insertion is believed to be due to terminal command"
+ debug.println(debug.LEVEL_INFO, msg, True)
+
+ oldString = event.any_data
+ newString = self.utilities.insertedText(event)
+ if oldString != newString:
+ msg = "TERMINAL: Adjusting event string to: %s" % newString
+ debug.println(debug.LEVEL_INFO, msg, True)
+
+ if len(newString) == 1:
+ self.speakCharacter(newString)
+ else:
+ voice = self.speechGenerator.voice(string=newString)
+ speech.speak(newString, voice)
+
+ def presentKeyboardEvent(self, event):
+ if orca_state.learnModeEnabled or not event.isPrintableKey():
+ return super().presentKeyboardEvent(event)
+
+ if event.isPressedKey():
+ return False
+
+ self._sayAllIsInterrupted = False
+ self.utilities.clearCachedCommandState()
+ if event.shouldEcho == False or event.isOrcaModified():
+ return False
+
+ # We have no reliable way of knowing a password is being entered into
+ # a terminal -- other than the fact that the text typed isn't there.
+ try:
+ text = event.getObject().queryText()
+ offset = text.caretOffset
+ prevChar = text.getText(offset - 1, offset)
+ char = text.getText(offset, offset + 1)
+ except:
+ return False
+
+ string = event.event_string
+ if string not in [prevChar, "space", char]:
+ return False
+
+ msg = "TERMINAL: Presenting keyboard event %s" % string
+ debug.println(debug.LEVEL_INFO, msg, True)
+
+ voice = self.speechGenerator.voice(string=string)
+ speech.speakKeyEvent(event, voice)
+ return True
diff --git a/src/orca/scripts/terminal/script_utilities.py b/src/orca/scripts/terminal/script_utilities.py
new file mode 100644
index 0000000..3a8e1bd
--- /dev/null
+++ b/src/orca/scripts/terminal/script_utilities.py
@@ -0,0 +1,110 @@
+# Orca
+#
+# Copyright 2016 Igalia, S.L.
+# Author: Joanmarie Diggs <jdiggs igalia com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA 02110-1301 USA.
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2016 Igalia, S.L."
+__license__ = "LGPL"
+
+import pyatspi
+
+from orca import debug
+from orca import keybindings
+from orca import script_utilities
+from orca import settings_manager
+
+_settingsManager = settings_manager.getManager()
+
+
+class Utilities(script_utilities.Utilities):
+
+ def __init__(self, script):
+ super().__init__(script)
+
+ def clearCache(self):
+ pass
+
+ def insertedText(self, event):
+ if len(event.any_data) == 1:
+ return event.any_data
+
+ try:
+ text = event.source.queryText()
+ except:
+ msg = "ERROR: Exception querying text for %s" % event.source
+ debug.println(debug.LEVEL_INFO, msg, True)
+ return event.any_data
+
+ start, end = event.detail1, event.detail1 + len(event.any_data)
+ boundary = pyatspi.TEXT_BOUNDARY_LINE_START
+
+ firstLine = text.getTextAtOffset(start, boundary)
+ if firstLine != ("", 0, 0):
+ start = firstLine[1]
+
+ lastLine = text.getTextAtOffset(end - 1, boundary)
+ if lastLine != ("", 0, 0):
+ end = min(lastLine[2], text.caretOffset)
+
+ return text.getText(start, end)
+
+ def isTextArea(self, obj):
+ return True
+
+ def treatEventAsTerminalCommand(self, event):
+ if self.lastInputEventWasCommand():
+ return True
+
+ if event.type.startswith("object:text-changed:insert") and event.any_data.strip():
+ keyString, mods = self.lastKeyAndModifiers()
+ if keyString in ["Return", "Tab", "space", " "]:
+ return True
+ if mods & keybindings.ALT_MODIFIER_MASK:
+ return True
+ if len(event.any_data) > 1 and self.lastInputEventWasPrintableKey():
+ return True
+
+ return False
+
+ def treatEventAsTerminalNoise(self, event):
+ if self.lastInputEventWasCommand():
+ return False
+
+ if event.type.startswith("object:text-changed:delete") and event.any_data.strip():
+ keyString, mods = self.lastKeyAndModifiers()
+ if keyString in ["Return", "Tab", "space", " "]:
+ return True
+ if mods & keybindings.ALT_MODIFIER_MASK:
+ return True
+ if len(event.any_data) > 1 and self.lastInputEventWasPrintableKey():
+ return True
+
+ return False
+
+ def willEchoCharacter(self, event):
+ if not _settingsManager.getSetting("enableEchoByCharacter"):
+ return False
+
+ if len(event.event_string) != 1 \
+ or event.modifiers & keybindings.ORCA_CTRL_MODIFIER_MASK:
+ return False
+
+ return True
diff --git a/src/orca/scripts/terminal/speech_generator.py b/src/orca/scripts/terminal/speech_generator.py
new file mode 100644
index 0000000..e6167b1
--- /dev/null
+++ b/src/orca/scripts/terminal/speech_generator.py
@@ -0,0 +1,38 @@
+# Orca
+#
+# Copyright 2016 Igalia, S.L.
+# Author: Joanmarie Diggs <jdiggs igalia com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
+# Boston MA 02110-1301 USA.
+
+__id__ = "$Id$"
+__version__ = "$Revision$"
+__date__ = "$Date$"
+__copyright__ = "Copyright (c) 2016 Igalia, S.L."
+__license__ = "LGPL"
+
+from orca import speech_generator
+
+
+class SpeechGenerator(speech_generator.SpeechGenerator):
+
+ def __init__(self, script):
+ super().__init__(script)
+
+ def _generateDescription(self, obj, **args):
+ # The text in the description is the same as the text in the page
+ # tab and similar to (and sometimes the same as) the prompt.
+ return []
diff --git a/src/orca/scripts/toolkits/gtk/script.py b/src/orca/scripts/toolkits/gtk/script.py
index 164677c..a6507ca 100644
--- a/src/orca/scripts/toolkits/gtk/script.py
+++ b/src/orca/scripts/toolkits/gtk/script.py
@@ -129,11 +129,6 @@ class Script(default.Script):
orca.setLocusOfFocus(event, event.source)
return
- # https://bugzilla.gnome.org/show_bug.cgi?id=748311
- if role == pyatspi.ROLE_TERMINAL:
- orca.setLocusOfFocus(event, event.source)
- return
-
# https://bugzilla.gnome.org/show_bug.cgi?id=720987
if role == pyatspi.ROLE_TABLE_COLUMN_HEADER:
orca.setLocusOfFocus(event, event.source)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]