Add essential development tools and documentation for Cthulhu development: Development Scripts: - build-local.sh: Local build and install to ~/.local - clean-local.sh: Clean build artifacts and local installation - test-local.sh: Test local installation Documentation: - README-REMOTE-CONTROLLER.md: D-Bus service API documentation - README-DEVELOPMENT.md: Development workflow documentation - .gitignore: Updated with local build artifact patterns These tools enable efficient local development without system-wide installation and provide proper documentation for the D-Bus remote control capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
386 lines
12 KiB
Markdown
386 lines
12 KiB
Markdown
# Cthulhu Remote Controller (D-Bus Interface)
|
|
|
|
> **✅ STABLE**: This D-Bus interface has been successfully ported from Orca v49.alpha and integrated
|
|
> into Cthulhu. The API is functional and ready for use, providing external control and automation
|
|
> capabilities for the Cthulhu screen reader.
|
|
|
|
[TOC]
|
|
|
|
## Overview
|
|
|
|
Cthulhu exposes a D-Bus service at:
|
|
|
|
- **Service Name**: `org.stormux.Cthulhu.Service`
|
|
- **Main Object Path**: `/org/stormux/Cthulhu/Service`
|
|
- **Module Object Paths**: `/org/stormux/Cthulhu/Service/ModuleName`
|
|
(e.g., `/org/stormux/Cthulhu/Service/SpeechAndVerbosityManager`)
|
|
|
|
## Dependencies
|
|
|
|
The D-Bus interface requires:
|
|
|
|
- **dasbus** - Python D-Bus library used by Cthulhu for the remote controller implementation.
|
|
([Installation instructions](https://dasbus.readthedocs.io/en/latest/index.html))
|
|
- **python-dasbus** package (available on most distributions)
|
|
|
|
## Service-Level Commands
|
|
|
|
Commands available directly on the main service (`/org/stormux/Cthulhu/Service`):
|
|
|
|
### Get Cthulhu's Version
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service \
|
|
org.stormux.Cthulhu.Service GetVersion
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service \
|
|
--method org.stormux.Cthulhu.Service.GetVersion
|
|
```
|
|
|
|
**Returns:** String containing the version (and revision if available)
|
|
|
|
**Example output:** `s "Cthulhu screen reader version 2025.06.05-plugins (rev 408fb85)"`
|
|
|
|
### Present a Custom Message in Speech and/or Braille
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service \
|
|
org.stormux.Cthulhu.Service PresentMessage s "Your message here"
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service \
|
|
--method org.stormux.Cthulhu.Service.PresentMessage "Your message here"
|
|
```
|
|
|
|
**Parameters:**
|
|
|
|
- `message` (string): The message to present to the user
|
|
|
|
**Returns:** Boolean indicating success
|
|
|
|
### List Available Service Commands
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service \
|
|
org.stormux.Cthulhu.Service ListCommands
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service \
|
|
--method org.stormux.Cthulhu.Service.ListCommands
|
|
```
|
|
|
|
**Returns:** List of (command_name, description) tuples
|
|
|
|
### List Registered Modules
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service \
|
|
org.stormux.Cthulhu.Service ListModules
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service \
|
|
--method org.stormux.Cthulhu.Service.ListModules
|
|
```
|
|
|
|
**Returns:** List of module names
|
|
|
|
## Interacting with Modules
|
|
|
|
Each registered module exposes its own set of operations. Based on the underlying Cthulhu code, these
|
|
are categorized as **Commands**, **Runtime Getters**, and **Runtime Setters**:
|
|
|
|
- **Commands**: Actions that perform a task. These typically correspond to Cthulhu commands bound
|
|
to a keystroke (e.g., `IncreaseRate`).
|
|
- **Runtime Getters**: Operations that retrieve the current value of an item, often a setting
|
|
(e.g., `GetRate`).
|
|
- **Runtime Setters**: Operations that set the current value of an item, often a setting
|
|
(e.g., `SetRate`). Note that setting a value does NOT cause it to become permanently saved.
|
|
|
|
You can discover and execute these for each module.
|
|
|
|
### Discovering Module Capabilities
|
|
|
|
#### List Commands for a Module
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/ModuleName \
|
|
org.stormux.Cthulhu.Module ListCommands
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
|
--method org.stormux.Cthulhu.Module.ListCommands
|
|
```
|
|
|
|
Replace `ModuleName` with an actual module name from `ListModules`.
|
|
|
|
**Returns:** List of (command_name, description) tuples.
|
|
|
|
#### List Runtime Getters for a Module
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/ModuleName \
|
|
org.stormux.Cthulhu.Module ListRuntimeGetters
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
|
--method org.stormux.Cthulhu.Module.ListRuntimeGetters
|
|
```
|
|
|
|
Replace `ModuleName` with an actual module name from `ListModules`.
|
|
|
|
**Returns:** List of (getter_name, description) tuples.
|
|
|
|
#### List Runtime Setters for a Module
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/ModuleName \
|
|
org.stormux.Cthulhu.Module ListRuntimeSetters
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
|
--method org.stormux.Cthulhu.Module.ListRuntimeSetters
|
|
```
|
|
|
|
Replace `ModuleName` with an actual module name from `ListModules`.
|
|
|
|
**Returns:** List of (setter_name, description) tuples.
|
|
|
|
### Executing Module Operations
|
|
|
|
#### Execute a Runtime Getter
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/ModuleName \
|
|
org.stormux.Cthulhu.Module ExecuteRuntimeGetter s 'PropertyName'
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
|
--method org.stormux.Cthulhu.Module.ExecuteRuntimeGetter 'PropertyName'
|
|
```
|
|
|
|
**Parameters:**
|
|
|
|
- `PropertyName` (string): The name of the runtime getter to execute.
|
|
|
|
**Returns:** The value returned by the getter as a GLib variant (type depends on the getter).
|
|
|
|
##### Example: Get the current speech rate
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
|
org.stormux.Cthulhu.Module ExecuteRuntimeGetter s 'Rate'
|
|
```
|
|
|
|
This will return the rate as a GLib Variant.
|
|
|
|
#### Execute a Runtime Setter
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/ModuleName \
|
|
org.stormux.Cthulhu.Module ExecuteRuntimeSetter s 'PropertyName' v <value>
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
|
--method org.stormux.Cthulhu.Module.ExecuteRuntimeSetter 'PropertyName' <value>
|
|
```
|
|
|
|
**Parameters:**
|
|
|
|
- `PropertyName` (string): The name of the runtime setter to execute.
|
|
- `<value>`: The value to set, as a GLib variant (type depends on the setter).
|
|
|
|
**Returns:** Boolean indicating success.
|
|
|
|
##### Example: Set the current speech rate
|
|
|
|
```bash
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
|
org.stormux.Cthulhu.Module ExecuteRuntimeSetter s 'Rate' v '<90>'
|
|
```
|
|
|
|
#### Execute a Module Command
|
|
|
|
```bash
|
|
# With user notification
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/ModuleName \
|
|
org.stormux.Cthulhu.Module ExecuteCommand s 'CommandName' b true
|
|
|
|
# Without user notification (silent)
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/ModuleName \
|
|
org.stormux.Cthulhu.Module ExecuteCommand s 'CommandName' b false
|
|
```
|
|
|
|
**Alternative using gdbus:**
|
|
```bash
|
|
# With user notification
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
|
--method org.stormux.Cthulhu.Module.ExecuteCommand 'CommandName' true
|
|
|
|
# Without user notification (silent)
|
|
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
|
--method org.stormux.Cthulhu.Module.ExecuteCommand 'CommandName' false
|
|
```
|
|
|
|
**Parameters (both required):**
|
|
|
|
- `CommandName` (string): The name of the command to execute
|
|
- `notify_user` (boolean): Whether to notify the user of the action (see section below)
|
|
|
|
**Returns:** Boolean indicating success
|
|
|
|
### Please Note
|
|
|
|
**Setting `notify_user=true` is not a guarantee that feedback will be presented.** Some commands
|
|
inherently don't make sense to announce. For example:
|
|
|
|
```bash
|
|
# This command should simply stop speech, not announce that it is stopping speech.
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
|
org.stormux.Cthulhu.Module ExecuteCommand s 'InterruptSpeech' b true
|
|
```
|
|
|
|
In those cases Cthulhu will ignore the value of `notify_user`.
|
|
|
|
**Setting `notify_user=false` is a guarantee that Cthulhu will remain silent.** If Cthulhu provides any
|
|
feedback when `notify_user=false`, it should be considered a bug.
|
|
|
|
## Integration with Cthulhu's Plugin System
|
|
|
|
The D-Bus Remote Controller integrates seamlessly with Cthulhu's pluggy-based plugin system. Plugins can:
|
|
|
|
- Register their own D-Bus commands using the `@cthulhu_hookimpl` decorator
|
|
- Expose plugin-specific functionality via the remote controller
|
|
- Access the D-Bus service through the dynamic API manager
|
|
|
|
See the main `CLAUDE.md` file for more details on plugin development with D-Bus integration.
|
|
|
|
## Troubleshooting
|
|
|
|
### Service Not Available
|
|
|
|
If you get "The name is not activatable" or similar errors:
|
|
|
|
1. **Check if Cthulhu is running:**
|
|
```bash
|
|
ps aux | grep cthulhu
|
|
```
|
|
|
|
2. **Check if the D-Bus service is registered:**
|
|
```bash
|
|
busctl --user list | grep -i cthulhu
|
|
```
|
|
|
|
3. **Verify dasbus is installed:**
|
|
```bash
|
|
python3 -c "import dasbus; print('dasbus available')"
|
|
```
|
|
|
|
4. **Check Cthulhu debug output:**
|
|
```bash
|
|
DISPLAY=:0 ~/.local/bin/cthulhu --debug 2>&1 | grep -i dbus
|
|
```
|
|
|
|
### Common Issues
|
|
|
|
- **Timing Issues**: The D-Bus service starts after ATSPI initialization. Wait a few seconds after Cthulhu startup before attempting D-Bus calls.
|
|
- **Permissions**: Ensure you're using `--user` with busctl/gdbus for session bus access.
|
|
- **Display**: Make sure `DISPLAY=:0` is set when running Cthulhu in terminal sessions.
|
|
|
|
## Examples
|
|
|
|
### Quick Test Script
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# Test Cthulhu D-Bus Remote Controller
|
|
|
|
echo "Testing Cthulhu D-Bus Remote Controller..."
|
|
|
|
# Get version
|
|
echo "Version:"
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service \
|
|
org.stormux.Cthulhu.Service GetVersion
|
|
|
|
# Present a message
|
|
echo "Presenting message..."
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service \
|
|
org.stormux.Cthulhu.Service PresentMessage s "Hello from D-Bus!"
|
|
|
|
# List available modules
|
|
echo "Available modules:"
|
|
busctl --user call org.stormux.Cthulhu.Service \
|
|
/org/stormux/Cthulhu/Service \
|
|
org.stormux.Cthulhu.Service ListModules
|
|
|
|
echo "D-Bus test complete!"
|
|
```
|
|
|
|
## Integration Status
|
|
|
|
- ✅ **Core D-Bus service**: Fully integrated with Cthulhu
|
|
- ✅ **Service lifecycle**: Automatic start/shutdown with Cthulhu
|
|
- ✅ **Message presentation**: `PresentMessage()` method working
|
|
- ✅ **Version info**: `GetVersion()` method working
|
|
- ✅ **Deferred startup**: D-Bus service starts after ATSPI initialization to prevent crashes
|
|
- ✅ **Error handling**: Proper exception handling and logging
|
|
- 🔄 **Module registration**: Ready for individual managers to register D-Bus commands
|
|
- 🔄 **Plugin integration**: Plugins can expose D-Bus commands using decorators
|
|
|
|
## Future Development
|
|
|
|
- Add more speech configuration commands, getters, and setters
|
|
- Expose Cthulhu's plugin system commands via D-Bus
|
|
- Integrate with Cthulhu's advanced features (indentation audio, self-voicing, etc.)
|
|
- Progressively expose all of Cthulhu's commands and settings via the remote controller interface
|
|
|
|
## Related Files
|
|
|
|
- `src/cthulhu/dbus_service.py` - Main D-Bus service implementation
|
|
- `src/cthulhu/cthulhu.py` - Integration and startup logic
|
|
- `CLAUDE.md` - Main development guide with plugin integration details |