Added support for Orca's new self-voiced capabilities.
This commit is contained in:
parent
2efd0de68f
commit
c9f9e66c7c
@ -49,6 +49,62 @@ from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QHBoxLayout,
|
|||||||
from PySide6.QtCore import Qt, QTimer
|
from PySide6.QtCore import Qt, QTimer
|
||||||
import webbrowser
|
import webbrowser
|
||||||
|
|
||||||
|
class OrcaRemoteController:
|
||||||
|
"""D-Bus interface for Orca screen reader remote control"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.service_name = "org.gnome.Orca.Service"
|
||||||
|
self.main_path = "/org/gnome/Orca/Service"
|
||||||
|
self.available = self._test_availability()
|
||||||
|
|
||||||
|
def _test_availability(self):
|
||||||
|
"""Test if Orca remote controller is available"""
|
||||||
|
try:
|
||||||
|
result = subprocess.run([
|
||||||
|
"gdbus", "call", "--session",
|
||||||
|
"--dest", self.service_name,
|
||||||
|
"--object-path", self.main_path,
|
||||||
|
"--method", "org.gnome.Orca.Service.ListCommands"
|
||||||
|
], check=True, capture_output=True, text=True, timeout=2)
|
||||||
|
return True
|
||||||
|
except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def present_message(self, message):
|
||||||
|
"""Present a message via Orca speech/braille output"""
|
||||||
|
if not self.available:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run([
|
||||||
|
"gdbus", "call", "--session",
|
||||||
|
"--dest", self.service_name,
|
||||||
|
"--object-path", self.main_path,
|
||||||
|
"--method", "org.gnome.Orca.Service.PresentMessage",
|
||||||
|
message
|
||||||
|
], check=True, capture_output=True, text=True, timeout=2)
|
||||||
|
return "true" in result.stdout.lower()
|
||||||
|
except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def interrupt_speech(self):
|
||||||
|
"""Interrupt current speech via SpeechAndVerbosityManager"""
|
||||||
|
if not self.available:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run([
|
||||||
|
"gdbus", "call", "--session",
|
||||||
|
"--dest", self.service_name,
|
||||||
|
"--object-path", f"{self.main_path}/SpeechAndVerbosityManager",
|
||||||
|
"--method", "org.gnome.Orca.Module.ExecuteCommand",
|
||||||
|
"InterruptSpeech", "false"
|
||||||
|
], check=True, capture_output=True, text=True, timeout=2)
|
||||||
|
return "true" in result.stdout.lower()
|
||||||
|
except (subprocess.CalledProcessError, subprocess.TimeoutExpired, FileNotFoundError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Initialize speech provider based on platform
|
# Initialize speech provider based on platform
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
# Set up DLL paths for Windows
|
# Set up DLL paths for Windows
|
||||||
@ -70,7 +126,12 @@ if platform.system() == "Windows":
|
|||||||
print(f"Failed to initialize accessible_output2: {e}")
|
print(f"Failed to initialize accessible_output2: {e}")
|
||||||
sys.exit()
|
sys.exit()
|
||||||
else:
|
else:
|
||||||
# Linux/Mac path
|
# Linux/Mac path - prioritize Orca remote controller
|
||||||
|
orca_remote = OrcaRemoteController()
|
||||||
|
if orca_remote.available:
|
||||||
|
speechProvider = "orca_remote"
|
||||||
|
orca = orca_remote
|
||||||
|
else:
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output(["pgrep", "cthulhu"])
|
output = subprocess.check_output(["pgrep", "cthulhu"])
|
||||||
speechProvider = "cthulhu"
|
speechProvider = "cthulhu"
|
||||||
@ -205,7 +266,12 @@ class SpeechHandler:
|
|||||||
if not text or not self.use_tts:
|
if not text or not self.use_tts:
|
||||||
return
|
return
|
||||||
|
|
||||||
if speechProvider == "speechd":
|
if speechProvider == "orca_remote":
|
||||||
|
# Try Orca first, interrupt current speech then present message
|
||||||
|
orca.interrupt_speech()
|
||||||
|
if not orca.present_message(text):
|
||||||
|
print(f"Orca remote error - message not delivered", file=sys.stderr)
|
||||||
|
elif speechProvider == "speechd":
|
||||||
spd.cancel()
|
spd.cancel()
|
||||||
spd.speak(text)
|
spd.speak(text)
|
||||||
elif speechProvider == "accessible_output2":
|
elif speechProvider == "accessible_output2":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user