Started porting over some bug fixes and modernizations from Orca.
This commit is contained in:
@@ -540,7 +540,7 @@ class Component(Region):
|
||||
been scrolled off the display."""
|
||||
|
||||
if cthulhu_state.activeScript and cthulhu_state.activeScript.utilities.\
|
||||
grabFocusBeforeRouting(self.accessible, offset):
|
||||
grabFocusBeforeRouting(self.accessible):
|
||||
if AXObject.supports_component(self.accessible):
|
||||
try:
|
||||
Atspi.Component.grab_focus(self.accessible)
|
||||
|
||||
@@ -560,13 +560,12 @@ class Utilities:
|
||||
|
||||
return False
|
||||
|
||||
def grabFocusBeforeRouting(self, obj, offset):
|
||||
def grabFocusBeforeRouting(self, obj):
|
||||
"""Whether or not we should perform a grabFocus before routing
|
||||
the cursor via the braille cursor routing keys.
|
||||
|
||||
Arguments:
|
||||
- obj: the accessible object where the cursor should be routed
|
||||
- offset: the offset to which it should be routed
|
||||
|
||||
Returns True if we should do an explicit grabFocus on obj prior
|
||||
to routing the cursor.
|
||||
|
||||
@@ -81,9 +81,6 @@ class SpeechGenerator(speech_generator.SpeechGenerator):
|
||||
if not self._script.utilities.inDocumentContent(obj):
|
||||
return super()._generateAncestors(obj, **args)
|
||||
|
||||
if self._script.inSayAll() and obj == cthulhu_state.locusOfFocus:
|
||||
return []
|
||||
|
||||
result = []
|
||||
priorObj = args.get('priorObj')
|
||||
if priorObj and self._script.utilities.inDocumentContent(priorObj):
|
||||
|
||||
@@ -651,6 +651,10 @@ class SpeechGenerator(generator.Generator):
|
||||
Note that a 'role' attribute in args will override the
|
||||
accessible role of the obj.
|
||||
"""
|
||||
# Prevent role repetition when object is same as prior object
|
||||
if obj == args.get("priorObj"):
|
||||
return []
|
||||
|
||||
if _settingsManager.getSetting('onlySpeakDisplayedText'):
|
||||
return []
|
||||
|
||||
|
||||
@@ -596,15 +596,11 @@ class StructuralNavigation:
|
||||
#
|
||||
self.lastTableCell = [-1, -1]
|
||||
|
||||
self._objectCache = {}
|
||||
|
||||
self._inModalDialog = False
|
||||
|
||||
def clearCache(self, document=None):
|
||||
if document:
|
||||
self._objectCache[hash(document)] = {}
|
||||
else:
|
||||
self._objectCache = {}
|
||||
"""No-op for backwards compatibility. Caching has been removed."""
|
||||
pass
|
||||
|
||||
def structuralNavigationObjectCreator(self, name):
|
||||
"""This convenience method creates a StructuralNavigationObject
|
||||
@@ -794,7 +790,11 @@ class StructuralNavigation:
|
||||
structuralNavigationObject.present(cell, arg)
|
||||
|
||||
def _getAll(self, structuralNavigationObject, arg=None):
|
||||
"""Returns all the instances of structuralNavigationObject."""
|
||||
"""Returns all the instances of structuralNavigationObject.
|
||||
|
||||
Queries fresh each time without caching to ensure accurate results
|
||||
when returning to a page after switching applications.
|
||||
"""
|
||||
|
||||
modalDialog = self._script.utilities.getModalDialog(cthulhu_state.locusOfFocus)
|
||||
inModalDialog = bool(modalDialog)
|
||||
@@ -804,29 +804,11 @@ class StructuralNavigation:
|
||||
f"{self._inModalDialog} to {inModalDialog}"
|
||||
)
|
||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||
self.clearCache()
|
||||
self._inModalDialog = inModalDialog
|
||||
|
||||
def filterZombies(matchList):
|
||||
if not matchList:
|
||||
return []
|
||||
return [match for match in matchList if not self._script.utilities.isZombie(match)]
|
||||
|
||||
document = self._script.utilities.documentFrame()
|
||||
cache = self._objectCache.get(hash(document), {})
|
||||
key = f"{structuralNavigationObject.objType}:{arg}"
|
||||
matches = cache.get(key, [])
|
||||
if matches:
|
||||
matches = filterZombies(matches)
|
||||
if matches:
|
||||
tokens = ["STRUCTURAL NAVIGATION: Returning", len(matches), "matches from cache"]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
return matches.copy()
|
||||
|
||||
tokens = ["STRUCTURAL NAVIGATION: Cached matches are zombies; refreshing"]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
cache.pop(key, None)
|
||||
self._objectCache[hash(document)] = cache
|
||||
if not document:
|
||||
return []
|
||||
|
||||
if structuralNavigationObject.getter:
|
||||
matches = structuralNavigationObject.getter(document, arg)
|
||||
@@ -843,15 +825,12 @@ class StructuralNavigation:
|
||||
if inModalDialog:
|
||||
originalSize = len(matches)
|
||||
matches = [m for m in matches if AXObject.find_ancestor(m, lambda x: x == modalDialog)]
|
||||
tokens = ["STRUCTURAL NAVIGATION: Removed", {originalSize - len(matches)},
|
||||
tokens = ["STRUCTURAL NAVIGATION: Removed", originalSize - len(matches),
|
||||
"objects outside of modal dialog", modalDialog]
|
||||
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||
|
||||
matches = filterZombies(matches)
|
||||
rv = matches.copy()
|
||||
cache[key] = matches
|
||||
self._objectCache[hash(document)] = cache
|
||||
return rv
|
||||
# Filter out zombie objects and return
|
||||
return [m for m in matches if not self._script.utilities.isZombie(m)]
|
||||
|
||||
def goEdge(self, structuralNavigationObject, isStart, container=None, arg=None):
|
||||
if container is None:
|
||||
|
||||
Reference in New Issue
Block a user