Potential fix for nvda2cthulhu plugin crash bug.

This commit is contained in:
Storm Dragon
2026-05-02 17:59:39 -04:00
parent 265feb8188
commit 77b7c81d73

View File

@@ -29,6 +29,9 @@ from collections import OrderedDict
import subprocess
import threading
import urllib.parse
from typing import Any, Callable
from gi.repository import GLib
try:
import msgpack
@@ -202,17 +205,27 @@ class Nvda2Cthulhu(Plugin):
return True
def handle_message(self, message):
request = self._parse_request(message)
try:
request = self._parse_request(message)
except Exception as exc:
logger.warning(f"NVDA to Cthulhu: failed to parse message: {exc}")
debug.printException(debug.LEVEL_WARNING)
return
if not request:
return
requestType, payload = request
if requestType == "SpeakText":
self._handle_speak(payload)
elif requestType == "BrailleText":
self._handle_braille(payload)
elif requestType == "CancelSpeech":
speech.stop()
try:
requestType, payload = request
if requestType == "SpeakText":
self._handle_speak(payload)
elif requestType == "BrailleText":
self._schedule_on_main_thread(self._handle_braille, payload)
elif requestType == "CancelSpeech":
self._schedule_on_main_thread(self._handle_cancel_speech)
except Exception as exc:
logger.warning(f"NVDA to Cthulhu: failed to handle message: {exc}")
debug.printException(debug.LEVEL_WARNING)
def _server_main(self):
if not self._dependencies_available():
@@ -234,7 +247,7 @@ class Nvda2Cthulhu(Plugin):
self.ioLoop.start()
except Exception as exc:
logger.error(f"NVDA to Cthulhu failed to start server: {exc}")
self._present_message("NVDA to Cthulhu server failed to start")
self._schedule_on_main_thread(self._present_message, "NVDA to Cthulhu server failed to start")
finally:
self.httpServer = None
if self.ioLoop:
@@ -261,7 +274,7 @@ class Nvda2Cthulhu(Plugin):
if not self._dependencies_available():
return None
if isinstance(message, str):
return "SpeakText", message
return self._parse_payload(message)
if not isinstance(message, (bytes, bytearray)):
return None
@@ -318,7 +331,13 @@ class Nvda2Cthulhu(Plugin):
translated = self._translate_text(text)
logger.info(f"NVDA to Cthulhu: translated to: {translated[:50]}")
text = translated
speech.speak(text, interrupt=self.interruptEnabled)
self._schedule_on_main_thread(self._speak_text, text, self.interruptEnabled)
def _speak_text(self, text: str, interrupt: bool) -> None:
speech.speak(text, interrupt=interrupt)
def _handle_cancel_speech(self) -> None:
speech.stop()
def _handle_braille(self, text):
if not text or not text.strip():
@@ -350,6 +369,23 @@ class Nvda2Cthulhu(Plugin):
except Exception:
logger.info(message)
def _schedule_on_main_thread(self, callback: Callable[..., Any], *args: Any) -> bool:
try:
GLib.idle_add(self._run_on_main_thread, callback, args)
return True
except Exception as exc:
logger.warning(f"NVDA to Cthulhu: failed to queue main-loop callback: {exc}")
debug.printException(debug.LEVEL_WARNING)
return False
def _run_on_main_thread(self, callback: Callable[..., Any], args: tuple[Any, ...]) -> bool:
try:
callback(*args)
except Exception as exc:
logger.warning(f"NVDA to Cthulhu: main-loop callback failed: {exc}")
debug.printException(debug.LEVEL_WARNING)
return False
def _dependencies_available(self):
return msgpack is not None and tornado is not None