Backport Orca's d-bus remote fixes.
This commit is contained in:
@@ -59,8 +59,8 @@ cthulhu
|
||||
|
||||
Cthulhu now includes a D-Bus service for remote control:
|
||||
|
||||
- **Service**: `org.stormux.Cthulhu.Service`
|
||||
- **Path**: `/org/stormux/Cthulhu/Service`
|
||||
- **Service**: `org.stormux.Cthulhu1.Service`
|
||||
- **Path**: `/org/stormux/Cthulhu1/Service`
|
||||
- **Requires**: `dasbus` library (should be installed)
|
||||
|
||||
### Testing D-Bus Service
|
||||
@@ -70,10 +70,10 @@ Cthulhu now includes a D-Bus service for remote control:
|
||||
~/.local/bin/cthulhu
|
||||
|
||||
# In another terminal, test the service
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service org.stormux.Cthulhu.Service GetVersion
|
||||
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service org.stormux.Cthulhu1.Service GetVersion
|
||||
|
||||
# Present a message via D-Bus
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service org.stormux.Cthulhu.Service PresentMessage s "Hello from D-Bus"
|
||||
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service org.stormux.Cthulhu1.Service PresentMessage s "Hello from D-Bus"
|
||||
```
|
||||
|
||||
## Development Workflow
|
||||
|
||||
+89
-174
@@ -22,10 +22,11 @@ on any Linux desktop environment or window manager.
|
||||
|
||||
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`)
|
||||
- **Service Name**: `org.stormux.Cthulhu1.Service`
|
||||
- **Main Object Path**: `/org/stormux/Cthulhu1/Service`
|
||||
- **Module Object Paths**: `/org/stormux/Cthulhu1/Service/ModuleName`
|
||||
(e.g., `/org/stormux/Cthulhu1/Service/SpeechManager`)
|
||||
- **Module Interfaces**: `org.stormux.Cthulhu1.ModuleName`
|
||||
|
||||
See [REMOTE-CONTROLLER-COMMANDS.md](REMOTE-CONTROLLER-COMMANDS.md) for a complete
|
||||
list of available commands.
|
||||
@@ -43,34 +44,34 @@ While this documentation primarily uses `gdbus` for examples, you can use any D-
|
||||
|
||||
### Using `busctl` (systemd D-Bus tool)
|
||||
```bash
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service GetVersion
|
||||
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||
org.stormux.Cthulhu1.Service GetVersion
|
||||
```
|
||||
|
||||
### Using Python with `dasbus`
|
||||
```python
|
||||
from dasbus.connection import SessionMessageBus
|
||||
bus = SessionMessageBus()
|
||||
proxy = bus.get_proxy("org.stormux.Cthulhu.Service", "/org/stormux/Cthulhu/Service")
|
||||
proxy = bus.get_proxy("org.stormux.Cthulhu1.Service", "/org/stormux/Cthulhu1/Service")
|
||||
version = proxy.GetVersion()
|
||||
```
|
||||
|
||||
### Using `qdbus` (Qt D-Bus tool - available on KDE)
|
||||
```bash
|
||||
qdbus org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service.GetVersion
|
||||
qdbus org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||
org.stormux.Cthulhu1.Service.GetVersion
|
||||
```
|
||||
|
||||
## Service-Level Commands
|
||||
|
||||
Commands available directly on the main service (`/org/stormux/Cthulhu/Service`):
|
||||
Commands available directly on the main service (`/org/stormux/Cthulhu1/Service`):
|
||||
|
||||
### Get Cthulhu's Version
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service \
|
||||
--method org.stormux.Cthulhu.Service.GetVersion
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service \
|
||||
--method org.stormux.Cthulhu1.Service.GetVersion
|
||||
```
|
||||
|
||||
**Returns:** String containing the version (and revision if available)
|
||||
@@ -78,9 +79,9 @@ gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
### Present a Custom Message in Speech and/or Braille
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service \
|
||||
--method org.stormux.Cthulhu.Service.PresentMessage "Your message here"
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service \
|
||||
--method org.stormux.Cthulhu1.Service.PresentMessage "Your message here"
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@@ -92,9 +93,9 @@ gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
### Show Cthulhu's Preferences GUI
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service \
|
||||
--method org.stormux.Cthulhu.Service.ShowPreferences
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service \
|
||||
--method org.stormux.Cthulhu1.Service.ShowPreferences
|
||||
```
|
||||
|
||||
**Returns:** Boolean indicating success
|
||||
@@ -102,44 +103,39 @@ gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
### Quit Cthulhu
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service \
|
||||
--method org.stormux.Cthulhu.Service.Quit
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service \
|
||||
--method org.stormux.Cthulhu1.Service.Quit
|
||||
```
|
||||
|
||||
**Returns:** Boolean indicating if the quit request was accepted
|
||||
|
||||
### List Available Service Commands
|
||||
## Discovering Modules and Their Capabilities
|
||||
|
||||
Use the standard DBus introspection interface to discover registered modules:
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service \
|
||||
--method org.stormux.Cthulhu.Service.ListCommands
|
||||
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service --recurse
|
||||
```
|
||||
|
||||
**Returns:** List of (command_name, description) tuples
|
||||
|
||||
### List Registered Modules
|
||||
The child `<node>` entries beneath `/org/stormux/Cthulhu1/Service` are the
|
||||
registered modules. To inspect the methods and properties for one module:
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service \
|
||||
--method org.stormux.Cthulhu.Service.ListModules
|
||||
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/SpeechManager
|
||||
```
|
||||
|
||||
**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**:
|
||||
Each registered module exposes its own native DBus interface. Based on the underlying Cthulhu code,
|
||||
these are categorized as **Commands** and **Properties**:
|
||||
|
||||
- **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.
|
||||
- **Properties**: Runtime values, often settings (e.g., `Rate`). Setting a property does not cause
|
||||
it to become permanently saved.
|
||||
|
||||
You can discover and execute these for each module.
|
||||
|
||||
@@ -147,41 +143,41 @@ You can discover and execute these for each module.
|
||||
|
||||
Plugins that expose D-Bus decorators are automatically registered as modules using the naming
|
||||
convention `Plugin_<ModuleName>` (e.g., `Plugin_GameMode`, `Plugin_WindowTitleReader`). Use
|
||||
`ListModules` to discover available plugin modules at runtime.
|
||||
standard DBus introspection to discover available plugin modules at runtime.
|
||||
|
||||
#### Plugin_WindowTitleReader
|
||||
|
||||
Controls for the Window Title Reader plugin:
|
||||
|
||||
- Parameterized command: `SetEnabled` (`enabled`: bool)
|
||||
- Runtime getter: `Enabled`
|
||||
- Method: `SetEnabled` (`enabled`: bool, `notify_user`: bool)
|
||||
- Property: `Enabled`
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand \
|
||||
'SetEnabled' '{"enabled": <true>}' false
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||
--method org.stormux.Cthulhu1.Plugin_WindowTitleReader.SetEnabled true false
|
||||
|
||||
# Check current state
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeGetter 'Enabled'
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||
--method org.freedesktop.DBus.Properties.Get \
|
||||
org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled
|
||||
```
|
||||
|
||||
Busctl example:
|
||||
|
||||
```bash
|
||||
busctl --user call org.stormux.Cthulhu.Service \
|
||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
||||
org.stormux.Cthulhu.Module ExecuteParameterizedCommand \
|
||||
s a{sv} b 'SetEnabled' 1 enabled b true false
|
||||
busctl --user call org.stormux.Cthulhu1.Service \
|
||||
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||
org.stormux.Cthulhu1.Plugin_WindowTitleReader SetEnabled bb true false
|
||||
|
||||
# Check current state
|
||||
busctl --user call org.stormux.Cthulhu.Service \
|
||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
||||
org.stormux.Cthulhu.Module ExecuteRuntimeGetter s 'Enabled'
|
||||
busctl --user call org.stormux.Cthulhu1.Service \
|
||||
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||
org.freedesktop.DBus.Properties Get ss \
|
||||
org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled
|
||||
```
|
||||
|
||||
### PluginSystemManager Module
|
||||
@@ -190,166 +186,85 @@ The `PluginSystemManager` module provides session-only plugin control:
|
||||
|
||||
- `ListPlugins`
|
||||
- `ListActivePlugins`
|
||||
- `IsPluginActive` (parameterized)
|
||||
- `SetPluginActive` (parameterized)
|
||||
- `IsPluginActive`
|
||||
- `SetPluginActive`
|
||||
- `RescanPlugins`
|
||||
|
||||
These calls do **not** persist changes to user preferences.
|
||||
|
||||
### Discovering Module Capabilities
|
||||
|
||||
#### List Commands for a Module
|
||||
|
||||
```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 Parameterized Commands for a Module
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu.Module.ListParameterizedCommands
|
||||
```
|
||||
|
||||
Replace `ModuleName` with an actual module name from `ListModules`.
|
||||
|
||||
**Returns:** List of (command_name, description, parameters) tuples, where `parameters` is a
|
||||
list of (parameter_name, parameter_type) tuples.
|
||||
|
||||
**Example output:**
|
||||
|
||||
```bash
|
||||
([('GetVoicesForLanguage',
|
||||
'Returns a list of available voices for the specified language.',
|
||||
[('language', 'str'), ('variant', 'str'), ('notify_user', 'bool')])],)
|
||||
```
|
||||
|
||||
#### List Runtime Getters for a Module
|
||||
|
||||
```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
|
||||
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
|
||||
#### Get a Property
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeGetter 'PropertyName'
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||
--method org.freedesktop.DBus.Properties.Get \
|
||||
org.stormux.Cthulhu1.ModuleName 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
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeGetter 'Rate'
|
||||
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||
--method org.freedesktop.DBus.Properties.Get \
|
||||
org.stormux.Cthulhu1.SpeechManager Rate
|
||||
```
|
||||
|
||||
This will return the rate as a GLib Variant.
|
||||
|
||||
#### Execute a Runtime Setter
|
||||
#### Set a Property
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeSetter 'PropertyName' <value>
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||
--method org.freedesktop.DBus.Properties.Set \
|
||||
org.stormux.Cthulhu1.ModuleName 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
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeSetter 'Rate' '<90>'
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||
--method org.freedesktop.DBus.Properties.Set \
|
||||
org.stormux.Cthulhu1.SpeechManager Rate '<90>'
|
||||
```
|
||||
|
||||
#### Execute a Module Command
|
||||
|
||||
```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
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu1.ModuleName.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
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu1.ModuleName.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
|
||||
|
||||
#### Execute a Parameterized Command
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand 'CommandName' \
|
||||
'{"param1": <"value1">, "param2": <"value2">}' false
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu1.ModuleName.CommandName \
|
||||
"value1" "value2" false
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `CommandName` (string): The name of the parameterized command to execute
|
||||
- `parameters` (dict): Dictionary of parameter names and values as GLib variants
|
||||
- `notify_user` (boolean): Whether to notify the user of the action
|
||||
|
||||
**Returns:** The result returned by the command as a GLib variant (type depends on the command)
|
||||
|
||||
##### Example: Get voices for a specific language
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand 'GetVoicesForLanguage' \
|
||||
'{"language": <"en-us">, "variant": <"">}' false
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||
--method org.stormux.Cthulhu1.SpeechManager.GetVoicesForLanguage "en-us" "" false
|
||||
```
|
||||
|
||||
This will return a list of available voices for US English.
|
||||
@@ -362,9 +277,9 @@ 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.
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteCommand 'InterruptSpeech' true
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||
--method org.stormux.Cthulhu1.SpeechManager.InterruptSpeech true
|
||||
```
|
||||
|
||||
In those cases Cthulhu will ignore the value of `notify_user`.
|
||||
|
||||
@@ -66,22 +66,21 @@ toolkit, OpenOffice/LibreOffice, Gecko, WebKitGtk, and KDE Qt toolkit.
|
||||
Cthulhu exposes a D-Bus service for external automation and integrations.
|
||||
|
||||
### Service Details
|
||||
- **Service Name**: `org.stormux.Cthulhu.Service`
|
||||
- **Main Object Path**: `/org/stormux/Cthulhu/Service`
|
||||
- **Module Object Paths**: `/org/stormux/Cthulhu/Service/<ModuleName>`
|
||||
- **Service Name**: `org.stormux.Cthulhu1.Service`
|
||||
- **Main Object Path**: `/org/stormux/Cthulhu1/Service`
|
||||
- **Module Object Paths**: `/org/stormux/Cthulhu1/Service/<ModuleName>`
|
||||
- **Module Interfaces**: `org.stormux.Cthulhu1.<ModuleName>`
|
||||
|
||||
### Discovering Capabilities
|
||||
|
||||
```bash
|
||||
# List registered modules
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service \
|
||||
--method org.stormux.Cthulhu.Service.ListModules
|
||||
# List registered module object paths and introspect their methods/properties
|
||||
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service --recurse
|
||||
|
||||
# List commands on a module
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
||||
--method org.stormux.Cthulhu.Module.ListCommands
|
||||
# Inspect one module
|
||||
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/ModuleName
|
||||
```
|
||||
|
||||
### Plugin Modules
|
||||
@@ -95,8 +94,8 @@ The `PluginSystemManager` module provides **session-only** plugin control (no pr
|
||||
|
||||
- `ListPlugins`
|
||||
- `ListActivePlugins`
|
||||
- `IsPluginActive` (parameterized)
|
||||
- `SetPluginActive` (parameterized)
|
||||
- `IsPluginActive`
|
||||
- `SetPluginActive`
|
||||
- `RescanPlugins`
|
||||
|
||||
### Plugin Preferences Pages
|
||||
|
||||
@@ -11,7 +11,7 @@ This document lists the currently available D-Bus commands in Cthulhu's Remote C
|
||||
|
||||
## Service-Level Commands
|
||||
|
||||
Available on the main service object `/org/stormux/Cthulhu/Service`:
|
||||
Available on the main service object `/org/stormux/Cthulhu1/Service`:
|
||||
|
||||
### Service Commands
|
||||
|
||||
@@ -21,40 +21,37 @@ Available on the main service object `/org/stormux/Cthulhu/Service`:
|
||||
| `PresentMessage` | Present a message via speech/braille | `message` (string) | Boolean (success) |
|
||||
| `ShowPreferences` | Opens Cthulhu's preferences GUI | None | Boolean (success) |
|
||||
| `Quit` | Exits Cthulhu | None | Boolean (accepted) |
|
||||
| `ListCommands` | Lists available service commands | None | List of (name, description) tuples |
|
||||
| `ListModules` | Lists registered D-Bus modules | None | List of module names |
|
||||
|
||||
### Example Usage
|
||||
|
||||
```bash
|
||||
# Get Cthulhu version
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service GetVersion
|
||||
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||
org.stormux.Cthulhu1.Service GetVersion
|
||||
|
||||
# Present a custom message
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service PresentMessage s "Hello from D-Bus"
|
||||
|
||||
# List available commands
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service ListCommands
|
||||
|
||||
# List registered modules
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service ListModules
|
||||
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||
org.stormux.Cthulhu1.Service PresentMessage s "Hello from D-Bus"
|
||||
|
||||
# Open preferences
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service ShowPreferences
|
||||
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||
org.stormux.Cthulhu1.Service ShowPreferences
|
||||
|
||||
# Quit Cthulhu
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service Quit
|
||||
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||
org.stormux.Cthulhu1.Service Quit
|
||||
```
|
||||
|
||||
## Module-Level Commands
|
||||
|
||||
Module-level commands are available and can be discovered via `ListModules`. Two key additions are:
|
||||
Module-level commands and properties are discovered with standard DBus introspection:
|
||||
|
||||
```bash
|
||||
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service --recurse
|
||||
```
|
||||
|
||||
Two key additions are:
|
||||
|
||||
### PluginSystemManager
|
||||
|
||||
@@ -62,8 +59,8 @@ Session-only plugin control (does not persist preferences):
|
||||
|
||||
- `ListPlugins`
|
||||
- `ListActivePlugins`
|
||||
- `IsPluginActive` (parameterized)
|
||||
- `SetPluginActive` (parameterized)
|
||||
- `IsPluginActive`
|
||||
- `SetPluginActive`
|
||||
- `RescanPlugins`
|
||||
|
||||
### Plugin Modules
|
||||
@@ -73,31 +70,30 @@ convention `Plugin_<ModuleName>` (e.g., `Plugin_GameMode`, `Plugin_WindowTitleRe
|
||||
|
||||
#### WindowTitleReader (Plugin_WindowTitleReader)
|
||||
|
||||
- `SetEnabled` (parameterized) -> enabled (bool)
|
||||
- `Enabled` (runtime getter)
|
||||
- `SetEnabled` -> enabled (bool), notify_user (bool)
|
||||
- `Enabled` (property)
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
||||
--object-path /org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand \
|
||||
'SetEnabled' '{"enabled": <true>}' false
|
||||
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||
--object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||
--method org.stormux.Cthulhu1.Plugin_WindowTitleReader.SetEnabled true false
|
||||
```
|
||||
|
||||
Busctl example:
|
||||
|
||||
```bash
|
||||
busctl --user call org.stormux.Cthulhu.Service \
|
||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
||||
org.stormux.Cthulhu.Module ExecuteParameterizedCommand \
|
||||
s a{sv} b 'SetEnabled' 1 enabled b true false
|
||||
busctl --user call org.stormux.Cthulhu1.Service \
|
||||
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||
org.stormux.Cthulhu1.Plugin_WindowTitleReader SetEnabled bb true false
|
||||
```
|
||||
|
||||
# Check current state
|
||||
busctl --user call org.stormux.Cthulhu.Service \
|
||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
||||
org.stormux.Cthulhu.Module ExecuteRuntimeGetter s 'Enabled'
|
||||
busctl --user call org.stormux.Cthulhu1.Service \
|
||||
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||
org.freedesktop.DBus.Properties Get ss \
|
||||
org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled
|
||||
|
||||
See [README-REMOTE-CONTROLLER.md](README-REMOTE-CONTROLLER.md) for comprehensive D-Bus API documentation and usage examples.
|
||||
|
||||
@@ -107,11 +103,15 @@ See [README-REMOTE-CONTROLLER.md](README-REMOTE-CONTROLLER.md) for comprehensive
|
||||
# Check if Cthulhu's D-Bus service is running
|
||||
busctl --user list | grep Cthulhu
|
||||
|
||||
# Introspect the service to see all available methods
|
||||
busctl --user introspect org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service
|
||||
# Introspect the service to see available module nodes
|
||||
busctl --user introspect org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service
|
||||
|
||||
# Introspect a module to see its methods and properties
|
||||
busctl --user introspect org.stormux.Cthulhu1.Service \
|
||||
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader
|
||||
|
||||
# Get detailed service information
|
||||
busctl --user status org.stormux.Cthulhu.Service
|
||||
busctl --user status org.stormux.Cthulhu1.Service
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
+748
-657
File diff suppressed because it is too large
Load Diff
@@ -669,14 +669,14 @@ class PluginSystemManager:
|
||||
logger.error(f"Failed to deregister D-Bus module for plugin {plugin_info.get_module_name()}: {error}")
|
||||
|
||||
@dbus_service.command
|
||||
def list_plugins(self):
|
||||
def list_plugins(self) -> list[str]:
|
||||
"""Returns a list of available plugin module names."""
|
||||
if not self._plugins:
|
||||
self.rescanPlugins()
|
||||
return [info.get_module_name() for info in self.plugins]
|
||||
|
||||
@dbus_service.command
|
||||
def list_active_plugins(self):
|
||||
def list_active_plugins(self) -> list[str]:
|
||||
"""Returns a list of currently active plugin module names."""
|
||||
return [info.get_module_name() for info in self.plugins if info.loaded]
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from cthulhu import dbus_service
|
||||
|
||||
|
||||
class SampleModule:
|
||||
def __init__(self):
|
||||
self.enabled = False
|
||||
self.calls = []
|
||||
|
||||
@dbus_service.command
|
||||
def toggle_feature(self, script=None, event=None, notify_user=True):
|
||||
"""Toggles the test feature."""
|
||||
self.calls.append((script, event, notify_user))
|
||||
return True
|
||||
|
||||
@dbus_service.command
|
||||
def command_without_notify(self, script=None, event=None):
|
||||
"""Runs a command that does not accept notify_user."""
|
||||
self.calls.append((script, event))
|
||||
return True
|
||||
|
||||
@dbus_service.command
|
||||
def list_items(self) -> "list[str]":
|
||||
"""Returns a list from a command."""
|
||||
return ["alpha", "beta"]
|
||||
|
||||
@dbus_service.parameterized_command
|
||||
def speak_text(
|
||||
self,
|
||||
text: "str",
|
||||
count: "int" = 1,
|
||||
script=None,
|
||||
event=None,
|
||||
notify_user=True,
|
||||
) -> "str":
|
||||
"""Speaks text a number of times."""
|
||||
self.calls.append((text, count, script, event, notify_user))
|
||||
return text * count
|
||||
|
||||
@dbus_service.getter
|
||||
def get_enabled(self) -> "bool":
|
||||
"""Returns whether the feature is enabled."""
|
||||
return self.enabled
|
||||
|
||||
@dbus_service.setter
|
||||
def set_enabled(self, value: "bool"):
|
||||
"""Sets whether the feature is enabled."""
|
||||
self.enabled = value
|
||||
|
||||
|
||||
class NativeInterfaceBuilderTest(unittest.TestCase):
|
||||
def test_registration_groups_decorated_members_by_native_names(self):
|
||||
registration = dbus_service._ModuleRegistration.from_module_instance(
|
||||
"TestModule", SampleModule()
|
||||
)
|
||||
|
||||
self.assertIn("ToggleFeature", registration.get_commands())
|
||||
self.assertIn("SpeakText", registration.get_parameterized_commands())
|
||||
self.assertIn("Enabled", registration.get_getters())
|
||||
self.assertIn("Enabled", registration.get_setters())
|
||||
self.assertEqual(registration.total_member_count(), 6)
|
||||
|
||||
def test_interface_builder_exposes_methods_and_properties(self):
|
||||
registration = dbus_service._ModuleRegistration.from_module_instance(
|
||||
"TestModule", SampleModule()
|
||||
)
|
||||
interface_class = dbus_service._InterfaceBuilder.build(registration)
|
||||
|
||||
self.assertTrue(hasattr(interface_class, "ToggleFeature"))
|
||||
self.assertTrue(hasattr(interface_class, "CommandWithoutNotify"))
|
||||
self.assertTrue(hasattr(interface_class, "ListItems"))
|
||||
self.assertTrue(hasattr(interface_class, "SpeakText"))
|
||||
self.assertIsInstance(interface_class.Enabled, property)
|
||||
self.assertFalse(hasattr(interface_class, "ExecuteCommand"))
|
||||
self.assertIn("org.stormux.Cthulhu1.TestModule", interface_class.__dbus_xml__)
|
||||
|
||||
def test_generated_command_method_uses_active_or_default_script(self):
|
||||
module = SampleModule()
|
||||
registration = dbus_service._ModuleRegistration.from_module_instance("TestModule", module)
|
||||
interface = dbus_service._InterfaceBuilder.build(registration)()
|
||||
script = mock.Mock()
|
||||
manager = mock.Mock()
|
||||
manager.get_active_script.return_value = None
|
||||
manager.get_default_script.return_value = script
|
||||
event_manager = mock.Mock()
|
||||
event_manager_module = mock.Mock()
|
||||
event_manager_module.get_manager.return_value = event_manager
|
||||
|
||||
with (
|
||||
mock.patch.object(dbus_service.script_manager, "get_manager", return_value=manager),
|
||||
mock.patch.object(
|
||||
dbus_service, "_get_input_event_manager", return_value=event_manager_module
|
||||
),
|
||||
):
|
||||
self.assertTrue(interface.ToggleFeature(False))
|
||||
self.assertTrue(interface.CommandWithoutNotify(False))
|
||||
self.assertEqual(interface.ListItems(False), ["alpha", "beta"])
|
||||
|
||||
self.assertEqual(module.calls[0][0], script)
|
||||
self.assertFalse(module.calls[0][2])
|
||||
self.assertEqual(module.calls[1][0], script)
|
||||
self.assertEqual(event_manager.process_remote_controller_event.call_count, 3)
|
||||
|
||||
def test_generated_properties_call_getters_and_setters(self):
|
||||
module = SampleModule()
|
||||
registration = dbus_service._ModuleRegistration.from_module_instance("TestModule", module)
|
||||
interface = dbus_service._InterfaceBuilder.build(registration)()
|
||||
|
||||
self.assertFalse(interface.Enabled)
|
||||
interface.Enabled = True
|
||||
self.assertTrue(module.enabled)
|
||||
self.assertTrue(interface.Enabled)
|
||||
|
||||
|
||||
class NativeRemoteControllerTest(unittest.TestCase):
|
||||
def test_controller_uses_versioned_service_name_and_object_path(self):
|
||||
self.assertEqual(dbus_service.CthulhuRemoteController.SERVICE_NAME, "org.stormux.Cthulhu1.Service")
|
||||
self.assertEqual(dbus_service.CthulhuRemoteController.OBJECT_PATH, "/org/stormux/Cthulhu1/Service")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user