Potential fix for nvda2cthulhu plugin crash bug.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user