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:
|
Cthulhu now includes a D-Bus service for remote control:
|
||||||
|
|
||||||
- **Service**: `org.stormux.Cthulhu.Service`
|
- **Service**: `org.stormux.Cthulhu1.Service`
|
||||||
- **Path**: `/org/stormux/Cthulhu/Service`
|
- **Path**: `/org/stormux/Cthulhu1/Service`
|
||||||
- **Requires**: `dasbus` library (should be installed)
|
- **Requires**: `dasbus` library (should be installed)
|
||||||
|
|
||||||
### Testing D-Bus Service
|
### Testing D-Bus Service
|
||||||
@@ -70,10 +70,10 @@ Cthulhu now includes a D-Bus service for remote control:
|
|||||||
~/.local/bin/cthulhu
|
~/.local/bin/cthulhu
|
||||||
|
|
||||||
# In another terminal, test the service
|
# 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
|
# 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
|
## Development Workflow
|
||||||
|
|||||||
+89
-174
@@ -22,10 +22,11 @@ on any Linux desktop environment or window manager.
|
|||||||
|
|
||||||
Cthulhu exposes a D-Bus service at:
|
Cthulhu exposes a D-Bus service at:
|
||||||
|
|
||||||
- **Service Name**: `org.stormux.Cthulhu.Service`
|
- **Service Name**: `org.stormux.Cthulhu1.Service`
|
||||||
- **Main Object Path**: `/org/stormux/Cthulhu/Service`
|
- **Main Object Path**: `/org/stormux/Cthulhu1/Service`
|
||||||
- **Module Object Paths**: `/org/stormux.Cthulhu/Service/ModuleName`
|
- **Module Object Paths**: `/org/stormux/Cthulhu1/Service/ModuleName`
|
||||||
(e.g., `/org/stormux/Cthulhu/Service/SpeechAndVerbosityManager`)
|
(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
|
See [REMOTE-CONTROLLER-COMMANDS.md](REMOTE-CONTROLLER-COMMANDS.md) for a complete
|
||||||
list of available commands.
|
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)
|
### Using `busctl` (systemd D-Bus tool)
|
||||||
```bash
|
```bash
|
||||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||||
org.stormux.Cthulhu.Service GetVersion
|
org.stormux.Cthulhu1.Service GetVersion
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using Python with `dasbus`
|
### Using Python with `dasbus`
|
||||||
```python
|
```python
|
||||||
from dasbus.connection import SessionMessageBus
|
from dasbus.connection import SessionMessageBus
|
||||||
bus = 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()
|
version = proxy.GetVersion()
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using `qdbus` (Qt D-Bus tool - available on KDE)
|
### Using `qdbus` (Qt D-Bus tool - available on KDE)
|
||||||
```bash
|
```bash
|
||||||
qdbus org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
qdbus org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||||
org.stormux.Cthulhu.Service.GetVersion
|
org.stormux.Cthulhu1.Service.GetVersion
|
||||||
```
|
```
|
||||||
|
|
||||||
## Service-Level Commands
|
## 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
|
### Get Cthulhu's Version
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service \
|
--object-path /org/stormux/Cthulhu1/Service \
|
||||||
--method org.stormux.Cthulhu.Service.GetVersion
|
--method org.stormux.Cthulhu1.Service.GetVersion
|
||||||
```
|
```
|
||||||
|
|
||||||
**Returns:** String containing the version (and revision if available)
|
**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
|
### Present a Custom Message in Speech and/or Braille
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service \
|
--object-path /org/stormux/Cthulhu1/Service \
|
||||||
--method org.stormux.Cthulhu.Service.PresentMessage "Your message here"
|
--method org.stormux.Cthulhu1.Service.PresentMessage "Your message here"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
@@ -92,9 +93,9 @@ gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|||||||
### Show Cthulhu's Preferences GUI
|
### Show Cthulhu's Preferences GUI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service \
|
--object-path /org/stormux/Cthulhu1/Service \
|
||||||
--method org.stormux.Cthulhu.Service.ShowPreferences
|
--method org.stormux.Cthulhu1.Service.ShowPreferences
|
||||||
```
|
```
|
||||||
|
|
||||||
**Returns:** Boolean indicating success
|
**Returns:** Boolean indicating success
|
||||||
@@ -102,44 +103,39 @@ gdbus call --session --dest org.stormux.Cthulhu.Service \
|
|||||||
### Quit Cthulhu
|
### Quit Cthulhu
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service \
|
--object-path /org/stormux/Cthulhu1/Service \
|
||||||
--method org.stormux.Cthulhu.Service.Quit
|
--method org.stormux.Cthulhu1.Service.Quit
|
||||||
```
|
```
|
||||||
|
|
||||||
**Returns:** Boolean indicating if the quit request was accepted
|
**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
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service \
|
--object-path /org/stormux/Cthulhu1/Service --recurse
|
||||||
--method org.stormux.Cthulhu.Service.ListCommands
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Returns:** List of (command_name, description) tuples
|
The child `<node>` entries beneath `/org/stormux/Cthulhu1/Service` are the
|
||||||
|
registered modules. To inspect the methods and properties for one module:
|
||||||
### List Registered Modules
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service \
|
--object-path /org/stormux/Cthulhu1/Service/SpeechManager
|
||||||
--method org.stormux.Cthulhu.Service.ListModules
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Returns:** List of module names
|
|
||||||
|
|
||||||
## Interacting with Modules
|
## Interacting with Modules
|
||||||
|
|
||||||
Each registered module exposes its own set of operations. Based on the underlying Cthulhu code, these
|
Each registered module exposes its own native DBus interface. Based on the underlying Cthulhu code,
|
||||||
are categorized as **Commands**, **Runtime Getters**, and **Runtime Setters**:
|
these are categorized as **Commands** and **Properties**:
|
||||||
|
|
||||||
- **Commands**: Actions that perform a task. These typically correspond to Cthulhu commands bound
|
- **Commands**: Actions that perform a task. These typically correspond to Cthulhu commands bound
|
||||||
to a keystroke (e.g., `IncreaseRate`).
|
to a keystroke (e.g., `IncreaseRate`).
|
||||||
- **Runtime Getters**: Operations that retrieve the current value of an item, often a setting
|
- **Properties**: Runtime values, often settings (e.g., `Rate`). Setting a property does not cause
|
||||||
(e.g., `GetRate`).
|
it to become permanently saved.
|
||||||
- **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.
|
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
|
Plugins that expose D-Bus decorators are automatically registered as modules using the naming
|
||||||
convention `Plugin_<ModuleName>` (e.g., `Plugin_GameMode`, `Plugin_WindowTitleReader`). Use
|
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
|
#### Plugin_WindowTitleReader
|
||||||
|
|
||||||
Controls for the Window Title Reader plugin:
|
Controls for the Window Title Reader plugin:
|
||||||
|
|
||||||
- Parameterized command: `SetEnabled` (`enabled`: bool)
|
- Method: `SetEnabled` (`enabled`: bool, `notify_user`: bool)
|
||||||
- Runtime getter: `Enabled`
|
- Property: `Enabled`
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
--object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand \
|
--method org.stormux.Cthulhu1.Plugin_WindowTitleReader.SetEnabled true false
|
||||||
'SetEnabled' '{"enabled": <true>}' false
|
|
||||||
|
|
||||||
# Check current state
|
# Check current state
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
--object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeGetter 'Enabled'
|
--method org.freedesktop.DBus.Properties.Get \
|
||||||
|
org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled
|
||||||
```
|
```
|
||||||
|
|
||||||
Busctl example:
|
Busctl example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
busctl --user call org.stormux.Cthulhu.Service \
|
busctl --user call org.stormux.Cthulhu1.Service \
|
||||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||||
org.stormux.Cthulhu.Module ExecuteParameterizedCommand \
|
org.stormux.Cthulhu1.Plugin_WindowTitleReader SetEnabled bb true false
|
||||||
s a{sv} b 'SetEnabled' 1 enabled b true false
|
|
||||||
|
|
||||||
# Check current state
|
# Check current state
|
||||||
busctl --user call org.stormux.Cthulhu.Service \
|
busctl --user call org.stormux.Cthulhu1.Service \
|
||||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||||
org.stormux.Cthulhu.Module ExecuteRuntimeGetter s 'Enabled'
|
org.freedesktop.DBus.Properties Get ss \
|
||||||
|
org.stormux.Cthulhu1.Plugin_WindowTitleReader Enabled
|
||||||
```
|
```
|
||||||
|
|
||||||
### PluginSystemManager Module
|
### PluginSystemManager Module
|
||||||
@@ -190,166 +186,85 @@ The `PluginSystemManager` module provides session-only plugin control:
|
|||||||
|
|
||||||
- `ListPlugins`
|
- `ListPlugins`
|
||||||
- `ListActivePlugins`
|
- `ListActivePlugins`
|
||||||
- `IsPluginActive` (parameterized)
|
- `IsPluginActive`
|
||||||
- `SetPluginActive` (parameterized)
|
- `SetPluginActive`
|
||||||
- `RescanPlugins`
|
- `RescanPlugins`
|
||||||
|
|
||||||
These calls do **not** persist changes to user preferences.
|
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
|
### Executing Module Operations
|
||||||
|
|
||||||
#### Execute a Runtime Getter
|
#### Get a Property
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeGetter 'PropertyName'
|
--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
|
##### Example: Get the current speech rate
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeGetter 'Rate'
|
--method org.freedesktop.DBus.Properties.Get \
|
||||||
|
org.stormux.Cthulhu1.SpeechManager Rate
|
||||||
```
|
```
|
||||||
|
|
||||||
This will return the rate as a GLib Variant.
|
#### Set a Property
|
||||||
|
|
||||||
#### Execute a Runtime Setter
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeSetter 'PropertyName' <value>
|
--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
|
##### Example: Set the current speech rate
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteRuntimeSetter 'Rate' '<90>'
|
--method org.freedesktop.DBus.Properties.Set \
|
||||||
|
org.stormux.Cthulhu1.SpeechManager Rate '<90>'
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Execute a Module Command
|
#### Execute a Module Command
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# With user notification
|
# With user notification
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteCommand 'CommandName' true
|
--method org.stormux.Cthulhu1.ModuleName.CommandName true
|
||||||
|
|
||||||
# Without user notification (silent)
|
# Without user notification (silent)
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteCommand 'CommandName' false
|
--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)
|
- `notify_user` (boolean): Whether to notify the user of the action (see section below)
|
||||||
|
|
||||||
**Returns:** Boolean indicating success
|
|
||||||
|
|
||||||
#### Execute a Parameterized Command
|
#### Execute a Parameterized Command
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
--object-path /org/stormux/Cthulhu1/Service/ModuleName \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand 'CommandName' \
|
--method org.stormux.Cthulhu1.ModuleName.CommandName \
|
||||||
'{"param1": <"value1">, "param2": <"value2">}' false
|
"value1" "value2" false
|
||||||
```
|
```
|
||||||
|
|
||||||
**Parameters:**
|
**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
|
- `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
|
##### Example: Get voices for a specific language
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand 'GetVoicesForLanguage' \
|
--method org.stormux.Cthulhu1.SpeechManager.GetVoicesForLanguage "en-us" "" false
|
||||||
'{"language": <"en-us">, "variant": <"">}' false
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This will return a list of available voices for US English.
|
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
|
```bash
|
||||||
# This command should simply stop speech, not announce that it is stopping speech.
|
# This command should simply stop speech, not announce that it is stopping speech.
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/SpeechAndVerbosityManager \
|
--object-path /org/stormux/Cthulhu1/Service/SpeechManager \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteCommand 'InterruptSpeech' true
|
--method org.stormux.Cthulhu1.SpeechManager.InterruptSpeech true
|
||||||
```
|
```
|
||||||
|
|
||||||
In those cases Cthulhu will ignore the value of `notify_user`.
|
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.
|
Cthulhu exposes a D-Bus service for external automation and integrations.
|
||||||
|
|
||||||
### Service Details
|
### Service Details
|
||||||
- **Service Name**: `org.stormux.Cthulhu.Service`
|
- **Service Name**: `org.stormux.Cthulhu1.Service`
|
||||||
- **Main Object Path**: `/org/stormux/Cthulhu/Service`
|
- **Main Object Path**: `/org/stormux/Cthulhu1/Service`
|
||||||
- **Module Object Paths**: `/org/stormux/Cthulhu/Service/<ModuleName>`
|
- **Module Object Paths**: `/org/stormux/Cthulhu1/Service/<ModuleName>`
|
||||||
|
- **Module Interfaces**: `org.stormux.Cthulhu1.<ModuleName>`
|
||||||
|
|
||||||
### Discovering Capabilities
|
### Discovering Capabilities
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# List registered modules
|
# List registered module object paths and introspect their methods/properties
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service \
|
--object-path /org/stormux/Cthulhu1/Service --recurse
|
||||||
--method org.stormux.Cthulhu.Service.ListModules
|
|
||||||
|
|
||||||
# List commands on a module
|
# Inspect one module
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus introspect --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/ModuleName \
|
--object-path /org/stormux/Cthulhu1/Service/ModuleName
|
||||||
--method org.stormux.Cthulhu.Module.ListCommands
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Plugin Modules
|
### Plugin Modules
|
||||||
@@ -95,8 +94,8 @@ The `PluginSystemManager` module provides **session-only** plugin control (no pr
|
|||||||
|
|
||||||
- `ListPlugins`
|
- `ListPlugins`
|
||||||
- `ListActivePlugins`
|
- `ListActivePlugins`
|
||||||
- `IsPluginActive` (parameterized)
|
- `IsPluginActive`
|
||||||
- `SetPluginActive` (parameterized)
|
- `SetPluginActive`
|
||||||
- `RescanPlugins`
|
- `RescanPlugins`
|
||||||
|
|
||||||
### Plugin Preferences Pages
|
### Plugin Preferences Pages
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ This document lists the currently available D-Bus commands in Cthulhu's Remote C
|
|||||||
|
|
||||||
## Service-Level Commands
|
## 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
|
### 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) |
|
| `PresentMessage` | Present a message via speech/braille | `message` (string) | Boolean (success) |
|
||||||
| `ShowPreferences` | Opens Cthulhu's preferences GUI | None | Boolean (success) |
|
| `ShowPreferences` | Opens Cthulhu's preferences GUI | None | Boolean (success) |
|
||||||
| `Quit` | Exits Cthulhu | None | Boolean (accepted) |
|
| `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
|
### Example Usage
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Get Cthulhu version
|
# Get Cthulhu version
|
||||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||||
org.stormux.Cthulhu.Service GetVersion
|
org.stormux.Cthulhu1.Service GetVersion
|
||||||
|
|
||||||
# Present a custom message
|
# Present a custom message
|
||||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||||
org.stormux.Cthulhu.Service PresentMessage s "Hello from D-Bus"
|
org.stormux.Cthulhu1.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
|
|
||||||
|
|
||||||
# Open preferences
|
# Open preferences
|
||||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||||
org.stormux.Cthulhu.Service ShowPreferences
|
org.stormux.Cthulhu1.Service ShowPreferences
|
||||||
|
|
||||||
# Quit Cthulhu
|
# Quit Cthulhu
|
||||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
busctl --user call org.stormux.Cthulhu1.Service /org/stormux/Cthulhu1/Service \
|
||||||
org.stormux.Cthulhu.Service Quit
|
org.stormux.Cthulhu1.Service Quit
|
||||||
```
|
```
|
||||||
|
|
||||||
## Module-Level Commands
|
## 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
|
### PluginSystemManager
|
||||||
|
|
||||||
@@ -62,8 +59,8 @@ Session-only plugin control (does not persist preferences):
|
|||||||
|
|
||||||
- `ListPlugins`
|
- `ListPlugins`
|
||||||
- `ListActivePlugins`
|
- `ListActivePlugins`
|
||||||
- `IsPluginActive` (parameterized)
|
- `IsPluginActive`
|
||||||
- `SetPluginActive` (parameterized)
|
- `SetPluginActive`
|
||||||
- `RescanPlugins`
|
- `RescanPlugins`
|
||||||
|
|
||||||
### Plugin Modules
|
### Plugin Modules
|
||||||
@@ -73,31 +70,30 @@ convention `Plugin_<ModuleName>` (e.g., `Plugin_GameMode`, `Plugin_WindowTitleRe
|
|||||||
|
|
||||||
#### WindowTitleReader (Plugin_WindowTitleReader)
|
#### WindowTitleReader (Plugin_WindowTitleReader)
|
||||||
|
|
||||||
- `SetEnabled` (parameterized) -> enabled (bool)
|
- `SetEnabled` -> enabled (bool), notify_user (bool)
|
||||||
- `Enabled` (runtime getter)
|
- `Enabled` (property)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gdbus call --session --dest org.stormux.Cthulhu.Service \
|
gdbus call --session --dest org.stormux.Cthulhu1.Service \
|
||||||
--object-path /org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
--object-path /org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||||
--method org.stormux.Cthulhu.Module.ExecuteParameterizedCommand \
|
--method org.stormux.Cthulhu1.Plugin_WindowTitleReader.SetEnabled true false
|
||||||
'SetEnabled' '{"enabled": <true>}' false
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Busctl example:
|
Busctl example:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
busctl --user call org.stormux.Cthulhu.Service \
|
busctl --user call org.stormux.Cthulhu1.Service \
|
||||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||||
org.stormux.Cthulhu.Module ExecuteParameterizedCommand \
|
org.stormux.Cthulhu1.Plugin_WindowTitleReader SetEnabled bb true false
|
||||||
s a{sv} b 'SetEnabled' 1 enabled b true false
|
|
||||||
```
|
```
|
||||||
|
|
||||||
# Check current state
|
# Check current state
|
||||||
busctl --user call org.stormux.Cthulhu.Service \
|
busctl --user call org.stormux.Cthulhu1.Service \
|
||||||
/org/stormux/Cthulhu/Service/Plugin_WindowTitleReader \
|
/org/stormux/Cthulhu1/Service/Plugin_WindowTitleReader \
|
||||||
org.stormux.Cthulhu.Module ExecuteRuntimeGetter s 'Enabled'
|
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.
|
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
|
# Check if Cthulhu's D-Bus service is running
|
||||||
busctl --user list | grep Cthulhu
|
busctl --user list | grep Cthulhu
|
||||||
|
|
||||||
# Introspect the service to see all available methods
|
# Introspect the service to see available module nodes
|
||||||
busctl --user introspect org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service
|
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
|
# Get detailed service information
|
||||||
busctl --user status org.stormux.Cthulhu.Service
|
busctl --user status org.stormux.Cthulhu1.Service
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributing
|
## 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}")
|
logger.error(f"Failed to deregister D-Bus module for plugin {plugin_info.get_module_name()}: {error}")
|
||||||
|
|
||||||
@dbus_service.command
|
@dbus_service.command
|
||||||
def list_plugins(self):
|
def list_plugins(self) -> list[str]:
|
||||||
"""Returns a list of available plugin module names."""
|
"""Returns a list of available plugin module names."""
|
||||||
if not self._plugins:
|
if not self._plugins:
|
||||||
self.rescanPlugins()
|
self.rescanPlugins()
|
||||||
return [info.get_module_name() for info in self.plugins]
|
return [info.get_module_name() for info in self.plugins]
|
||||||
|
|
||||||
@dbus_service.command
|
@dbus_service.command
|
||||||
def list_active_plugins(self):
|
def list_active_plugins(self) -> list[str]:
|
||||||
"""Returns a list of currently active plugin module names."""
|
"""Returns a list of currently active plugin module names."""
|
||||||
return [info.get_module_name() for info in self.plugins if info.loaded]
|
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