Fixed browser crashing on some button activations, I think.
This commit is contained in:
@@ -509,8 +509,22 @@ class MouseReviewer:
|
|||||||
cthulhu_state.activeScript.presentMessage(msg)
|
cthulhu_state.activeScript.presentMessage(msg)
|
||||||
|
|
||||||
def _update_workspace_windows(self):
|
def _update_workspace_windows(self):
|
||||||
self._windows = [w for w in self._all_windows
|
"""Refresh cached windows for the current workspace."""
|
||||||
if w.is_on_workspace(self._workspace)]
|
|
||||||
|
if not self._workspace:
|
||||||
|
self._windows = []
|
||||||
|
return
|
||||||
|
|
||||||
|
windows = []
|
||||||
|
for w in self._all_windows:
|
||||||
|
try:
|
||||||
|
if w and w.is_on_workspace(self._workspace):
|
||||||
|
windows.append(w)
|
||||||
|
except TypeError:
|
||||||
|
# Seen when Wnck hands us None/invalid workspace references mid-switch.
|
||||||
|
continue
|
||||||
|
|
||||||
|
self._windows = windows
|
||||||
|
|
||||||
def _on_stacking_changed(self, screen):
|
def _on_stacking_changed(self, screen):
|
||||||
"""Callback for Wnck's window-stacking-changed signal."""
|
"""Callback for Wnck's window-stacking-changed signal."""
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ class Script(default.Script):
|
|||||||
self._inFocusMode = False
|
self._inFocusMode = False
|
||||||
self._focusModeIsSticky = False
|
self._focusModeIsSticky = False
|
||||||
self._browseModeIsSticky = False
|
self._browseModeIsSticky = False
|
||||||
|
self._navSuspended = False
|
||||||
|
self._structNavWasEnabled = None
|
||||||
|
|
||||||
if _settingsManager.getSetting('caretNavigationEnabled') is None:
|
if _settingsManager.getSetting('caretNavigationEnabled') is None:
|
||||||
_settingsManager.setSetting('caretNavigationEnabled', True)
|
_settingsManager.setSetting('caretNavigationEnabled', True)
|
||||||
@@ -114,6 +116,22 @@ class Script(default.Script):
|
|||||||
self.attributeNamesDict["text-align"] = "justification"
|
self.attributeNamesDict["text-align"] = "justification"
|
||||||
self.attributeNamesDict["text-indent"] = "indent"
|
self.attributeNamesDict["text-indent"] = "indent"
|
||||||
|
|
||||||
|
def activate(self):
|
||||||
|
"""Called when this script is activated."""
|
||||||
|
|
||||||
|
tokens = ["WEB: Activating script for", self.app]
|
||||||
|
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||||
|
|
||||||
|
focus = cthulhu_state.locusOfFocus
|
||||||
|
inApp = AXUtilities.get_application(focus) == self.app if focus else False
|
||||||
|
inDoc = self.utilities.inDocumentContent(focus)
|
||||||
|
suspend = not (inDoc and inApp)
|
||||||
|
reason = f"script activation, not in document content in this app: {suspend}"
|
||||||
|
|
||||||
|
self._setNavigationSuspended(suspend, reason)
|
||||||
|
|
||||||
|
super().activate()
|
||||||
|
|
||||||
def deactivate(self):
|
def deactivate(self):
|
||||||
"""Called when this script is deactivated."""
|
"""Called when this script is deactivated."""
|
||||||
|
|
||||||
@@ -130,8 +148,30 @@ class Script(default.Script):
|
|||||||
self._preMouseOverContext = None, -1
|
self._preMouseOverContext = None, -1
|
||||||
self._inMouseOverObject = False
|
self._inMouseOverObject = False
|
||||||
self.utilities.clearCachedObjects()
|
self.utilities.clearCachedObjects()
|
||||||
|
# Ensure navigation commands are re-enabled for the next activation.
|
||||||
|
self._setNavigationSuspended(False, "script deactivation")
|
||||||
self.removeKeyGrabs()
|
self.removeKeyGrabs()
|
||||||
|
|
||||||
|
def _setNavigationSuspended(self, suspend, reason=""):
|
||||||
|
"""Suspend or resume navigation command handling (caret & structural)."""
|
||||||
|
|
||||||
|
if suspend == self._navSuspended:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._navSuspended = suspend
|
||||||
|
|
||||||
|
# Structural navigation has an enabled flag we can toggle.
|
||||||
|
if suspend:
|
||||||
|
self._structNavWasEnabled = self.structuralNavigation.enabled
|
||||||
|
self.structuralNavigation.enabled = False
|
||||||
|
else:
|
||||||
|
if self._structNavWasEnabled is not None:
|
||||||
|
self.structuralNavigation.enabled = self._structNavWasEnabled
|
||||||
|
self._structNavWasEnabled = None
|
||||||
|
|
||||||
|
tokens = ["WEB: Navigation suspended:", suspend, reason]
|
||||||
|
debug.printTokens(debug.LEVEL_INFO, tokens, True)
|
||||||
|
|
||||||
def getAppKeyBindings(self):
|
def getAppKeyBindings(self):
|
||||||
"""Returns the application-specific keybindings for this script."""
|
"""Returns the application-specific keybindings for this script."""
|
||||||
|
|
||||||
@@ -1164,6 +1204,12 @@ class Script(default.Script):
|
|||||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if self._navSuspended:
|
||||||
|
if debugOutput:
|
||||||
|
msg = "WEB: Not using caret navigation: navigation suspended."
|
||||||
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
|
return False
|
||||||
|
|
||||||
if not self.utilities.inDocumentContent():
|
if not self.utilities.inDocumentContent():
|
||||||
if debugOutput:
|
if debugOutput:
|
||||||
tokens = ["WEB: Not using caret navigation: locusOfFocus",
|
tokens = ["WEB: Not using caret navigation: locusOfFocus",
|
||||||
@@ -1198,6 +1244,12 @@ class Script(default.Script):
|
|||||||
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if self._navSuspended:
|
||||||
|
if debugOutput:
|
||||||
|
msg = "WEB: Not using structural navigation: navigation suspended."
|
||||||
|
debug.printMessage(debug.LEVEL_INFO, msg, True)
|
||||||
|
return False
|
||||||
|
|
||||||
if not self.utilities.inDocumentContent():
|
if not self.utilities.inDocumentContent():
|
||||||
if debugOutput:
|
if debugOutput:
|
||||||
tokens = ["WEB: Not using structural navigation: locusOfFocus",
|
tokens = ["WEB: Not using structural navigation: locusOfFocus",
|
||||||
|
|||||||
@@ -4277,7 +4277,9 @@ class Utilities(script_utilities.Utilities):
|
|||||||
Atspi.Role.LIST_BOX,
|
Atspi.Role.LIST_BOX,
|
||||||
Atspi.Role.PASSWORD_TEXT,
|
Atspi.Role.PASSWORD_TEXT,
|
||||||
Atspi.Role.RADIO_BUTTON]
|
Atspi.Role.RADIO_BUTTON]
|
||||||
rv = role in roles and not self.displayedLabel(obj)
|
get_disp = getattr(AXUtilities, "get_displayed_label", lambda _o: None)
|
||||||
|
displayed = get_disp(obj) or self.displayedLabel(obj)
|
||||||
|
rv = role in roles and not displayed
|
||||||
|
|
||||||
self._shouldInferLabelFor[hash(obj)] = rv
|
self._shouldInferLabelFor[hash(obj)] = rv
|
||||||
|
|
||||||
@@ -4289,6 +4291,8 @@ class Utilities(script_utilities.Utilities):
|
|||||||
return rv
|
return rv
|
||||||
|
|
||||||
def displayedLabel(self, obj):
|
def displayedLabel(self, obj):
|
||||||
|
"""Return the author-visible label, preferring toolkit-displayed text when available."""
|
||||||
|
|
||||||
if not (obj and self.inDocumentContent(obj)):
|
if not (obj and self.inDocumentContent(obj)):
|
||||||
return super().displayedLabel(obj)
|
return super().displayedLabel(obj)
|
||||||
|
|
||||||
@@ -4296,10 +4300,13 @@ class Utilities(script_utilities.Utilities):
|
|||||||
if rv is not None:
|
if rv is not None:
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
labels = self.labelsForObject(obj)
|
# Prefer toolkit-provided displayed label (covers aria-labelledby/displayed text cases).
|
||||||
strings = [AXObject.get_name(label)
|
rv = getattr(AXUtilities, "get_displayed_label", lambda _o: None)(obj) or ""
|
||||||
or self.displayedText(label) for label in labels if label is not None]
|
if not rv:
|
||||||
rv = " ".join(strings)
|
labels = self.labelsForObject(obj)
|
||||||
|
strings = [AXObject.get_name(label) or self.displayedText(label)
|
||||||
|
for label in labels if label is not None]
|
||||||
|
rv = " ".join(strings)
|
||||||
|
|
||||||
self._displayedLabelText[hash(obj)] = rv
|
self._displayedLabelText[hash(obj)] = rv
|
||||||
return rv
|
return rv
|
||||||
|
|||||||
Reference in New Issue
Block a user