Fixed browser crashing on some button activations, I think.

This commit is contained in:
Storm Dragon
2025-12-17 06:25:02 -05:00
parent 53614b13b9
commit 61e40b81f6
3 changed files with 80 additions and 7 deletions
+16 -2
View File
@@ -509,8 +509,22 @@ class MouseReviewer:
cthulhu_state.activeScript.presentMessage(msg)
def _update_workspace_windows(self):
self._windows = [w for w in self._all_windows
if w.is_on_workspace(self._workspace)]
"""Refresh cached windows for the current 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):
"""Callback for Wnck's window-stacking-changed signal."""
+52
View File
@@ -84,6 +84,8 @@ class Script(default.Script):
self._inFocusMode = False
self._focusModeIsSticky = False
self._browseModeIsSticky = False
self._navSuspended = False
self._structNavWasEnabled = None
if _settingsManager.getSetting('caretNavigationEnabled') is None:
_settingsManager.setSetting('caretNavigationEnabled', True)
@@ -114,6 +116,22 @@ class Script(default.Script):
self.attributeNamesDict["text-align"] = "justification"
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):
"""Called when this script is deactivated."""
@@ -130,8 +148,30 @@ class Script(default.Script):
self._preMouseOverContext = None, -1
self._inMouseOverObject = False
self.utilities.clearCachedObjects()
# Ensure navigation commands are re-enabled for the next activation.
self._setNavigationSuspended(False, "script deactivation")
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):
"""Returns the application-specific keybindings for this script."""
@@ -1164,6 +1204,12 @@ class Script(default.Script):
debug.printMessage(debug.LEVEL_INFO, msg, True)
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 debugOutput:
tokens = ["WEB: Not using caret navigation: locusOfFocus",
@@ -1198,6 +1244,12 @@ class Script(default.Script):
debug.printMessage(debug.LEVEL_INFO, msg, True)
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 debugOutput:
tokens = ["WEB: Not using structural navigation: locusOfFocus",
+12 -5
View File
@@ -4277,7 +4277,9 @@ class Utilities(script_utilities.Utilities):
Atspi.Role.LIST_BOX,
Atspi.Role.PASSWORD_TEXT,
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
@@ -4289,6 +4291,8 @@ class Utilities(script_utilities.Utilities):
return rv
def displayedLabel(self, obj):
"""Return the author-visible label, preferring toolkit-displayed text when available."""
if not (obj and self.inDocumentContent(obj)):
return super().displayedLabel(obj)
@@ -4296,10 +4300,13 @@ class Utilities(script_utilities.Utilities):
if rv is not None:
return rv
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)
# Prefer toolkit-provided displayed label (covers aria-labelledby/displayed text cases).
rv = getattr(AXUtilities, "get_displayed_label", lambda _o: None)(obj) or ""
if not rv:
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
return rv