Compare commits
90 Commits
toml
...
2026.05.14
| Author | SHA1 | Date | |
|---|---|---|---|
| e2f9a7c2e2 | |||
| 922ba60445 | |||
| a5f7c9a8f3 | |||
| 6f33caade1 | |||
| e54600ff4d | |||
| e6b6b1051e | |||
| e377f39fe3 | |||
| 42006f4725 | |||
| 3ae49f48ac | |||
| 4c0c0013ca | |||
| 77b7c81d73 | |||
| 265feb8188 | |||
| 337b5d4273 | |||
| 1707dca020 | |||
| 60d3fc613b | |||
| 23abeca651 | |||
| a98aa174f8 | |||
| ec7e073431 | |||
| 5bb5f3d711 | |||
| 8fc77c5a2f | |||
| 309822a0ca | |||
| 80d53ebcc3 | |||
| 3671b0d6b9 | |||
| d0aef1331d | |||
| f2f1de737d | |||
| 0f54fad9ba | |||
| daf3d46eeb | |||
| 16004af7c1 | |||
| 45b57b4d13 | |||
| 629785d548 | |||
| fb5684f8ef | |||
| 56030567ed | |||
| 6793522d93 | |||
| 67abceda9a | |||
| cc5adf4cce | |||
| 04c79f2e0f | |||
| 4a41b51d37 | |||
| 3dc565e8df | |||
| 6e049e35e2 | |||
| ee4292564a | |||
| eeb7bd046f | |||
| 2d9790de88 | |||
| 633ff214a4 | |||
| ceb03668b9 | |||
| d7d26c57f4 | |||
| 8e792dd4e2 | |||
| 9c94191583 | |||
| d51ef2ad69 | |||
| e72cc79c6a | |||
| 667c0babcb | |||
| a8950c42e2 | |||
| 91edf64a72 | |||
| 296c47be36 | |||
| 5779444d4b | |||
| c072f903db | |||
| 64ad1ab3e0 | |||
| 20e61d6259 | |||
| a750761f61 | |||
| 03b3880622 | |||
| f4af54228a | |||
| 518d2b3bb6 | |||
| 7043f08dab | |||
| d0bc7d8a3a | |||
| 438fae4fef | |||
| a7cd1d033a | |||
| c4890f31af | |||
| c44245189a | |||
| c7b8e4a30d | |||
| 20fe1a7e30 | |||
| 25931758f7 | |||
| daf57ef22c | |||
| 1d2d727fa2 | |||
| 11bd7107d2 | |||
| 95d33047fa | |||
| 523b896053 | |||
| 9152455227 | |||
| c0fdaca4d0 | |||
| 8312a842c1 | |||
| 07138197cb | |||
| ed78ffc248 | |||
| 4add36f5ca | |||
| 40e63150a6 | |||
| 4dba0ec0cd | |||
| e6f780c38b | |||
| 0f7f73a6a0 | |||
| aa71d02036 | |||
| 51ef3de672 | |||
| c6049ef5f3 | |||
| 78ef51d01f | |||
| 30a40f6974 |
@@ -75,6 +75,7 @@ debug.log
|
||||
# Package artifacts
|
||||
*.pkg.tar.zst
|
||||
distro-packages/*/cthulhu/
|
||||
distro-packages/*/cthulhu-git/
|
||||
distro-packages/*/pkg/
|
||||
|
||||
# Generated makefiles (should not be committed)
|
||||
@@ -103,3 +104,4 @@ po/insert-header.sed
|
||||
/help/*/*.mo
|
||||
/help/*/*.stamp
|
||||
.aider*
|
||||
.worktrees/
|
||||
|
||||
@@ -14,6 +14,23 @@ This repository is a screen reader. Prioritize accessibility, correctness, and s
|
||||
- `meson compile -C _build`
|
||||
- `meson install -C _build`
|
||||
|
||||
## Runtime target and testing rules
|
||||
- Make source changes in this repo, not in `~/.local/lib/python*/site-packages/cthulhu/`, unless the user explicitly asks for an installed-package hotfix.
|
||||
- If you confirm the active import comes from `~/.local/...`, that does **not** mean you should edit there. It means you should update the repo and then run `./build-local.sh` to replace the installed copy for testing.
|
||||
- Default test/apply workflow for local Cthulhu fixes:
|
||||
- edit repo files
|
||||
- run `./build-local.sh`
|
||||
- reproduce/test against the refreshed `~/.local` install
|
||||
- If repo and installed behavior differ, prefer rebuilding with `./build-local.sh` over patching the installed package directly.
|
||||
- Treat direct edits under `~/.local/.../cthulhu/` as an exception path that requires explicit user approval.
|
||||
|
||||
## Platform support stance
|
||||
- **critical** Robust Xorg support is required and is a merge gate for Cthulhu.
|
||||
- Wayland support is desirable, but it is secondary to keeping Xorg stable and usable.
|
||||
- If a change that improves Wayland would break, weaken, or regress Xorg support, the answer is a hard no by default.
|
||||
- If the user explicitly insists on such a change anyway, warn them plainly that the change is expected to be rejected without further consideration as long as Xorg is adversely affected.
|
||||
- Prefer desktop-agnostic fixes first. If a tradeoff is unavoidable, choose the path that preserves Xorg correctness and defer the Wayland-specific improvement.
|
||||
|
||||
## Coding guidelines
|
||||
- **When modifying existing code:** follow the surrounding code’s conventions.
|
||||
- **When writing new code from scratch:** prefer
|
||||
@@ -55,3 +72,8 @@ This repository is a screen reader. Prioritize accessibility, correctness, and s
|
||||
## Meson install reminder (important)
|
||||
- If you add new Python modules under `src/cthulhu/`, update `src/cthulhu/meson.build` so they get installed (otherwise imports can fail after install).
|
||||
- If you add a new plugin directory, update `src/cthulhu/plugins/meson.build` and add a `meson.build` in the plugin directory.
|
||||
|
||||
## Common Cthulhu agent mistakes
|
||||
- Checking the import origin, seeing `~/.local/...`, and then editing the installed package instead of the repo.
|
||||
- Forgetting that `./build-local.sh` is the normal way to apply repo changes into the installed copy for testing.
|
||||
- Making repo fixes and then diagnosing the old installed copy without rebuilding.
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Cthulhu is a fork of the Orca screen reader, designed as a desktop-agnostic screen reader for Linux. It works with applications supporting AT-SPI (Assistive Technology Service Provider Interface) including GTK+, Qt, Java Swing, LibreOffice, Gecko, and WebKitGtk.
|
||||
|
||||
**Key differentiators from Orca:**
|
||||
- Desktop-agnostic: Works on KDE, XFCE, i3, Sway, and other environments (not just GNOME)
|
||||
- Extensible plugin architecture using pluggy framework
|
||||
- D-Bus remote control interface for external automation
|
||||
- Enhanced support for tiling window managers
|
||||
|
||||
## Build Commands
|
||||
|
||||
```bash
|
||||
# Local development build (installs to ~/.local)
|
||||
./build-local.sh
|
||||
|
||||
# Test local installation
|
||||
./test-local.sh
|
||||
|
||||
# Run local version
|
||||
~/.local/bin/cthulhu
|
||||
|
||||
# Clean build artifacts and local installation
|
||||
./clean-local.sh
|
||||
./clean-local.sh --build-only # Clean only build artifacts
|
||||
./clean-local.sh --install-only # Remove only local installation
|
||||
|
||||
# Manual Meson build
|
||||
meson setup _build --prefix=$HOME/.local
|
||||
meson compile -C _build
|
||||
meson install -C _build
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Manual testing is recommended. The legacy keystroke-driven test harness has been removed.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Core Components (`src/cthulhu/`)
|
||||
|
||||
**Event & Input Processing:**
|
||||
- `event_manager.py` - Central AT-SPI event handling and routing
|
||||
- `input_event_manager.py` - Keyboard/mouse input processing
|
||||
- `input_event.py` - Input event data structures
|
||||
- `focus_manager.py` - Focus tracking across applications
|
||||
|
||||
**Accessibility Layer (ax_* files):**
|
||||
- `ax_object.py` - Core accessible object abstraction
|
||||
- `ax_utilities.py` - Common accessibility utilities
|
||||
- `ax_utilities_role.py` - Role-based accessibility helpers
|
||||
- `ax_utilities_collection.py` - Collection traversal utilities
|
||||
- `ax_text.py`, `ax_table.py`, `ax_component.py` - Specialized interfaces
|
||||
|
||||
**Output Systems:**
|
||||
- `speech.py`, `speechdispatcherfactory.py` - Speech synthesis
|
||||
- `braille.py`, `braille_generator.py` - Braille display support
|
||||
- `speech_generator.py` - Generate speech from accessible objects
|
||||
- `sound.py`, `sound_generator.py` - Audio cue generation
|
||||
|
||||
**Script System:**
|
||||
- `script_manager.py` - Loads/manages application-specific scripts
|
||||
- `script.py` - Base script class
|
||||
- `scripts/default.py` - Default behavior for all applications
|
||||
- `scripts/apps/` - Application-specific customizations (Firefox, LibreOffice, etc.)
|
||||
- `scripts/toolkits/` - Toolkit-specific scripts (GTK, Qt, WebKitGtk)
|
||||
- `scripts/web/` - Web content handling
|
||||
|
||||
**Plugin System:**
|
||||
- `plugin.py` - Base plugin class with `cthulhu_hookimpl` decorator
|
||||
- `plugin_system_manager.py` - Plugin discovery and lifecycle
|
||||
- `plugins/` - Built-in plugins (OCR, Clipboard, SpeechHistory, etc.)
|
||||
|
||||
**D-Bus Remote Control:**
|
||||
- `dbus_service.py` - D-Bus service implementation
|
||||
- Service: `org.stormux.Cthulhu.Service`
|
||||
- Path: `/org/stormux/Cthulhu/Service`
|
||||
|
||||
**Settings & State:**
|
||||
- `settings_manager.py` - User preferences persistence
|
||||
- `settings.py` - Default settings values
|
||||
- `cthulhu_state.py` - Runtime state (active script, focus, etc.)
|
||||
|
||||
### Key Design Patterns
|
||||
|
||||
**Script Inheritance:** Application scripts extend `default.Script`, overriding methods for custom behavior. The script manager selects scripts based on the focused application.
|
||||
|
||||
**Event Flow:** AT-SPI events → `event_manager` → active script's event handler → generators → output systems (speech/braille)
|
||||
|
||||
**Plugin Hooks:** Plugins implement hooks via `@cthulhu_hookimpl` decorator. Use `registerGestureByString()` for keybindings.
|
||||
|
||||
## Adding New Modules
|
||||
|
||||
When adding new Python modules under `src/cthulhu/`:
|
||||
|
||||
1. **Update `src/cthulhu/meson.build`** - Add the `.py` file to `cthulhu_python_sources`
|
||||
|
||||
2. **For new script modules** (e.g., `scripts/newmodule/`):
|
||||
- Create the directory with `__init__.py` and `script.py`
|
||||
- Add `meson.build` in the new directory
|
||||
- Add subdirectory to `src/cthulhu/scripts/meson.build`
|
||||
|
||||
3. **For new plugins**:
|
||||
- Create directory under `src/cthulhu/plugins/` with:
|
||||
- `__init__.py`, `plugin.py`, `plugin.info`, `meson.build`
|
||||
- Add subdirectory to `src/cthulhu/plugins/meson.build`
|
||||
|
||||
## Plugin Structure
|
||||
|
||||
```
|
||||
src/cthulhu/plugins/MyPlugin/
|
||||
├── __init__.py # from .plugin import *
|
||||
├── plugin.py # Main implementation extending Plugin
|
||||
├── plugin.info # Metadata (name, version, description, etc.)
|
||||
└── meson.build # install_data for .py and .info files
|
||||
```
|
||||
|
||||
Example plugin.py:
|
||||
```python
|
||||
from cthulhu.plugin import Plugin, cthulhu_hookimpl
|
||||
|
||||
class MyPlugin(Plugin):
|
||||
@cthulhu_hookimpl
|
||||
def activate(self, plugin=None):
|
||||
if plugin is not None and plugin is not self:
|
||||
return
|
||||
self.registerGestureByString(self.myHandler, "description", "kb:cthulhu+key")
|
||||
|
||||
def myHandler(self, script=None, inputEvent=None):
|
||||
self.app.getDynamicApiManager().getAPI('CthulhuState').activeScript.presentMessage('Message')
|
||||
return True
|
||||
```
|
||||
|
||||
## D-Bus Testing
|
||||
|
||||
```bash
|
||||
# Check service availability
|
||||
busctl --user list | grep Cthulhu
|
||||
|
||||
# Get version
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service GetVersion
|
||||
|
||||
# Present message
|
||||
busctl --user call org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service \
|
||||
org.stormux.Cthulhu.Service PresentMessage s "Hello"
|
||||
|
||||
# Introspect available methods
|
||||
busctl --user introspect org.stormux.Cthulhu.Service /org/stormux/Cthulhu/Service
|
||||
```
|
||||
|
||||
## Key Keybindings
|
||||
|
||||
- `Cthulhu+Space` - Open preferences
|
||||
- `Cthulhu+H` - Enter learn mode
|
||||
- `Cthulhu+Ctrl+Alt+Shift+Q` - Toggle sleep mode for current application
|
||||
- `Cthulhu+Q` - Quit Cthulhu
|
||||
|
||||
## Self-Voicing Interface
|
||||
|
||||
External applications can speak through Cthulhu via Unix socket:
|
||||
```bash
|
||||
echo "Hello world" | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
||||
echo "<!#APPEND#!>Without interrupt" | socat - UNIX-CLIENT:/tmp/cthulhu.sock
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
|
||||
**Core:** Python 3.9+, pygobject-3.0, gtk+-3.0, AT-SPI2, ATK
|
||||
**Speech:** python-speechd, gstreamer-1.0
|
||||
**Plugins:** pluggy, python-dasbus (optional, for D-Bus)
|
||||
**Braille:** BrlTTY, BrlAPI, liblouis (optional)
|
||||
|
||||
## Repository
|
||||
|
||||
- **Main repo:** https://git.stormux.org/storm/cthulhu
|
||||
- **Community:** IRC #stormux on irc.stormux.org
|
||||
- **Email patches:** storm_dragon@stormux.org
|
||||
+10
-6
@@ -1,5 +1,9 @@
|
||||
# Cthulhu Development Guide
|
||||
|
||||
This document applies to the Cthulhu fork maintained by Storm Dragon.
|
||||
Cthulhu is forked from Orca; prior Orca maintainers and contributors are part
|
||||
of the upstream history, but they are not current maintainers of this fork.
|
||||
|
||||
## Local Development Build
|
||||
|
||||
To develop Cthulhu without overwriting your system installation, use the provided build scripts:
|
||||
@@ -55,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
|
||||
@@ -66,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
|
||||
@@ -98,11 +102,11 @@ git status
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Runtime**: python3, pygobject-3.0, pluggy, AT-SPI2
|
||||
- **Runtime**: python3, pygobject-3.0, pluggy, tomlkit, AT-SPI2
|
||||
- **Build**: meson, ninja, gettext
|
||||
- **Optional**: dasbus (for D-Bus service), BrlTTY, speech-dispatcher, piper-tts
|
||||
|
||||
Install build dependencies on Arch Linux:
|
||||
```bash
|
||||
sudo pacman -S meson ninja gettext python-dasbus
|
||||
sudo pacman -S meson ninja gettext python-dasbus python-tomlkit
|
||||
```
|
||||
|
||||
+94
-174
@@ -1,5 +1,10 @@
|
||||
# Cthulhu Remote Controller (D-Bus Interface)
|
||||
|
||||
This documentation covers the Cthulhu fork maintained by Storm Dragon.
|
||||
Cthulhu is forked from Orca; former Orca maintainers and contributors are part
|
||||
of the project's upstream history, but they are not current maintainers of
|
||||
this fork.
|
||||
|
||||
> **⚠️⚠️ WORK IN PROGRESS**: This D-Bus interface is brand new and not yet feature complete.
|
||||
Low-risk feature additions will continue to be made. The API may be
|
||||
modified beyond bug fixes in future versions based on feedback from consumers of this support.
|
||||
@@ -17,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.
|
||||
@@ -38,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)
|
||||
@@ -73,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:**
|
||||
@@ -87,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
|
||||
@@ -97,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.
|
||||
|
||||
@@ -142,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
|
||||
@@ -185,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.
|
||||
@@ -357,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`.
|
||||
|
||||
@@ -2,7 +2,22 @@
|
||||
|
||||
## Note
|
||||
|
||||
Cthulhu is a fork of the Orca screen reader. Project home: https://git.stormux.org/storm/cthulhu. Cthulhu is currently a supplemental screen reader that fills a nitch for some advanced users. E.g. some older QT based programs may work with Cthulhu, and if you use certain window managers like i3, Mozilla applications like Firefox and Thunderbird may work better.
|
||||
Cthulhu is a fork of the Orca screen reader. Project home: https://git.stormux.org/storm/cthulhu. Cthulhu is currently a supplemental screen reader that fills a niche for some advanced users. For example, some older Qt-based programs may work with Cthulhu, and if you use certain window managers like i3, Mozilla applications like Firefox and Thunderbird may work better.
|
||||
|
||||
## Current Maintenance
|
||||
|
||||
Cthulhu is currently maintained by Storm Dragon.
|
||||
|
||||
Current contributors called out in this fork's documentation:
|
||||
|
||||
- Hunter Joziak
|
||||
- Harley Richardson (`destructatron`)
|
||||
|
||||
## Project History
|
||||
|
||||
Cthulhu is forked from Orca and builds on many years of upstream work by the Orca community, including former maintainers and contributors such as Joanmarie Diggs and others.
|
||||
|
||||
Those upstream maintainers and contributors are part of the project's history, but they are not current maintainers of this fork unless explicitly noted elsewhere.
|
||||
|
||||
|
||||
## Introduction
|
||||
@@ -51,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
|
||||
@@ -80,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
|
||||
@@ -179,6 +193,7 @@ Ensure you have the development dependencies installed:
|
||||
```bash
|
||||
sudo pacman -S python python-gobject gtk3 at-spi2-core at-spi2-atk \
|
||||
python-speechd gstreamer python-pluggy python-dasbus \
|
||||
python-tomlkit \
|
||||
meson ninja pkgconf intltool gettext
|
||||
```
|
||||
|
||||
@@ -187,6 +202,7 @@ sudo pacman -S python python-gobject gtk3 at-spi2-core at-spi2-atk \
|
||||
sudo apt install python3 python3-gi python3-gi-cairo gir1.2-gtk-3.0 \
|
||||
at-spi2-core libatk-adaptor python3-speechd \
|
||||
gstreamer1.0-plugins-base python3-pluggy python3-dasbus \
|
||||
python3-tomlkit \
|
||||
meson ninja-build pkg-config intltool gettext
|
||||
```
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
# Cthulhu Remote Controller - Available Commands
|
||||
|
||||
This documentation covers the Cthulhu fork maintained by Storm Dragon.
|
||||
Cthulhu is forked from Orca; former Orca maintainers and contributors are part
|
||||
of the project's upstream history, but they are not current maintainers of
|
||||
this fork.
|
||||
|
||||
This document lists the currently available D-Bus commands in Cthulhu's Remote Controller interface.
|
||||
|
||||
> **Note**: This is a work-in-progress. As more modules are exposed via D-Bus, this document will be expanded. Eventually this will be auto-generated using `tools/generate_dbus_documentation.py`.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -16,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
|
||||
|
||||
@@ -57,8 +59,8 @@ Session-only plugin control (does not persist preferences):
|
||||
|
||||
- `ListPlugins`
|
||||
- `ListActivePlugins`
|
||||
- `IsPluginActive` (parameterized)
|
||||
- `SetPluginActive` (parameterized)
|
||||
- `IsPluginActive`
|
||||
- `SetPluginActive`
|
||||
- `RescanPlugins`
|
||||
|
||||
### Plugin Modules
|
||||
@@ -68,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.
|
||||
|
||||
@@ -102,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
|
||||
|
||||
@@ -26,6 +26,31 @@ for cmd in meson ninja python3; do
|
||||
fi
|
||||
done
|
||||
|
||||
if ! python3 -c "import tomlkit" 2>/dev/null; then
|
||||
echo "Error: Python module tomlkit is not installed"
|
||||
echo "Please install: python-tomlkit"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
getPythonSiteDir() {
|
||||
python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")'
|
||||
}
|
||||
|
||||
removeExistingLocalInstall() {
|
||||
local pythonSite packageDir binPath desktopFile manPage
|
||||
pythonSite="$HOME/.local/lib/python$(getPythonSiteDir)/site-packages"
|
||||
packageDir="$pythonSite/cthulhu"
|
||||
binPath="$HOME/.local/bin/cthulhu"
|
||||
desktopFile="$HOME/.local/share/applications/cthulhu.desktop"
|
||||
manPage="$HOME/.local/share/man/man1/cthulhu.1"
|
||||
|
||||
echo "Removing existing local installation targets..."
|
||||
rm -f "$binPath"
|
||||
rm -rf "$packageDir"
|
||||
rm -f "$desktopFile"
|
||||
rm -f "$manPage"
|
||||
}
|
||||
|
||||
# Check for optional dependencies
|
||||
missingOptional=()
|
||||
if ! python3 -c "import gi" 2>/dev/null; then
|
||||
@@ -57,6 +82,7 @@ meson compile -C _build
|
||||
|
||||
# Install
|
||||
echo "Installing Cthulhu to ~/.local..."
|
||||
removeExistingLocalInstall
|
||||
meson install -C _build
|
||||
|
||||
# Update desktop database and icon cache
|
||||
|
||||
@@ -8,13 +8,11 @@ set -e # Exit on error
|
||||
|
||||
# Colors for output (only if stdout is a terminal)
|
||||
if [[ -t 1 ]]; then
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
else
|
||||
RED=''
|
||||
GREEN=''
|
||||
YELLOW=''
|
||||
BLUE=''
|
||||
@@ -56,12 +54,6 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
|
||||
# Remove data files
|
||||
|
||||
# Remove desktop files
|
||||
if [[ -f "$HOME/.local/share/applications/cthulhu-autostart.desktop" ]]; then
|
||||
rm -f "$HOME/.local/share/applications/cthulhu-autostart.desktop"
|
||||
echo " Removed: ~/.local/share/applications/cthulhu-autostart.desktop"
|
||||
fi
|
||||
|
||||
# Remove icons
|
||||
for size in 16x16 22x22 24x24 32x32 48x48 256x256 scalable symbolic; do
|
||||
icon_path="$HOME/.local/share/icons/hicolor/$size/apps"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Cthulhu Screen Reader
|
||||
Exec=cthulhu
|
||||
NoDisplay=true
|
||||
# Desktop-neutral autostart - no GNOME-specific conditions
|
||||
# Users can enable/disable via their desktop environment's accessibility settings
|
||||
# or by adding/removing this file from ~/.config/autostart/
|
||||
X-GNOME-AutoRestart=true
|
||||
Categories=Accessibility;
|
||||
Keywords=screen;reader;accessibility;speech;braille;
|
||||
+2
-10
@@ -15,16 +15,8 @@
|
||||
<programming-language>Python</programming-language>
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Joanmarie Diggs</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:jdiggs@igalia.com" />
|
||||
<gnome:userid>joanied</gnome:userid>
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
<maintainer>
|
||||
<foaf:Person>
|
||||
<foaf:name>Federico Mena Quintero</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:federico@gnome.org" />
|
||||
<gnome:userid>federico</gnome:userid>
|
||||
<foaf:name>Storm Dragon</foaf:name>
|
||||
<foaf:mbox rdf:resource="mailto:storm_dragon@stormux.org" />
|
||||
</foaf:Person>
|
||||
</maintainer>
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
# Maintainer: Storm Dragon <storm_dragon@stormux.org>
|
||||
|
||||
pkgname=cthulhu-git
|
||||
_pkgname=cthulhu
|
||||
pkgver=2026.05.06.r394.ga5f7c9a
|
||||
pkgrel=1
|
||||
pkgdesc="Desktop-agnostic screen reader with plugin system, forked from Orca"
|
||||
url="https://git.stormux.org/storm/cthulhu"
|
||||
arch=(any)
|
||||
license=(LGPL)
|
||||
provides=("${_pkgname}")
|
||||
conflicts=("${_pkgname}")
|
||||
depends=(
|
||||
# Core AT-SPI accessibility
|
||||
at-spi2-core
|
||||
gobject-introspection-runtime
|
||||
python-gobject
|
||||
python-cairo
|
||||
gtk3
|
||||
python-pywayland
|
||||
# Audio and speech
|
||||
speech-dispatcher
|
||||
gstreamer
|
||||
gst-plugins-base # playbin, audiotestsrc, basic decoders
|
||||
gst-plugins-good # pulsesink, more decoders
|
||||
|
||||
# Braille support
|
||||
brltty
|
||||
liblouis
|
||||
|
||||
# Plugin system and D-Bus remote control
|
||||
python-pluggy
|
||||
python-tomlkit
|
||||
python-dasbus
|
||||
|
||||
# AI Assistant dependencies (for screenshots, HTTP requests, and actions)
|
||||
python-requests
|
||||
python-pyautogui
|
||||
|
||||
# Desktop integration
|
||||
hicolor-icon-theme
|
||||
libwnck3
|
||||
pango
|
||||
|
||||
# System utilities
|
||||
python
|
||||
python-setproctitle
|
||||
socat # for self-voicing feature
|
||||
xorg-xkbcomp
|
||||
xorg-xmodmap
|
||||
)
|
||||
optdepends=(
|
||||
'espeak-ng: Alternative TTS engine'
|
||||
'festival: Alternative TTS engine'
|
||||
'flite: Lightweight TTS engine'
|
||||
'espeak: Legacy TTS engine'
|
||||
|
||||
# AI Assistant providers (optional)
|
||||
'claude-code: Claude AI provider support'
|
||||
'openai-codex: ChatGPT AI provider support'
|
||||
'gemini-cli: Gemini AI provider support'
|
||||
'ollama: Local AI model support'
|
||||
|
||||
# OCR plugin dependencies (optional)
|
||||
'python-pillow: Image processing for OCR and AI Assistant'
|
||||
'python-pytesseract: Python wrapper for Tesseract OCR engine'
|
||||
'python-pdf2image: PDF to image conversion for OCR'
|
||||
'python-scipy: Scientific computing for OCR color analysis'
|
||||
'python-webcolors: Color name lookup for OCR text decoration'
|
||||
'tesseract: OCR engine for text recognition'
|
||||
'tesseract-data-eng: English language data for Tesseract'
|
||||
|
||||
# nvda2cthulhu plugin (optional)
|
||||
'python-msgpack: Msgpack decoding for nvda2cthulhu'
|
||||
'python-tornado: WebSocket server for nvda2cthulhu'
|
||||
|
||||
# Window Title Reader plugin (optional)
|
||||
'python-xlib: X11 access for Wine window title plugin'
|
||||
)
|
||||
makedepends=(
|
||||
git
|
||||
meson
|
||||
ninja
|
||||
python-build
|
||||
python-installer
|
||||
python-wheel
|
||||
)
|
||||
install=cthulhu.install
|
||||
source=(
|
||||
"${_pkgname}::git+https://git.stormux.org/storm/${_pkgname}.git#branch=master"
|
||||
"cthulhu.install"
|
||||
)
|
||||
b2sums=(
|
||||
'SKIP'
|
||||
'SKIP'
|
||||
)
|
||||
|
||||
pkgver() {
|
||||
cd "${_pkgname}"
|
||||
local projectVersion revisionCount commitHash
|
||||
|
||||
projectVersion=$(sed -n "s/^[[:space:]]*version: '\([^']*\)'.*/\1/p" meson.build)
|
||||
projectVersion=${projectVersion%-master}
|
||||
projectVersion=${projectVersion//-/.}
|
||||
[[ -n "${projectVersion}" ]] || return 1
|
||||
|
||||
revisionCount=$(git rev-list --count HEAD)
|
||||
commitHash=$(git rev-parse --short=7 HEAD)
|
||||
printf "%s.r%s.g%s\n" "${projectVersion}" "${revisionCount}" "${commitHash}"
|
||||
}
|
||||
|
||||
build() {
|
||||
cd "${_pkgname}"
|
||||
arch-meson _build
|
||||
meson compile -C _build
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "${_pkgname}"
|
||||
meson install -C _build --destdir "$pkgdir"
|
||||
|
||||
# Remove icon cache - it will be generated by post-install hooks
|
||||
rm -f "$pkgdir/usr/share/icons/hicolor/icon-theme.cache"
|
||||
}
|
||||
|
||||
# vim:set sw=2 sts=-1 et:
|
||||
@@ -1,7 +1,7 @@
|
||||
# Maintainer: Storm Dragon <storm_dragon@stormux.org>
|
||||
|
||||
pkgname=cthulhu
|
||||
pkgver=2026.01.19
|
||||
pkgver=2026.05.14
|
||||
pkgrel=1
|
||||
pkgdesc="Desktop-agnostic screen reader with plugin system, forked from Orca"
|
||||
url="https://git.stormux.org/storm/cthulhu"
|
||||
@@ -14,7 +14,7 @@ depends=(
|
||||
python-gobject
|
||||
python-cairo
|
||||
gtk3
|
||||
|
||||
python-pywayland
|
||||
# Audio and speech
|
||||
speech-dispatcher
|
||||
gstreamer
|
||||
@@ -84,7 +84,7 @@ makedepends=(
|
||||
)
|
||||
install=cthulhu.install
|
||||
source=(
|
||||
"git+https://git.stormux.org/storm/cthulhu.git"
|
||||
"git+https://git.stormux.org/storm/cthulhu.git#tag=${pkgver}"
|
||||
"cthulhu.install"
|
||||
)
|
||||
b2sums=(
|
||||
@@ -92,11 +92,6 @@ b2sums=(
|
||||
'SKIP'
|
||||
)
|
||||
|
||||
pkgver() {
|
||||
cd cthulhu
|
||||
grep "^version = " src/cthulhu/cthulhuVersion.py | sed 's/version = "\(.*\)"/\1/'
|
||||
}
|
||||
|
||||
build() {
|
||||
cd cthulhu
|
||||
arch-meson _build
|
||||
@@ -0,0 +1,11 @@
|
||||
post_install() {
|
||||
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
|
||||
}
|
||||
|
||||
post_upgrade() {
|
||||
post_install
|
||||
}
|
||||
|
||||
post_remove() {
|
||||
gtk-update-icon-cache -q -t -f usr/share/icons/hicolor
|
||||
}
|
||||
@@ -82,7 +82,7 @@ find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | gr
|
||||
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
|
||||
|
||||
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cp -a AUTHORS COPYING ChangeLog NEWS README.md \
|
||||
cp -a AUTHORS COPYING ChangeLog README.md \
|
||||
$PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
Cthulhu is a screen reader for individuals who are blind or visually impaired,
|
||||
forked from Orca. It provides access to applications and toolkits that support
|
||||
the AT-SPI (e.g., the GNOME desktop).
|
||||
the AT-SPI (e.g., GNOME and other Linux desktop environments).
|
||||
|
||||
This fork is currently maintained by Storm Dragon. It builds on upstream Orca
|
||||
work, but former Orca maintainers and contributors are not current maintainers
|
||||
of this fork.
|
||||
|
||||
This screen reader helps users navigate their desktop environment and applications
|
||||
through speech synthesis and braille output.
|
||||
|
||||
After installation, you can start Cthulhu through the GNOME desktop environment
|
||||
After installation, you can start Cthulhu through your desktop environment
|
||||
or by running 'cthulhu' from the command line.
|
||||
|
||||
DEPENDENCIES:
|
||||
@@ -13,7 +17,6 @@ This package requires the following packages, all available from SlackBuilds.org
|
||||
- at-spi2-core
|
||||
- brltty
|
||||
- gobject-introspection
|
||||
- gsettings-desktop-schemas
|
||||
- gstreamer
|
||||
- gst-plugins-base
|
||||
- gst-plugins-good
|
||||
|
||||
@@ -5,6 +5,6 @@ DOWNLOAD="https://git.stormux.org/storm/cthulhu.git"
|
||||
MD5SUM="SKIP"
|
||||
DOWNLOAD_x86_64=""
|
||||
MD5SUM_x86_64=""
|
||||
REQUIRES="at-spi2-core brltty gobject-introspection gsettings-desktop-schemas gstreamer gst-plugins-base gst-plugins-good gtk3 liblouis libwnck3 python3-atspi python3-cairo python3-gobject python3-setproctitle speech-dispatcher"
|
||||
REQUIRES="at-spi2-core brltty gobject-introspection gstreamer gst-plugins-base gst-plugins-good gtk3 liblouis libwnck3 python3-atspi python3-cairo python3-gobject python3-setproctitle speech-dispatcher"
|
||||
MAINTAINER="Storm Dragon"
|
||||
EMAIL="storm_dragon@stormux.org"
|
||||
|
||||
@@ -82,7 +82,7 @@ find $PKG -print0 | xargs -0 file | grep -e "executable" -e "shared object" | gr
|
||||
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
|
||||
|
||||
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cp -a AUTHORS COPYING ChangeLog NEWS README.md \
|
||||
cp -a AUTHORS COPYING ChangeLog README.md \
|
||||
$PKG/usr/doc/$PRGNAM-$VERSION
|
||||
cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# AT-SPI Document Selection Branch Handoff
|
||||
|
||||
Branch: `atspi-document-selection`
|
||||
|
||||
## Implemented
|
||||
|
||||
- Added document-wide AT-SPI selection normalization in
|
||||
`src/cthulhu/ax_document_selection.py`.
|
||||
- Reworked text-selection handling in `src/cthulhu/script_utilities.py` to use
|
||||
the shared adapter where possible and fall back cleanly where not.
|
||||
- Updated primary callers in the default and web scripts so copy/cut,
|
||||
selection announcements, and selected-text queries use the shared selection
|
||||
path.
|
||||
- Added keyboard-driven clipboard announcement fallback in
|
||||
`src/cthulhu/scripts/default.py`, including Wayland-specific policy changes.
|
||||
- Fixed `build-local.sh` so rebuilding refreshes modified installed modules
|
||||
under `~/.local`.
|
||||
|
||||
## Verified
|
||||
|
||||
- `python3 -m pytest -q tests/test_document_selection_regressions.py`
|
||||
- `python3 -m pytest -q tests/test_default_script_clipboard_regressions.py`
|
||||
- `python3 -m pytest -q tests/test_web_input_regressions.py`
|
||||
- `HOME=/tmp/cthulhu-test-home python3 -m pytest -q tests`
|
||||
- `./build-local.sh`
|
||||
|
||||
Latest full-suite result before handoff: `95 passed, 1 warning`.
|
||||
|
||||
## Still Open
|
||||
|
||||
- Browser link-text selection is still not reliable in Chromium/Edge and in
|
||||
web-backed content like Steam.
|
||||
- The current branch includes extra diagnostics around clipboard and selection
|
||||
paths because they were useful during manual debugging.
|
||||
- The newest attempted web fix is in `src/cthulhu/scripts/web/script.py`, but
|
||||
the manual repro still fails:
|
||||
- selecting link text with `Shift+Left` / `Shift+Right`
|
||||
- hearing no selection announcement
|
||||
- then having copy behavior depend on fallback logic instead of real
|
||||
selection state
|
||||
|
||||
## Useful Files For Follow-Up
|
||||
|
||||
- `src/cthulhu/ax_document_selection.py`
|
||||
- `src/cthulhu/script_utilities.py`
|
||||
- `src/cthulhu/scripts/default.py`
|
||||
- `src/cthulhu/scripts/web/script.py`
|
||||
- `src/cthulhu/scripts/web/script_utilities.py`
|
||||
- `tests/test_document_selection_regressions.py`
|
||||
- `tests/test_default_script_clipboard_regressions.py`
|
||||
- `tests/test_web_input_regressions.py`
|
||||
+17
-15
@@ -14,7 +14,7 @@
|
||||
.\" along with this; if not write to the Free Software Foundation, Inc.
|
||||
.\" 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
|
||||
'\"
|
||||
.TH cthulhu 1 "20 September 2013" "GNOME"
|
||||
.TH cthulhu 1 "10 April 2026" "Stormux"
|
||||
.SH NAME
|
||||
cthulhu \- a scriptable screen reader
|
||||
.SH SYNOPSIS
|
||||
@@ -26,13 +26,17 @@ is a screen reader for people with visual impairments,
|
||||
it provides alternative access to the desktop by using speech synthesis and braille.
|
||||
.P
|
||||
.B cthulhu
|
||||
is maintained in this fork by Storm Dragon. It is forked from Orca and builds
|
||||
on upstream work by former Orca maintainers and contributors, who are part of
|
||||
the project's history but are not current maintainers of this fork.
|
||||
.P
|
||||
.B cthulhu
|
||||
works with applications and toolkits that support
|
||||
the Assistive Technology Service Provider Interface (AT-SPI), which
|
||||
is the primary assistive technology infrastructure for Linux and
|
||||
Solaris. Applications and toolkits supporting the AT-SPI include the
|
||||
GNOME Gtk+ toolkit, the Java platform's Swing toolkit, LibreOffice,
|
||||
Gecko, and WebKitGtk. AT-SPI support for the KDE Qt toolkit is being
|
||||
pursued.
|
||||
Gecko, WebKitGtk, and the KDE Qt toolkit.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-s, --setup
|
||||
@@ -121,7 +125,7 @@ in desktop keyboard layout and
|
||||
in laptop keyboard layout.
|
||||
|
||||
.B Cthulhu
|
||||
uses default GNOME keyboard shortcuts to navigate the desktop and interact with various applications. The flat review commands provide an alternative method of interaction in certain inaccessible applications. It should not be confused with flat review functionality provided by other screen readers.
|
||||
uses its configured keyboard shortcuts to navigate the desktop and interact with various applications. The flat review commands provide an alternative method of interaction in certain inaccessible applications. It should not be confused with flat review functionality provided by other screen readers.
|
||||
|
||||
.SH Desktop Mode
|
||||
|
||||
@@ -318,17 +322,15 @@ originated as a community effort led by the Sun Microsystems Inc.
|
||||
Accessibility Program Office and with contributions from many community members.
|
||||
.SH SEE ALSO
|
||||
For more information please visit
|
||||
.B cthulhu
|
||||
wiki at
|
||||
.UR http://live.gnome.org/Cthulhu
|
||||
<http://live.gnome.org/Cthulhu>
|
||||
.B Cthulhu
|
||||
at
|
||||
.UR https://git.stormux.org/storm/cthulhu
|
||||
<https://git.stormux.org/storm/cthulhu>
|
||||
.UE
|
||||
.P
|
||||
The
|
||||
.B cthulhu
|
||||
mailing list
|
||||
.UR http://mail.gnome.org/mailman/listinfo/cthulhu-list
|
||||
<http://mail.gnome.org/mailman/listinfo/cthulhu-list>
|
||||
To post a message to all
|
||||
.B cthulhu
|
||||
list, send a email to https://groups.io/g/stormux
|
||||
.B Stormux
|
||||
community list is available at
|
||||
.UR https://groups.io/g/stormux
|
||||
<https://groups.io/g/stormux>
|
||||
.UE
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
# Sounds Tab Design
|
||||
|
||||
Date: 2026-04-05
|
||||
|
||||
## Context
|
||||
|
||||
Cthulhu currently stores several non-speech sound settings in the general settings file, but the preferences dialog does not present them coherently:
|
||||
|
||||
- The General tab contains an inline Sound section for backend, theme, and role-sound presentation.
|
||||
- The progress-bar beep checkbox lives in the General tab's progress-bar section.
|
||||
- `soundVolume` exists in settings and the user's active profile, but there is no UI control for it.
|
||||
- `enableSound`, `playSoundForRole`, `playSoundForState`, `playSoundForPositionInSet`, and `playSoundForValue` exist as persisted settings but are not currently exposed in the dialog.
|
||||
- `progressBarBeepInterval` exists in runtime defaults but is not part of the normal persisted general-settings key list.
|
||||
|
||||
The result is that sound-related behavior is split across the dialog and some active settings cannot be inspected or changed from the UI.
|
||||
|
||||
## Goals
|
||||
|
||||
- Add a dedicated `Sounds` preferences tab.
|
||||
- Move currently exposed sound-related controls out of `General` and into `Sounds`.
|
||||
- Move the progress-bar beep option into `Sounds` while leaving the rest of the progress-bar section in `General`.
|
||||
- Expose currently hidden sound-related settings in the UI.
|
||||
- Add a UI control for `soundVolume`.
|
||||
- Expose and persist `progressBarBeepInterval`.
|
||||
- Preserve the existing settings model and save format.
|
||||
- Avoid clobbering unrelated settings when saving preferences.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No refactor of the broader preferences architecture.
|
||||
- No changes to sound playback implementation outside what is needed to load and save settings correctly.
|
||||
- No new settings schema beyond persisting the existing hidden `progressBarBeepInterval`.
|
||||
- No dynamic enable/disable logic for sound controls in this pass.
|
||||
|
||||
## Design Summary
|
||||
|
||||
Add a new notebook page labeled `Sounds` and make it the single home for non-speech sound configuration. Remove the inline Sound frame from `General`. Keep the existing progress-bar speech/braille controls and shared progress-bar behavior controls in `General`, but move beep-specific controls into `Sounds`.
|
||||
|
||||
The new tab will use existing settings keys wherever possible and will save through the existing `prefsDict` and settings-manager flow.
|
||||
|
||||
## Sounds Tab Layout
|
||||
|
||||
The `Sounds` tab will contain three sections.
|
||||
|
||||
### Output
|
||||
|
||||
- `enableSound` checkbox
|
||||
- `soundVolume` slider
|
||||
- `soundSink` combo box
|
||||
|
||||
`soundVolume` should be represented by a native `GtkScale` and persisted back to the existing floating-point `soundVolume` setting. The control should initialize from `prefsDict.get("soundVolume", settings.soundVolume)`.
|
||||
|
||||
For this implementation, the slider should match the stored setting directly rather than introducing a new percentage representation. That keeps the implementation small and avoids conversion-only complexity in a settings path that already exists.
|
||||
|
||||
### Presentation
|
||||
|
||||
- `soundTheme` combo box
|
||||
- `roleSoundPresentation` combo box
|
||||
- `playSoundForRole` checkbox
|
||||
- `playSoundForState` checkbox
|
||||
- `playSoundForPositionInSet` checkbox
|
||||
- `playSoundForValue` checkbox
|
||||
|
||||
These controls will expose already-existing settings and use the same `prefsDict` update pattern already used by the current dialog.
|
||||
|
||||
### Alerts
|
||||
|
||||
- `beepProgressBarUpdates` checkbox
|
||||
- `progressBarBeepInterval` spin button
|
||||
|
||||
This section controls only beep-based progress-bar alerts. The label should make it clear that the interval is beep-specific, not the general progress-bar announcement interval.
|
||||
|
||||
## General Tab Changes
|
||||
|
||||
Keep these controls in `General`:
|
||||
|
||||
- `speakProgressBarUpdates`
|
||||
- `brailleProgressBarUpdates`
|
||||
- `progressBarUpdateInterval`
|
||||
- `progressBarVerbosity`
|
||||
- `ignoreStatusBarProgressBars`
|
||||
|
||||
Remove these from `General`:
|
||||
|
||||
- the inline Sound frame
|
||||
- `beepProgressBarUpdates`
|
||||
|
||||
This preserves the current organization for general progress-bar announcement behavior while moving sound-only concerns into the new tab.
|
||||
|
||||
## Settings and Persistence
|
||||
|
||||
### Existing Keys Reused
|
||||
|
||||
The new UI will continue to use the existing settings keys:
|
||||
|
||||
- `enableSound`
|
||||
- `soundVolume`
|
||||
- `soundSink`
|
||||
- `soundTheme`
|
||||
- `roleSoundPresentation`
|
||||
- `playSoundForRole`
|
||||
- `playSoundForState`
|
||||
- `playSoundForPositionInSet`
|
||||
- `playSoundForValue`
|
||||
- `beepProgressBarUpdates`
|
||||
|
||||
### Persisted Hidden Key
|
||||
|
||||
Add `progressBarBeepInterval` to the persisted general-settings key list so it round-trips through:
|
||||
|
||||
- defaults in `settings.py`
|
||||
- settings-manager general settings
|
||||
- TOML backend save/load
|
||||
- `prefsDict` in the preferences dialog
|
||||
|
||||
This avoids the current mismatch where beep interval exists as a runtime default but is not part of the normal persisted general-settings path.
|
||||
|
||||
### Save Behavior
|
||||
|
||||
The implementation should continue to update individual keys in `prefsDict` and then rely on the existing general-settings save flow. No bulk replacement of the whole settings structure should be introduced.
|
||||
|
||||
This is specifically intended to avoid accidental overwrites of unrelated settings already present in `user-settings.toml`.
|
||||
|
||||
## Default Values
|
||||
|
||||
- Keep `progressBarUpdateInterval = 10` as the default for speech and braille progress-bar updates.
|
||||
- Keep `progressBarBeepInterval = 0` as the default for beep-based progress-bar updates.
|
||||
- Keep `soundVolume = 0.5` as the existing default unless the user explicitly changes it.
|
||||
|
||||
The new UI should reflect these values accurately on load.
|
||||
|
||||
## Accessibility
|
||||
|
||||
Use native GTK controls and follow the existing preferences-dialog patterns:
|
||||
|
||||
- every label must be associated with its control via `mnemonic_widget`
|
||||
- checkboxes should use the existing `checkButtonToggled` convention when possible
|
||||
- combo boxes should keep proper `label-for` / `labelled-by` relationships
|
||||
- no custom-drawn controls
|
||||
- no keyboard traps
|
||||
|
||||
The new tab should be fully reachable with standard tab navigation.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
Expected files to change:
|
||||
|
||||
- `src/cthulhu/cthulhu-setup.ui`
|
||||
- `src/cthulhu/cthulhu_gui_prefs.py`
|
||||
- `src/cthulhu/settings.py`
|
||||
|
||||
Implementation should:
|
||||
|
||||
- add the new notebook page and move or recreate the relevant widgets there
|
||||
- initialize and save the new sound controls using existing dialog patterns
|
||||
- add explicit handling for `soundVolume`
|
||||
- add explicit handling for `progressBarBeepInterval`
|
||||
- keep all unrelated preference behavior unchanged
|
||||
|
||||
## Verification
|
||||
|
||||
The implementation should be considered complete only after all of the following are checked:
|
||||
|
||||
1. The preferences dialog opens and the new `Sounds` tab is present.
|
||||
2. Existing sound settings load into the correct controls.
|
||||
3. Changing sound settings updates `prefsDict` without breaking unrelated settings.
|
||||
4. Saving preferences preserves unrelated keys in `user-settings.toml`.
|
||||
5. `progressBarBeepInterval` is written and reloaded correctly.
|
||||
6. The General tab still handles speech/braille progress-bar settings correctly.
|
||||
7. Touched Python files pass compile checks.
|
||||
8. Manual verification confirms keyboard navigation and label association remain intact.
|
||||
@@ -0,0 +1,117 @@
|
||||
# Guarded Mouse Review Wayland Backport
|
||||
|
||||
## Summary
|
||||
|
||||
Backport Orca's modern mouse review split into Cthulhu in a conservative way. Keep the current X11 `Wnck` plus `mouse:abs` implementation as the existing path. Add a second path that uses `Atspi.Device` pointer monitoring only when the local AT-SPI version is new enough and the compositor/device actually grants `POINTER_MONITOR`. If either condition fails, Cthulhu stays on the current behavior.
|
||||
|
||||
This is explicitly an X-safe design. The X11 path remains first-class and unchanged in behavior. Wayland support is opportunistic and must fail closed.
|
||||
|
||||
## Current State
|
||||
|
||||
- Cthulhu mouse review currently depends on `Wnck` window lookup and `mouse:abs` events in [mouse_review.py](/home/storm/devel/cthulhu/src/cthulhu/mouse_review.py).
|
||||
- Recent local changes already avoid importing `Wnck` on Wayland to suppress the terminal warning, but they do not add functional Wayland mouse review.
|
||||
- Cthulhu already has an `Atspi.Device` for keyboard handling in [input_event_manager.py](/home/storm/devel/cthulhu/src/cthulhu/input_event_manager.py), which is the required foundation for an Orca-style pointer-monitor path.
|
||||
|
||||
## Goals
|
||||
|
||||
- Preserve existing X11 mouse review behavior.
|
||||
- Add a guarded Wayland-capable path modeled on Orca's `Atspi.Device` pointer monitoring.
|
||||
- Avoid startup warnings from `Wnck` on Wayland.
|
||||
- Avoid enabling any new path unless support is positively confirmed at runtime.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No full Orca mouse review rewrite beyond the pointer-monitor split.
|
||||
- No removal or semantic change of the current X11 `Wnck` path.
|
||||
- No OCR refactor beyond existing `Wnck` gating already added.
|
||||
- No assumption that Wayland mouse review will work everywhere; unsupported compositors must remain a no-op.
|
||||
|
||||
## Design
|
||||
|
||||
### Capability Detection
|
||||
|
||||
Mouse review will select its backend at runtime:
|
||||
|
||||
1. If AT-SPI version is at least `2.60`, or the pre-release threshold Orca used (`2.59.90`), Cthulhu may try the new backend.
|
||||
2. The new backend must call `set_capabilities(... | POINTER_MONITOR)` on the existing `Atspi.Device`.
|
||||
3. The new backend is considered available only if `POINTER_MONITOR` is present in the returned capability set.
|
||||
4. If any of those checks fail, Cthulhu uses the existing X11 path.
|
||||
|
||||
This means X11 systems on older stacks continue to use the current implementation. Wayland systems with insufficient AT-SPI support do not partially enable mouse review.
|
||||
|
||||
### InputEventManager Extension
|
||||
|
||||
Extend [input_event_manager.py](/home/storm/devel/cthulhu/src/cthulhu/input_event_manager.py) with narrow pointer-monitor wrappers:
|
||||
|
||||
- `enable_pointer_monitoring() -> bool`
|
||||
- `start_pointer_watcher(callback) -> None`
|
||||
- `stop_pointer_watcher() -> None`
|
||||
|
||||
These wrappers should mirror Orca's error handling:
|
||||
|
||||
- return `False` on missing device or `GLib.GError`
|
||||
- never raise into callers
|
||||
- leave existing keyboard handling unchanged
|
||||
|
||||
No unrelated device-manager refactor is included in this pass.
|
||||
|
||||
### Mouse Review Backend Split
|
||||
|
||||
Update [mouse_review.py](/home/storm/devel/cthulhu/src/cthulhu/mouse_review.py) to maintain two internal paths:
|
||||
|
||||
- Legacy path:
|
||||
- existing `Wnck` window tracking
|
||||
- existing `mouse:abs` listener
|
||||
- existing absolute-coordinate flow
|
||||
- New path:
|
||||
- register a `pointer-moved` watcher on the `Atspi.Device`
|
||||
- use the accessible object and local coordinates delivered by AT-SPI
|
||||
- if the event source is an application, resolve the containing window from the app's accessible children
|
||||
- otherwise use the event object directly
|
||||
|
||||
The common object-presentation logic should stay shared as much as possible. Only the event source and coordinate acquisition differ.
|
||||
|
||||
### Safety Rules
|
||||
|
||||
- Do not change the old X11 path except for harmless factoring needed to share code.
|
||||
- Do not force the new path on X11 systems that are currently using the legacy path successfully.
|
||||
- If pointer monitoring disconnects, errors, or cannot be enabled, mouse review must behave as unavailable rather than falling into a broken mixed state.
|
||||
- Existing `Wnck` suppression on Wayland remains in place.
|
||||
|
||||
## Testing
|
||||
|
||||
### Automated
|
||||
|
||||
Add focused regressions for:
|
||||
|
||||
- version/capability gating chooses the new backend only when allowed
|
||||
- `enable_pointer_monitoring()` returns `False` on capability failure
|
||||
- pointer watcher start/stop are no-ops when there is no device
|
||||
- mouse review activation chooses the legacy backend when AT-SPI support is not available
|
||||
- mouse review activation chooses the pointer-monitor backend when support is available
|
||||
|
||||
Tests should mock AT-SPI rather than requiring a compositor.
|
||||
|
||||
### Manual
|
||||
|
||||
X11:
|
||||
|
||||
- mouse review still enables and behaves as before
|
||||
- no regressions in pointer routing or reviewed object presentation
|
||||
|
||||
Wayland:
|
||||
|
||||
- no `Wnck` warning on startup
|
||||
- mouse review only enables when AT-SPI pointer monitoring is actually available
|
||||
- if supported, pointer hover review works without breaking keyboard handling
|
||||
- if unsupported, failure is clean and explicit rather than noisy or partially broken
|
||||
|
||||
## Risks
|
||||
|
||||
- The local environment here is still on AT-SPI `2.58.4`, so the new backend cannot be exercised live in this workspace.
|
||||
- The guarded design limits that risk by preserving the existing path and enabling the new path only under the same runtime conditions Orca used.
|
||||
- The main regression risk is accidental interaction with Cthulhu's existing keyboard `Atspi.Device`; that is why the change is limited to small wrappers plus mouse-review-specific watcher usage.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Implement the guarded dual-path backport and stop there. Do not port broader Orca mouse review refactors in the same pass.
|
||||
@@ -0,0 +1,355 @@
|
||||
# Wayland Compositor Event Interface For Churn Reduction
|
||||
|
||||
## Summary
|
||||
|
||||
Revise Cthulhu's event interface so Wayland session state can reduce AT-SPI churn before it reaches the current object-event pipeline. Keep `AT-SPI` authoritative for object semantics, text, selection, and actions. Add a small compositor-state normalization layer that is authoritative for desktop context such as active workspace, active top-level window, and focus routing during transitions.
|
||||
|
||||
This is not a Newton-style redesign. It is a conservative performance-oriented split intended to reduce queue growth, redundant script activation, and processing of stale events on Wayland systems while preserving existing accessibility semantics.
|
||||
|
||||
## Current State
|
||||
|
||||
- Cthulhu's main event flow is still centered on `Atspi.EventListener` and a single `event_manager` queue in `src/cthulhu/event_manager.py`.
|
||||
- The current design already spends significant effort filtering spam, handling floods and deluges, recovering focus context, and pruning duplicate events.
|
||||
- `src/cthulhu/input_event_manager.py` already uses `Atspi.Device` for keyboard handling and pointer monitoring wrappers, so Cthulhu already has one narrow example of a side-channel interface on Wayland.
|
||||
- `src/cthulhu/focus_manager.py` and `src/cthulhu/cthulhu_state.py` still derive active-window and focus truth primarily from AT-SPI objects and events.
|
||||
- `src/cthulhu/wnck_support.py` correctly gates `Wnck` to X11-only use, which is a useful precedent for runtime capability-based backend selection.
|
||||
- Recent work in this repository has improved individual Wayland features, but there is not yet a compositor-agnostic interface for desktop state that can suppress irrelevant object churn before it enters the hot path.
|
||||
|
||||
## Goals
|
||||
|
||||
- Reduce AT-SPI event churn on Wayland systems before it reaches the main queue.
|
||||
- Keep the design generic and compositor-agnostic at the Cthulhu interface level.
|
||||
- Preserve current `AT-SPI` object semantics and script behavior as much as possible.
|
||||
- Improve prioritization of focus and active-window related work during workspace and window transitions.
|
||||
- Provide a single internal contract that can support Mutter, KWin, and wlroots-based compositors without teaching the rest of Cthulhu about compositor brands.
|
||||
- Fail safe to current behavior when compositor state is missing, incomplete, or inconsistent.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No Newton-style compositor-authoritative accessibility tree transport.
|
||||
- No replacement of AT-SPI for object semantics, text, selection, caret movement, or actions.
|
||||
- No dependency on `niri` IPC, GNOME Shell extensions, or KWin scripts in the core architecture for phase one.
|
||||
- No requirement that every supported compositor expose the same amount of state.
|
||||
- No broad rewrite of script listeners or script modules in this pass.
|
||||
|
||||
## Approaches Considered
|
||||
|
||||
### 1. Direct Wayland Integration Inside `event_manager`
|
||||
|
||||
Teach `event_manager` to consume shared Wayland state directly and add compositor-specific checks inside its current logic.
|
||||
|
||||
Pros:
|
||||
|
||||
- smallest code footprint up front
|
||||
- no new internal abstraction layer
|
||||
|
||||
Cons:
|
||||
|
||||
- quickly leaks compositor-specific capability checks into the hottest code path
|
||||
- makes Mutter, KWin, and wlroots differences part of `event_manager` logic
|
||||
- harder to test in isolation
|
||||
|
||||
### 2. Thin Compositor-State Adapter Layer
|
||||
|
||||
Introduce a small internal normalization layer that consumes shared compositor-facing signals and emits a compact generic event vocabulary to `event_manager`.
|
||||
|
||||
Pros:
|
||||
|
||||
- keeps compositor-specific capability detection out of the hot path
|
||||
- gives `event_manager` one stable interface to consume
|
||||
- matches the long-term direction of consuming normalized state below the main screen reader logic
|
||||
- easy to test with mocked backends
|
||||
|
||||
Cons:
|
||||
|
||||
- adds one more internal subsystem
|
||||
- requires careful definition of authority boundaries to avoid duplication with AT-SPI
|
||||
|
||||
### 3. Full Compositor-Authoritative Routing
|
||||
|
||||
Make compositor state the primary truth for most event routing and use AT-SPI only for fine-grained object semantics.
|
||||
|
||||
Pros:
|
||||
|
||||
- highest potential performance ceiling
|
||||
- most direct path toward a future compositor-led architecture
|
||||
|
||||
Cons:
|
||||
|
||||
- much higher correctness risk
|
||||
- too large a shift for a churn-focused first pass
|
||||
- would require significantly more backend-specific coverage and recovery logic
|
||||
|
||||
## Recommendation
|
||||
|
||||
Implement approach 2.
|
||||
|
||||
For phase one, Cthulhu should add a thin compositor-state adapter layer. It should be authoritative for desktop context and transition hints, but not for accessible object semantics. This gives Cthulhu a generic way to suppress or reprioritize AT-SPI noise without requiring a full architecture rewrite.
|
||||
|
||||
## Design
|
||||
|
||||
### Authority Split
|
||||
|
||||
The revised interface should split responsibility cleanly:
|
||||
|
||||
- compositor-state adapter is authoritative for:
|
||||
- active desktop context
|
||||
- active workspace set
|
||||
- active top-level window identity when available
|
||||
- desktop transition start and end
|
||||
- focus-routing hints during compositor-driven changes
|
||||
- AT-SPI remains authoritative for:
|
||||
- focused accessible object
|
||||
- accessible roles, names, and states
|
||||
- text, caret, and selection semantics
|
||||
- actionable objects and accessibility events consumed by scripts
|
||||
|
||||
Inference from upstream: current Orca remains AT-SPI-authoritative in its main pipeline, while newer GNOME accessibility work moves normalization below Orca rather than throughout it. This design follows that same direction without depending on Newton itself.
|
||||
|
||||
### New Internal Boundary
|
||||
|
||||
Add a new internal interface named `CompositorStateAdapter`.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- detect and activate the best available compositor-state backend at runtime
|
||||
- normalize raw backend signals into a small generic event vocabulary
|
||||
- maintain a current desktop-context snapshot
|
||||
- emit state deltas and control hints to `event_manager`
|
||||
- degrade to no-op behavior when capabilities are absent or unclear
|
||||
|
||||
This adapter should not expose compositor-specific event names or objects outside its own implementation.
|
||||
|
||||
### Normalized Event Vocabulary
|
||||
|
||||
The adapter should emit two families of signals.
|
||||
|
||||
State deltas:
|
||||
|
||||
- `workspace_state_changed`
|
||||
- `desktop_focus_context_changed`
|
||||
- `desktop_transition_started`
|
||||
- `desktop_transition_finished`
|
||||
|
||||
Control hints:
|
||||
|
||||
- `pause_atspi_churn`
|
||||
- `resume_atspi_churn`
|
||||
- `prioritize_focus`
|
||||
- `deprioritize_context`
|
||||
- `flush_stale_atspi_events`
|
||||
|
||||
This vocabulary is intentionally small. It exists to shape queueing and prioritization, not to mirror every compositor event.
|
||||
|
||||
### Desktop Context Snapshot
|
||||
|
||||
The adapter should maintain a compact snapshot object with fields along these lines:
|
||||
|
||||
- `session_type`
|
||||
- `backend_name`
|
||||
- `active_workspace_ids`
|
||||
- `active_window_token`
|
||||
- `focus_route_token`
|
||||
- `transition_active`
|
||||
- `timestamp`
|
||||
|
||||
`active_window_token` and `focus_route_token` are intentionally generic. They should be comparable identifiers, not compositor-native objects leaking into the rest of Cthulhu.
|
||||
|
||||
### Backend Selection
|
||||
|
||||
Phase one should use capability-driven backend selection with generic shared interfaces first.
|
||||
|
||||
Preferred order:
|
||||
|
||||
1. `WaylandSharedProtocolsBackend`
|
||||
2. `AtspiContextBackend`
|
||||
3. `NullBackend`
|
||||
|
||||
#### `WaylandSharedProtocolsBackend`
|
||||
|
||||
This backend should consume shared Wayland-facing protocols where available and normalize them for Cthulhu. The first protocol target should be `ext_workspace_v1`.
|
||||
|
||||
Reasoning:
|
||||
|
||||
- `ext_workspace_v1` provides workspace groups, workspaces, active state, and atomic `done` notifications, which is exactly the sort of low-volume desktop-state signal Cthulhu needs to reason about transitions.
|
||||
- As of April 9, 2026, Wayland Explorer lists `ext_workspace_v1` support for Mutter `49.2`, KWin `6.6`, and niri `25.11`, making it a good cross-family starting point.
|
||||
|
||||
This backend should only expose normalized state to the rest of Cthulhu. It should not expose protocol objects or protocol-specific state transitions outside the backend.
|
||||
|
||||
#### `AtspiContextBackend`
|
||||
|
||||
This backend should use current AT-SPI-based context recovery when shared Wayland state is missing or insufficient. It does not improve churn by itself, but it preserves current behavior and keeps the adapter contract usable everywhere.
|
||||
|
||||
#### `NullBackend`
|
||||
|
||||
This backend should emit no compositor hints and leave the rest of Cthulhu in its current behavior. It is the fail-safe path.
|
||||
|
||||
### Explicit Exclusions For Phase One
|
||||
|
||||
The following are not part of the core architecture in phase one:
|
||||
|
||||
- `niri` IPC as a first-class public interface
|
||||
- compositor-specific `D-Bus` integrations
|
||||
- GNOME Shell extension event streams
|
||||
- KWin scripting APIs
|
||||
|
||||
These may become optional backend implementations in the future if a shared protocol proves insufficient, but they must remain behind the same generic adapter contract.
|
||||
|
||||
### Event Flow
|
||||
|
||||
The adapter should sit ahead of the current `event_manager`, not replace it.
|
||||
|
||||
Proposed flow:
|
||||
|
||||
1. backend receives shared compositor-facing state changes
|
||||
2. adapter updates its desktop-context snapshot
|
||||
3. adapter emits normalized state deltas and control hints
|
||||
4. `event_manager` updates queueing, prioritization, and obsolescence decisions
|
||||
5. AT-SPI object events continue to provide object-level truth within the selected desktop context
|
||||
|
||||
This allows Cthulhu to reduce irrelevant work before scripts interpret it, while keeping existing AT-SPI semantics intact.
|
||||
|
||||
### `event_manager` Integration
|
||||
|
||||
`event_manager` should gain a separate notion of desktop-context state in addition to its existing AT-SPI queue.
|
||||
|
||||
New responsibilities:
|
||||
|
||||
- track whether churn suppression is active
|
||||
- track the currently prioritized desktop context
|
||||
- reject queued AT-SPI work that became stale because the compositor already moved to a new context
|
||||
- prefer script activation and focus recovery work that matches the current desktop context
|
||||
|
||||
The existing queue does not need to be replaced, but it does need one new concept: context obsolescence.
|
||||
|
||||
### Context Obsolescence
|
||||
|
||||
Add a new pruning rule: an event can be obsolete not only because a newer event of the same type exists, but because the desktop context that made the event relevant no longer exists.
|
||||
|
||||
Examples:
|
||||
|
||||
- a large `children-changed` burst from a window on a workspace that is no longer active
|
||||
- queued `showing` or `name-change` events from a window that just lost compositor priority
|
||||
- stale background application updates that were queued before a workspace switch finished
|
||||
|
||||
This is the primary performance win of the new interface. It lets Cthulhu discard irrelevant work based on context freshness, not only on event-type heuristics.
|
||||
|
||||
### Churn Suppression Mode
|
||||
|
||||
When the adapter emits `pause_atspi_churn`, `event_manager` should enter a guarded suppression mode.
|
||||
|
||||
This is not a full stop. It is a mode where:
|
||||
|
||||
- high-value focus and activation events are always preserved
|
||||
- low-value background churn is collapsed, deprioritized, or dropped
|
||||
- stale work from the prior desktop context is pruned aggressively
|
||||
|
||||
Events that should still be preserved during suppression:
|
||||
|
||||
- `window:*`
|
||||
- `object:state-changed:focused` with `detail1=true`
|
||||
- `object:state-changed:active` on frames and windows
|
||||
- `object:text-selection-changed`
|
||||
- `object:selection-changed` for the prioritized context
|
||||
- user-trigger-correlated events associated with the last input event
|
||||
|
||||
Events that should usually be suppressed, collapsed, or deprioritized:
|
||||
|
||||
- `object:children-changed:*`
|
||||
- `object:state-changed:showing`
|
||||
- `object:state-changed:sensitive`
|
||||
- background `object:property-change:accessible-name`
|
||||
- bulk `object:text-changed:*`
|
||||
- repeated `object:text-caret-moved` from non-priority contexts
|
||||
|
||||
### Transition Handling
|
||||
|
||||
When the adapter indicates a desktop transition:
|
||||
|
||||
- `desktop_transition_started`
|
||||
- adapter marks `transition_active=True`
|
||||
- adapter emits `pause_atspi_churn`
|
||||
- `desktop_focus_context_changed`
|
||||
- `event_manager` updates the preferred app/window context before AT-SPI focus settles
|
||||
- focus-related events for the new context get priority
|
||||
- `desktop_transition_finished`
|
||||
- adapter emits `resume_atspi_churn`
|
||||
- adapter emits `flush_stale_atspi_events`
|
||||
- `event_manager` drops queued events that belong to the old context and resumes normal flow
|
||||
|
||||
This allows Cthulhu to be more decisive during workspace switches, app switches, and transient window transitions without needing compositor-authoritative object trees.
|
||||
|
||||
### Script Activation
|
||||
|
||||
`event_manager` should use the adapter's prioritized desktop context as an additional input when deciding whether to activate a script.
|
||||
|
||||
It should not activate a script purely because the compositor hinted at it, but it should:
|
||||
|
||||
- prioritize AT-SPI events from the compositor-indicated context
|
||||
- deprioritize or skip activation from obviously stale background contexts
|
||||
- improve focus recovery when AT-SPI active-window truth is noisy or delayed
|
||||
|
||||
This should reduce cases where script activation thrashes between background and foreground apps during Wayland transitions.
|
||||
|
||||
### Debugging And Observability
|
||||
|
||||
Add explicit logs around the new boundary:
|
||||
|
||||
- backend chosen and why
|
||||
- normalized adapter signal emitted
|
||||
- transition suppression entered and left
|
||||
- events dropped due to context obsolescence
|
||||
- events preserved during suppression and why
|
||||
|
||||
These logs should make it possible to explain every major pruning decision in the same way current flood and ignore logic can be debugged.
|
||||
|
||||
## Testing
|
||||
|
||||
### Automated
|
||||
|
||||
Add targeted tests for:
|
||||
|
||||
- backend capability detection and fallback order
|
||||
- normalization of backend signals into adapter events
|
||||
- transition start and finish behavior
|
||||
- churn suppression activation and release
|
||||
- context-obsolescence pruning of queued AT-SPI events
|
||||
- preservation of focus and selection events during suppression
|
||||
- script activation preferring compositor-indicated context when AT-SPI is noisy
|
||||
- fail-safe fallback to current behavior when the adapter is uncertain
|
||||
|
||||
These tests should be written with mocks and fake backend signals. No real compositor should be required for unit coverage.
|
||||
|
||||
### Manual
|
||||
|
||||
Manual validation should focus on:
|
||||
|
||||
- workspace switches on Mutter, KWin, and niri
|
||||
- fast application switching
|
||||
- opening and dismissing transient dialogs and menus
|
||||
- noisy web or Steam-like scenarios where background AT-SPI churn is high
|
||||
- confirmation that speech follows real focused objects once AT-SPI settles
|
||||
- confirmation that no important notifications or menu interactions are lost during suppression
|
||||
|
||||
## Risks
|
||||
|
||||
- Shared Wayland protocols may provide enough workspace truth but not enough top-level detail on every compositor.
|
||||
- Compositor state may lead AT-SPI focus briefly, which could cause over-eager prioritization if the suppression policy is too aggressive.
|
||||
- Some legitimate background AT-SPI events may look like churn if the rules are too broad.
|
||||
- Adding a new boundary introduces state-synchronization bugs if adapter and event queue state diverge.
|
||||
|
||||
## Risk Management
|
||||
|
||||
- keep suppression guarded rather than absolute
|
||||
- keep AT-SPI authoritative for object semantics
|
||||
- make context obsolescence explicit and debuggable
|
||||
- fail back to current behavior whenever backend certainty is too low
|
||||
- avoid compositor-specific backends in phase one unless a shared protocol is clearly insufficient
|
||||
|
||||
## Recommendation
|
||||
|
||||
Implement a small generic `CompositorStateAdapter` and teach `event_manager` to consume its normalized desktop-state signals and churn-control hints.
|
||||
|
||||
Do not make `niri` IPC part of the core contract.
|
||||
Do not attempt a compositor-authoritative accessibility architecture in this pass.
|
||||
Do not broaden the first implementation beyond shared protocol detection, AT-SPI fallback, context-based pruning, and guarded churn suppression.
|
||||
@@ -0,0 +1,195 @@
|
||||
# Tolk NVDA Presence Compatibility Design
|
||||
|
||||
## Goal
|
||||
|
||||
Allow applications running under Wine or Proton to use the official upstream `Tolk.dll` unchanged while routing Tolk speech through the existing Linux NVDA-to-Cthulhu path.
|
||||
|
||||
The compatibility layer must satisfy only the checks that Tolk performs when selecting its NVDA driver. It must not require replacing `Tolk.dll`, patching Tolk, or using a Tolk-specific DLL override.
|
||||
|
||||
## Confirmed Constraints
|
||||
|
||||
- The shipped `Tolk.dll` must remain the official upstream binary.
|
||||
- The existing `wine2speechd` package already provides replacement `nvdaControllerClient32.dll` and `nvdaControllerClient64.dll` implementations for Linux.
|
||||
- The current blocker is Tolk detection, not the downstream speech transport.
|
||||
- Scope is limited to making Tolk believe NVDA is present; broader NVDA emulation is out of scope.
|
||||
|
||||
## Current Tolk Behavior
|
||||
|
||||
From `tolk/src/ScreenReaderDriverNVDA.cpp`, Tolk considers NVDA active only when both of the following succeed:
|
||||
|
||||
1. `nvdaController_testIfRunning() == 0`
|
||||
2. `FindWindow(L"wxWindowClassNR", L"NVDA")` returns a window handle
|
||||
|
||||
If either check fails, Tolk will not select the NVDA driver and speech output through Tolk will fail.
|
||||
|
||||
## Recommended Approach
|
||||
|
||||
Extend the existing Wine NVDA compatibility stack with a minimal NVDA presence helper. The solution has two parts:
|
||||
|
||||
1. The existing custom NVDA controller DLLs continue handling `nvdaController_*` API calls and forwarding them into the Linux bridge.
|
||||
2. A lightweight Windows helper process running inside Wine creates the exact window Tolk expects for NVDA detection.
|
||||
|
||||
This keeps the official `Tolk.dll` untouched and confines the compatibility contract to Tolk's actual checks.
|
||||
|
||||
## Architecture
|
||||
|
||||
### 1. NVDA controller DLLs
|
||||
|
||||
The custom `nvdaControllerClient32.dll` and `nvdaControllerClient64.dll` remain the Wine-visible implementation that applications and Tolk load.
|
||||
|
||||
Required behavior:
|
||||
|
||||
- `nvdaController_speakText` forwards speech to the existing Linux bridge.
|
||||
- `nvdaController_brailleMessage` continues current behavior.
|
||||
- `nvdaController_cancelSpeech` continues current behavior.
|
||||
- `nvdaController_testIfRunning` returns success only when the Linux bridge is reachable and the compatibility environment is operational.
|
||||
|
||||
`nvdaController_testIfRunning` must not return success solely because the DLL loaded. It is the main guard against false positive Tolk detection.
|
||||
|
||||
### 2. NVDA presence helper
|
||||
|
||||
A small Windows executable is added to the Wine-side compatibility package. Its only job is to create and maintain a top-level window with:
|
||||
|
||||
- class name: `wxWindowClassNR`
|
||||
- window title: `NVDA`
|
||||
|
||||
Required behavior:
|
||||
|
||||
- starts quickly and remains idle
|
||||
- single-instance per Wine prefix or session
|
||||
- exits cleanly without user interaction
|
||||
- does not present visible UI unless Wine forces a window surface
|
||||
- can be launched independently or on demand by the controller DLL
|
||||
|
||||
### 3. Startup coordination
|
||||
|
||||
The presence helper must be running before Tolk calls `FindWindow`, or Tolk detection will fail.
|
||||
|
||||
Acceptable coordination strategies:
|
||||
|
||||
- preferred: launch the helper as part of the existing Wine accessibility startup path
|
||||
- acceptable: lazily launch the helper the first time the custom NVDA DLL is loaded, then wait briefly for the window to appear
|
||||
|
||||
The preferred strategy is external startup rather than in-DLL process creation because it separates concerns and avoids loader-time side effects.
|
||||
|
||||
## Detection Contract
|
||||
|
||||
Tolk compatibility is considered successful only when all of the following are true:
|
||||
|
||||
- official `Tolk.dll` loads normally
|
||||
- Tolk loads the custom NVDA controller DLL
|
||||
- `nvdaController_testIfRunning()` returns `0`
|
||||
- `FindWindow(L"wxWindowClassNR", L"NVDA")` succeeds
|
||||
- `Tolk_DetectScreenReader()` returns `NVDA`
|
||||
- `Tolk_Output()` delivers speech through the existing Linux bridge
|
||||
|
||||
If the Linux bridge is unavailable, the compatibility layer must fail closed:
|
||||
|
||||
- `nvdaController_testIfRunning()` returns failure
|
||||
- Tolk does not report NVDA as active
|
||||
|
||||
The dummy NVDA window alone must never make Tolk think speech is available.
|
||||
|
||||
## Packaging
|
||||
|
||||
The compatibility feature belongs with the Wine NVDA compatibility stack, not in Tolk itself.
|
||||
|
||||
Expected package contents:
|
||||
|
||||
- `nvdaControllerClient32.dll`
|
||||
- `nvdaControllerClient64.dll`
|
||||
- `nvda-presence-helper.exe` or similarly named helper
|
||||
- startup integration so the helper is available in Wine and Proton environments where Tolk-based games run
|
||||
|
||||
No `Tolk.dll` replacement or override is added.
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Bridge unavailable
|
||||
|
||||
- `nvdaController_testIfRunning` returns failure
|
||||
- speech-related entry points return the existing failure behavior
|
||||
- Tolk should not detect NVDA
|
||||
|
||||
### Helper missing or failed to start
|
||||
|
||||
- `FindWindow` fails
|
||||
- Tolk should not detect NVDA
|
||||
- logging should identify missing helper startup distinctly from bridge connectivity failures
|
||||
|
||||
### Duplicate helper instances
|
||||
|
||||
- duplicates must resolve harmlessly, preferably by allowing one owner and exiting the rest
|
||||
|
||||
## Logging
|
||||
|
||||
Add targeted logging in the compatibility layer only. Logging should make these states distinguishable:
|
||||
|
||||
- controller DLL loaded
|
||||
- bridge connectivity check succeeded or failed
|
||||
- presence helper started
|
||||
- presence window created
|
||||
- Tolk compatibility ready
|
||||
|
||||
No Tolk-side logging changes are needed because Tolk is not being modified.
|
||||
|
||||
## Testing
|
||||
|
||||
### Functional test
|
||||
|
||||
Create or reuse a small Wine test application that:
|
||||
|
||||
1. calls `Tolk_Load()`
|
||||
2. calls `Tolk_DetectScreenReader()`
|
||||
3. calls `Tolk_Output(L\"test\", false)`
|
||||
|
||||
Expected result with bridge and helper active:
|
||||
|
||||
- `Tolk_DetectScreenReader()` returns `NVDA`
|
||||
- speech reaches Cthulhu through the existing NVDA path
|
||||
|
||||
### Negative tests
|
||||
|
||||
1. Bridge down, helper up:
|
||||
`Tolk_DetectScreenReader()` must not return `NVDA`
|
||||
2. Bridge up, helper down:
|
||||
`Tolk_DetectScreenReader()` must not return `NVDA`
|
||||
3. Both down:
|
||||
`Tolk_DetectScreenReader()` must not return `NVDA`
|
||||
|
||||
### Regression check
|
||||
|
||||
Verify that existing non-Tolk NVDA speech consumers continue using the current `wine2speechd` path without requiring Tolk-specific configuration.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- adding a plugin mechanism to Tolk
|
||||
- maintaining a Tolk fork
|
||||
- broader NVDA desktop emulation beyond what Tolk checks
|
||||
- compatibility with applications that perform additional NVDA-specific probing outside the current `wine2speechd` contract
|
||||
- anti-cheat or anti-tamper guarantees beyond avoiding Tolk replacement
|
||||
|
||||
## Risks
|
||||
|
||||
### Wine window behavior
|
||||
|
||||
The helper must create a window that `FindWindow` can discover reliably under Wine and Proton. If Wine normalizes or alters class registration behavior, the helper may need adjustment.
|
||||
|
||||
### Timing
|
||||
|
||||
If a game calls Tolk very early, helper startup races could cause intermittent detection failure. This is why pre-starting the helper is preferred.
|
||||
|
||||
### Split responsibility
|
||||
|
||||
The controller DLL and helper must agree on readiness. If they drift apart, Tolk may see the window but still fail to speak. The fail-closed `testIfRunning` check is the protection against this.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Implement the feature in the existing Wine NVDA compatibility stack, not in Tolk and not in Cthulhu core.
|
||||
|
||||
The smallest correct implementation is:
|
||||
|
||||
1. fix or confirm `nvdaController_testIfRunning()` behavior in the custom DLL
|
||||
2. add a minimal Wine helper that exposes the NVDA window Tolk checks for
|
||||
3. wire startup so the helper is available before Tolk detection occurs
|
||||
4. verify with a small Tolk test program under Wine
|
||||
+2
-11
@@ -1,5 +1,5 @@
|
||||
project('cthulhu',
|
||||
version: '2026.01.19-testing',
|
||||
version: '2026.05.14-master',
|
||||
meson_version: '>= 1.0.0',
|
||||
)
|
||||
|
||||
@@ -57,6 +57,7 @@ optional_modules = {
|
||||
'speechd': 'speech output',
|
||||
'dasbus': 'D-Bus remote controller',
|
||||
'psutil': 'system information commands',
|
||||
'pywayland': 'Wayland shared workspace backend',
|
||||
'gi.repository.Wnck': 'mouse review',
|
||||
'pdf2image': 'PDF processing for OCR',
|
||||
'scipy': 'Scientific computing for OCR analysis',
|
||||
@@ -93,16 +94,6 @@ else
|
||||
summary += {'sound support': 'no (missing gstreamer)'}
|
||||
endif
|
||||
|
||||
# Integration with session startup
|
||||
i18n.merge_file(
|
||||
input: 'cthulhu-autostart.desktop.in',
|
||||
output: '@BASENAME@',
|
||||
type: 'desktop',
|
||||
po_dir: meson.project_source_root() / 'po',
|
||||
install: true,
|
||||
install_dir: get_option('sysconfdir') / 'xdg' / 'autostart',
|
||||
)
|
||||
|
||||
# Update icon cache manually (desktop-neutral) - optional, ignore failures
|
||||
gtk_update_icon_cache = find_program('gtk4-update-icon-cache', required: false)
|
||||
if gtk_update_icon_cache.found()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
cthulhu-autostart.desktop.in
|
||||
src/cthulhu/braille_rolenames.py
|
||||
src/cthulhu/brltablenames.py
|
||||
src/cthulhu/chnames.py
|
||||
|
||||
@@ -13,11 +13,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-DamnedLies-Scope: partial\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr ""
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lector de pantalla Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
#, fuzzy
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "lector de pantalla; fabla; braille;"
|
||||
|
||||
@@ -24,11 +24,9 @@ msgstr ""
|
||||
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||
"X-Poedit-Language: Arabic\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "قارئ الشاشة Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "شاشة;قارئ;إمكانية الوصول;كلام;برايل;"
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@ msgstr ""
|
||||
"X-Poedit-Language: Asturian\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Llector de pantalla d'Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@ msgstr ""
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Чытач з экрана Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
#, fuzzy
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "чытач з экрана;экран;голас;маўленне;Брайль;"
|
||||
|
||||
@@ -23,11 +23,9 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu — екранен четец"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "екран;четец;достъпност;говор;брайл;"
|
||||
|
||||
|
||||
@@ -21,12 +21,10 @@ msgstr ""
|
||||
"X-Generator: KBabel 1.9.1\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "অর্কা স্ক্রীন রিডার / বিবর্ধন"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,12 +18,10 @@ msgstr ""
|
||||
"X-Generator: KBabel 1.9.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu'র বৈশিষ্ট্য"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -15,11 +15,9 @@ msgstr ""
|
||||
"X-Launchpad-Export-Date: 2015-02-05 06:46+0000\n"
|
||||
"X-Generator: Poedit 1.7.4\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu čitač ekrana"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "čitač ekrana;govor;brailleovo pismo;"
|
||||
|
||||
|
||||
@@ -27,11 +27,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lector de pantalla Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "pantalla;lector;accessibilitat;veu;braille;"
|
||||
|
||||
|
||||
@@ -27,11 +27,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Poedit 1.8.11\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lector de pantalla Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "lector de pantalla;pronunciació;braille;"
|
||||
|
||||
|
||||
@@ -19,12 +19,10 @@ msgstr ""
|
||||
"X-Launchpad-Export-Date: 2020-05-04 21:32+0000\n"
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "خوێنەری پەردەی ئۆرکا"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -24,11 +24,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Čtečka obrazovky Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "obrazovka;čtečka;přístupnost;řeč;braille;"
|
||||
|
||||
|
||||
@@ -17,12 +17,10 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=4; plural= (n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != "
|
||||
"11) ? 2 : 3;\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Hoffterau Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -32,11 +32,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.0.1\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Skærmlæseren Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "skærm;læser;tilgængelighed;tale;braille;"
|
||||
|
||||
|
||||
@@ -37,11 +37,9 @@ msgstr ""
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu-Bildschirmleser"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "bildschirm;leser;barrierefreiheit;sprache;braille;"
|
||||
|
||||
|
||||
@@ -20,12 +20,10 @@ msgstr ""
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n!=1)\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "ཨོར་ཀ་གསལ་གཞི་ལྷག་བྱེད་/ཆེ་ཤེལ་"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -28,11 +28,9 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Αναγνώστης οθόνης Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "οθόνη;αναγνώστης;προσβασιμότητα;ομιλία;μπράιγ;"
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr ""
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -21,11 +21,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Gtranslator 45.3\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu Screen Reader"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "screen reader;speech;braille;"
|
||||
|
||||
|
||||
@@ -21,11 +21,9 @@ msgstr ""
|
||||
"X-Generator: Poedit 3.2.2\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Ekranlegilo Orko"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
#, fuzzy
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "ekranlegilo;parolo;brajlo;"
|
||||
|
||||
@@ -28,11 +28,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"X-Generator: Gtranslator 45.alpha0\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lector de pantalla Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "lector;pantalla;accesibilidad;voz;braille;"
|
||||
|
||||
|
||||
@@ -20,12 +20,10 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu ekraanilugeja ja luup"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu pantaila-irakurlea"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "pantaila;irakurlea;irisgarritasuna;mintzamena;braillea;"
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 3.4\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "صفحهخوان اورکا"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -27,11 +27,9 @@ msgstr ""
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
"X-Poedit-Bookmarks: 814,-1,-1,-1,-1,-1,-1,-1,-1,-1\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu-näytönlukija"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "näyttö;lukija;saavutettavuus;puhe;pistekirjoitus;"
|
||||
|
||||
|
||||
@@ -31,11 +31,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lecteur d’écran Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "lecteur;écran;accessibilité;parole;braille;"
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.0.3\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr ""
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,12 +18,10 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=5; plural=n==1 ? 0 : (n%10==1 || n%10==2) ? 1 : "
|
||||
"(n%10>=3 && n%10<= 6) ? 2 : ((n%10>=7 && n%10<=9) || n==10) ? 3 : 4;\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Léitheoir Scáileáin agus Formhéadaitheoir Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -34,11 +34,9 @@ msgstr ""
|
||||
"X-DL-Domain: po\n"
|
||||
"X-DL-State: Translating\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lector da pantalla Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "pantalla;lector;accesibilidade;fala;braille;"
|
||||
|
||||
|
||||
@@ -33,12 +33,10 @@ msgstr ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu સ્ક્રીન વાંચક અને વિસ્તૃતકારક"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -14,11 +14,9 @@ msgstr ""
|
||||
"2 : 3);\n"
|
||||
"X-Generator: Poedit 3.4.1\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "מקריא המסך Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "מסך;קורא;נגישות;דיבור;ברייל;"
|
||||
|
||||
|
||||
@@ -22,11 +22,9 @@ msgstr ""
|
||||
"\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu स्क्रीन वाचक"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
#, fuzzy
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "स्क्रीन रीडर;भाषण;ब्रेल;"
|
||||
|
||||
@@ -20,11 +20,9 @@ msgstr ""
|
||||
"X-Launchpad-Export-Date: 2016-09-15 12:40+0000\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu čitač zaslona"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "čitač zaslona;govor;brajica;"
|
||||
|
||||
|
||||
@@ -22,11 +22,9 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.3\n"
|
||||
|
||||
# Megjegyzés: Mivel mindenhol régóta Gáborral egyeztetve az Cthulhu nevet magyarosan Orkaként írjuk a fordításban, így a fordítást megváltoztattam Orka képernyőolvasóra az Cthulhu képernyőolvasó helyett.
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Orka képernyőolvasó"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "képernyő;olvasó;akadálymentesítés;beszéd;braille;"
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Pembaca Layar Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "layar;pembaca;aksesibilitas;ucapan;braille;"
|
||||
|
||||
|
||||
@@ -17,11 +17,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Lokalize 1.5\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu skjálestur"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -39,11 +39,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"X-Generator: Gtranslator 42.0\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lettore schermo Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "lettore;schermo;accessibilità;voce;braille;"
|
||||
|
||||
|
||||
@@ -25,11 +25,9 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu スクリーンリーダー"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "スクリーン;リーダー;アクセシビリティ;音声;点字;"
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu - ეკრანის მკითხველი"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "ეკრანი;მკითხველი;ხელმისაწვდომობა;მეტყველება;ბრაილი;"
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Poedit 3.0\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr ""
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu экраннан оқитын қолданбасы"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,12 +18,10 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "ಆದ್ಯತೆಗಳು"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -15,11 +15,9 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu 화면 낭독기"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "화면;리더;접근성;음성;점자;"
|
||||
|
||||
|
||||
@@ -25,11 +25,9 @@ msgstr ""
|
||||
"(n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu ekrano skaityklė"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "ekrano skaityklė;kalba;brailio raštas;"
|
||||
|
||||
|
||||
@@ -23,11 +23,9 @@ msgstr ""
|
||||
"2);\n"
|
||||
"X-Generator: Lokalize 21.12.3\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu ekrāna lasītājs"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "ekrāna lasītājs;runa;Brails;"
|
||||
|
||||
|
||||
@@ -19,12 +19,10 @@ msgstr ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu स्क्रीन पाठक / आवर्द्धक"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural= n==1 || n%10==1 ? 0 : 1\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu читач на екранот"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -22,12 +22,10 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.0.1\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "സ്ക്രീന് വായന അവസാനിപ്പിക്കാം."
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,12 +18,10 @@ msgstr ""
|
||||
"X-Generator: KBabel 1.9.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "वर्धक भिंग"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Pembaca skrin Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "skrin;pembaca;kebolehcapaian;pertuturan;braille;"
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu skjermleser"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "skjerm;leser;tilgjengelighet;tale;blindeskrift;"
|
||||
|
||||
|
||||
@@ -13,11 +13,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.0.1\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "ओर्का दृष्टि वाचक"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "दृष्टि वाचक; वाचन;ब्रेल;"
|
||||
|
||||
|
||||
@@ -31,11 +31,9 @@ msgstr ""
|
||||
"X-Generator: Poedit 3.2.2\n"
|
||||
|
||||
# vergrootglas/loep
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu schermlezer"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "scherm;lezer;toegankelijkheid;spraak;braille;"
|
||||
|
||||
|
||||
@@ -18,12 +18,10 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu skjermlesar og forstørringsglas"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -23,11 +23,9 @@ msgstr ""
|
||||
"X-Launchpad-Export-Date: 2015-05-21 18:05+0000\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Lector d'ecran Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
"lector d'ecran;oral;braille;votz;sintèsi vocala;sintesi vocala;lector "
|
||||
|
||||
@@ -22,12 +22,10 @@ msgstr ""
|
||||
"\n"
|
||||
"\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "ଓର୍କା ସ୍କ୍ରିନ ପାଠକ /ଛୋଟକୁ ବଡ ଦେଖଉଥିବା ଉପକରଣ "
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -24,11 +24,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-Bookmarks: 589,-1,-1,-1,-1,-1,-1,-1,-1,-1\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "ਓਰਕਾ ਸਕਰੀਨ ਰੀਡਰ"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -24,11 +24,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
|
||||
"|| n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Czytnik ekranowy Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "czytnik;ekran;dostępność;mowa;braille;"
|
||||
|
||||
|
||||
@@ -28,11 +28,9 @@ msgstr ""
|
||||
"X-Source-Language: C\n"
|
||||
"X-Project-Style: gnome\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Leitor de ecrã Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "leitor;ecrã;acessibilidade;voz;braille;"
|
||||
|
||||
|
||||
@@ -49,11 +49,9 @@ msgstr ""
|
||||
"X-DL-Domain: po\n"
|
||||
"X-DL-State: Translating\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Leitor de tela Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "leitor;tela;acessibilidade;voz;braille;"
|
||||
|
||||
|
||||
@@ -24,11 +24,9 @@ msgstr ""
|
||||
"X-Project-Style: gnome\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cititorul de ecran Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "ecran;cititor;accesibilitate;vorbire;braille;"
|
||||
|
||||
|
||||
@@ -22,11 +22,9 @@ msgstr ""
|
||||
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Экранный диктор Cthulhu"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "экран;чтец;доступность;речь;брайль;"
|
||||
|
||||
|
||||
@@ -24,11 +24,9 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr ""
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -18,11 +18,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: KBabel 1.11.4\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr ""
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -19,11 +19,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
|
||||
"X-Generator: Gtranslator 2.91.7\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Ukončí čítačku obrazovky"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -22,11 +22,9 @@ msgstr ""
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
"X-Generator: Poedit 3.0.1\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Zaslonski bralnik Orka"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "govor;zaslonski bralnik;Braillova pisava;brajica;povečevalnik"
|
||||
|
||||
|
||||
@@ -17,12 +17,10 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
#, fuzzy
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Ekrani Zmadhues (Lupë)"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -21,11 +21,9 @@ msgstr ""
|
||||
"X-Project-Style: gnome\n"
|
||||
"X-Generator: Poedit 3.1.1\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Читач екрана Орка"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "читач екрана;говор;брајева азбука;"
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@ msgstr ""
|
||||
"X-Project-Style: gnome\n"
|
||||
"X-Generator: Poedit 2.0.3\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Čitač ekrana Orka"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "čitač ekrana;govor;brajeva azbuka;"
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.3.2\n"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:3
|
||||
msgid "Cthulhu Screen Reader"
|
||||
msgstr "Cthulhu skärmläsare"
|
||||
|
||||
#: cthulhu-autostart.desktop.in:11
|
||||
msgid "screen;reader;accessibility;speech;braille;"
|
||||
msgstr "skärm;läsare;tillgänglighet;tal;punktskrift;"
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user