Fixed user reported bug. Turns out old debugging was still in place. Should be fixed now.
This commit is contained in:
@@ -57,9 +57,9 @@ toolkit, OpenOffice/LibreOffice, Gecko, WebKitGtk, and KDE Qt toolkit.
|
|||||||
- **Preserves exit key**: Only sleep toggle remains active
|
- **Preserves exit key**: Only sleep toggle remains active
|
||||||
|
|
||||||
### Self-Voicing
|
### Self-Voicing
|
||||||
- **Unix socket interface**: Direct speech output via `/tmp/cthulhu.sock`
|
- **Unix socket interface**: Direct speech output via `${XDG_RUNTIME_DIR}/cthulhu.sock`
|
||||||
- **External integration**: Other applications can speak through Cthulhu
|
- **External integration**: Other applications can speak through Cthulhu
|
||||||
- **Simple protocol**: `echo "text" | socat - UNIX-CLIENT:/tmp/cthulhu.sock`
|
- **Simple protocol**: `echo "text" | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock"`
|
||||||
|
|
||||||
## D-Bus Remote Controller
|
## D-Bus Remote Controller
|
||||||
|
|
||||||
@@ -275,9 +275,9 @@ Cthulhu offers a mechanism through which messages may be spoken directly by the
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Speak hello world.
|
# Speak hello world.
|
||||||
echo "Hello world." | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
echo "Hello world." | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock"
|
||||||
# Speak Hello world without interrupting the previous speech.
|
# Speak Hello world without interrupting the previous speech.
|
||||||
echo "<!#APPEND#!>Hello world." | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
echo "<#APPEND#>Hello world." | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock"
|
||||||
# Make hello world persistant in Braille.
|
# Make hello world persistent in Braille.
|
||||||
echo "Hello world.<#APPEND#>" | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
echo "Hello world.<#PERSISTENT#>" | socat - UNIX-CLIENT:"${XDG_RUNTIME_DIR}/cthulhu.sock"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import select
|
|||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
from threading import Thread, Lock
|
from threading import Thread, Lock
|
||||||
|
from typing import Optional
|
||||||
from cthulhu.plugin import Plugin, cthulhu_hookimpl
|
from cthulhu.plugin import Plugin, cthulhu_hookimpl
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -34,6 +35,13 @@ logger = logging.getLogger(__name__)
|
|||||||
APPEND_CODE = '<#APPEND#>'
|
APPEND_CODE = '<#APPEND#>'
|
||||||
PERSISTENT_CODE = '<#PERSISTENT#>'
|
PERSISTENT_CODE = '<#PERSISTENT#>'
|
||||||
|
|
||||||
|
def _get_socket_file() -> Optional[str]:
|
||||||
|
runtimeDir = os.environ.get('XDG_RUNTIME_DIR')
|
||||||
|
if not runtimeDir:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return os.path.join(runtimeDir, 'cthulhu.sock')
|
||||||
|
|
||||||
class SelfVoice(Plugin):
|
class SelfVoice(Plugin):
|
||||||
"""Plugin that provides a socket interface for external applications to send text to Cthulhu."""
|
"""Plugin that provides a socket interface for external applications to send text to Cthulhu."""
|
||||||
|
|
||||||
@@ -115,9 +123,10 @@ class SelfVoice(Plugin):
|
|||||||
|
|
||||||
def voiceWorker(self):
|
def voiceWorker(self):
|
||||||
"""Worker thread that listens on a socket for messages to speak."""
|
"""Worker thread that listens on a socket for messages to speak."""
|
||||||
socketFile = '/tmp/cthulhu.sock'
|
socketFile = _get_socket_file()
|
||||||
# For testing purposes
|
if not socketFile:
|
||||||
# socketFile = '/tmp/cthulhu-plugin.sock'
|
logger.error("XDG_RUNTIME_DIR is not set; Self Voice plugin cannot create its socket")
|
||||||
|
return
|
||||||
|
|
||||||
# Clean up any existing socket file
|
# Clean up any existing socket file
|
||||||
if os.path.exists(socketFile):
|
if os.path.exists(socketFile):
|
||||||
|
|||||||
@@ -393,8 +393,6 @@ class Script(script.Script):
|
|||||||
return keyBindings
|
return keyBindings
|
||||||
|
|
||||||
def getExtensionBindings(self):
|
def getExtensionBindings(self):
|
||||||
with open('/tmp/extension_bindings_debug.log', 'a') as f:
|
|
||||||
f.write(f"=== getExtensionBindings() called ===\n")
|
|
||||||
keyBindings = keybindings.KeyBindings()
|
keyBindings = keybindings.KeyBindings()
|
||||||
|
|
||||||
bindings = self.notificationPresenter.get_bindings()
|
bindings = self.notificationPresenter.get_bindings()
|
||||||
@@ -443,35 +441,13 @@ class Script(script.Script):
|
|||||||
try:
|
try:
|
||||||
if hasattr(cthulhu, 'cthulhuApp') and cthulhu.cthulhuApp:
|
if hasattr(cthulhu, 'cthulhuApp') and cthulhu.cthulhuApp:
|
||||||
api_helper = cthulhu.cthulhuApp.getAPIHelper()
|
api_helper = cthulhu.cthulhuApp.getAPIHelper()
|
||||||
with open('/tmp/extension_bindings_debug.log', 'a') as f:
|
|
||||||
f.write(f"=== Checking for plugin bindings ===\n")
|
|
||||||
f.write(f"api_helper exists: {api_helper is not None}\n")
|
|
||||||
if api_helper:
|
|
||||||
f.write(f"api_helper has _gestureBindings: {hasattr(api_helper, '_gestureBindings')}\n")
|
|
||||||
if hasattr(api_helper, '_gestureBindings'):
|
|
||||||
f.write(f"_gestureBindings content: {api_helper._gestureBindings}\n")
|
|
||||||
f.write(f"Available contexts: {list(api_helper._gestureBindings.keys())}\n")
|
|
||||||
|
|
||||||
if api_helper and hasattr(api_helper, '_gestureBindings'):
|
if api_helper and hasattr(api_helper, '_gestureBindings'):
|
||||||
with open('/tmp/extension_bindings_debug.log', 'a') as f:
|
|
||||||
f.write(f"=== Adding plugin bindings in getExtensionBindings() ===\n")
|
|
||||||
|
|
||||||
for context_name, context_bindings in api_helper._gestureBindings.items():
|
for context_name, context_bindings in api_helper._gestureBindings.items():
|
||||||
for binding in context_bindings:
|
for binding in context_bindings:
|
||||||
keyBindings.add(binding)
|
keyBindings.add(binding)
|
||||||
with open('/tmp/extension_bindings_debug.log', 'a') as f:
|
|
||||||
f.write(f"Added plugin binding: {binding.keysymstring} modifiers={binding.modifiers} desc={binding.handler.description}\n")
|
|
||||||
else:
|
|
||||||
with open('/tmp/extension_bindings_debug.log', 'a') as f:
|
|
||||||
f.write(f"=== No plugin bindings available ===\n")
|
|
||||||
else:
|
|
||||||
with open('/tmp/extension_bindings_debug.log', 'a') as f:
|
|
||||||
f.write(f"=== cthulhuApp not available ===\n")
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
import cthulhu.debug as debug
|
import cthulhu.debug as debug
|
||||||
debug.printMessage(debug.LEVEL_WARNING, f"Failed to add plugin bindings: {e}", True)
|
debug.printMessage(debug.LEVEL_WARNING, f"Failed to add plugin bindings: {e}", True)
|
||||||
with open('/tmp/extension_bindings_debug.log', 'a') as f:
|
|
||||||
f.write(f"Exception in plugin binding addition: {e}\n")
|
|
||||||
|
|
||||||
return keyBindings
|
return keyBindings
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from cthulhu.plugins.self_voice import plugin
|
||||||
|
|
||||||
|
|
||||||
|
class SelfVoicePluginRegressionTests(unittest.TestCase):
|
||||||
|
def test_socket_file_is_scoped_to_user_runtime_directory(self) -> None:
|
||||||
|
with mock.patch.dict(os.environ, {"XDG_RUNTIME_DIR": "/run/user/1000"}, clear=True):
|
||||||
|
self.assertEqual(plugin._get_socket_file(), "/run/user/1000/cthulhu.sock")
|
||||||
|
|
||||||
|
def test_socket_file_is_unavailable_without_user_runtime_directory(self) -> None:
|
||||||
|
with mock.patch.dict(os.environ, {}, clear=True):
|
||||||
|
self.assertIsNone(plugin._get_socket_file())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user