Backport Orca's d-bus remote fixes.

This commit is contained in:
Storm Dragon
2026-04-26 13:18:23 -04:00
parent 337b5d4273
commit 265feb8188
7 changed files with 1017 additions and 888 deletions
+4 -4
View File
@@ -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
View File
@@ -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`.
+12 -13
View File
@@ -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
+38 -38
View File
@@ -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
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -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()