84 Commits
Author SHA1 Message Date
Storm Dragon f0352878f7 updated hook.'
git commit updated hook.
2026-10-25 15:36:09 -04:00
Storm Dragon cba6925bb9 Merge remote-tracking branch 'origin/testing' 2026-10-25 15:27:30 -04:00
Storm Dragon af78dd7a20 Connect testing ancestry to the master snapshot 2026-10-25 15:27:27 -04:00
Storm Dragon 01a43872ba Prepare master release metadata and packaging 2026-10-25 15:27:15 -04:00
deedra 7aa4617d04 Suppress hypertext object markers in text-change speech
Thunderbird's message composer emits U+FFFC object replacement characters
when creating or removing paragraph objects. Treating these structural
updates as inserted or deleted text sent raw placeholders to speech,
including multi-character updates that bypass ordinary key-echo settings.

Remove object markers from insertion and deletion presentation while
preserving surrounding text. Normalize typing-echo payloads before deciding
the echo kind or applying character, word, and sentence echo policies.
Return no text or echo kind for updates containing only object markers.

Add regression cases for single and repeated markers, mixed marker/text
payloads, and ordinary text through both event presentation and typing echo.

Validation:
- go test ./... -count=1, with the local cache and dependency network disabled.
- Built the reader and the BrlAPI-tagged Braille helper.
- A disposable Thunderbird profile on a private X11 display and session bus
  produced one marker-containing presentation before the fix and none after.
- Private Thunderbird checks preserved character, word, and line navigation
  after typing several paragraphs.
- The user confirmed main-arrow reading worked with the restarted build.

The original silent-arrow failure was not reproduced in isolation. Restarting
restored reading in the user's session; this commit does not claim to fix
its underlying cause or change arrow-key handling. Physical Braille output
was not tested. Preserve the original and fresh diagnostic logs locally.
2026-10-25 12:19:01 -07:00
Storm Dragon 9462ebfc82 More browser work. 2026-10-24 18:33:04 -04:00
Storm Dragon bf4b9d7b54 Browser changes. 2026-10-24 15:59:07 -04:00
Storm Dragon 133953e972 Report wine-access version if available in version commands. 2026-10-24 15:19:43 -04:00
lilmike 7c032a5f6e Some browser fixes. 2026-10-24 12:07:02 -07:00
Storm Dragon 8a560a25a5 Version bump. 2026-10-24 13:21:35 -04:00
Storm Dragon 54722e985e Simplified speech settings. 2026-10-24 05:27:16 -04:00
Storm Dragon 03e2b31e09 Fixed a bug with some edit field types that would cause every event to read the whole field. 2026-10-23 12:21:34 -04:00
Storm Dragon 736f5a0f68 Version Bump. 2026-10-23 01:31:20 -04:00
Storm Dragon 1d75168807 Extended tentacle capabilities a bit. 2026-10-22 21:13:08 -04:00
Storm Dragon d7b1efeba0 Some hopefully final flat review touch ups. 2026-10-22 16:39:44 -04:00
Storm Dragon fb2c5b818d Browser and flat review fixes. 2026-10-22 16:00:30 -04:00
Storm Dragon 754f1ce6d7 Fixed multiple sound types being played for some controls. 2026-10-22 14:22:36 -04:00
Storm Dragon 205d5c49d2 Preparing for release, so a bit of maintenance. 2026-10-22 13:14:06 -04:00
Storm Dragon 3e9c4f83ce Options for controlling how and when speech is interrupted now wired up in preferences under the speech tab. 2026-10-22 03:25:40 -04:00
Storm Dragon e62f8c8e17 Fixed a bug in a test that caused other channel names than master to fail.? 2026-10-22 01:42:53 -04:00
Storm Dragon b7426177d9 Version bump 2026-10-22 01:37:59 -04:00
Storm Dragon e88de5ee66 More flat review improvement. 2026-10-21 20:56:18 -04:00
Storm Dragon 50e32f24df Logging changes. Use --debug-file for a replaced log. Use --append to append to the log file if it exists. Also fixed a bug where cthulhu could try to restart without replacing the old running version. 2026-10-21 15:11:19 -04:00
Storm Dragon 4643f8e47f Flat review improvements. 2026-10-21 11:49:25 -04:00
Storm Dragon ce5f196956 Make unrelated atspi events filtering better. 2026-10-20 23:37:50 -04:00
Storm Dragon 41283a5d8d Add a description column to the reading settings table under speech. 2026-10-20 19:33:48 -04:00
Storm Dragon ffcea2efea Touch up our phonetic settings. 2026-10-20 19:19:04 -04:00
Storm Dragon 08cbcc00cb Improved flat review timing by a lot. 2026-10-20 18:55:32 -04:00
Storm Dragon 58e4b8aa15 Found and fixed a bug where Cthulhu could get stuck in a loop sometimes on pages with tooltips. 2026-10-20 18:33:29 -04:00
Storm Dragon 90f1411405 mnemonics are now spoken without surrounding punctuation e.g. les or greater. 2026-10-20 16:40:06 -04:00
Storm Dragon 1f8420ab4b Merged changes from Deedra. 2026-10-20 14:03:44 -04:00
Storm Dragon f4400cf3bb Updated AGENTS.md. 2026-10-20 13:52:38 -04:00
deedra 548a43aa24 Merge testing into deedra
Resolve the parity-ledger conflict by retaining testing's updated LibreOffice entry and Steam progress entry alongside deedra's edit-label and Mozilla records.

Verified: go test ./... -count=1, go vet ./..., parity ledger validation, and whitespace checks. Native GUI and physical speech/Braille acceptance were not run.
2026-10-20 10:47:34 -07:00
deedra edd6c560b8 Read Thunderbird message text and preserve link announcements
Thunderbird HTML messages expose readable text on containers around embedded
objects. The browse cursor previously considered only text leaves, and native
document capture omitted heading/link character counts. This skipped message
content, headings and link text. A caret event following Tab could also replace
a complete link announcement with its first character.

Capture owned hypertext child identities and native placeholder offsets on the
GLib thread, releasing native interfaces before returning. Require every child
to occupy one embedded-object character so providers exposing duplicate text
through static descendants retain their ordinary traversal.

Traverse native text ranges before and after embedded children without changing
their offset domains. Preserve character, word, line and document-boundary
navigation; normalize native caret and Braille routing positions at adjacent
embedded links. Keep the Braille cursor on the correct fragment when a parent
contributes text more than once to an assembled line.

Ignore same-input link caret echoes after focus while retaining subsequent
arrow and selection feedback. Add regression tests, extend the private Firefox
fixture, and record behavior and remaining acceptance in the parity ledger.

Validation:
- Full Go test suite with count=1; focused app/atspi/review race checks.
- go vet ./...; reader and brlapi helper builds.
- Private Firefox baseline, mixed-parent offsets and tab navigation.
- Private Chromium fragments, named links, document navigation and selection.
- Parity ledger validation and whitespace checks.

The existing Firefox tab test intermittently timed out on both an untouched
HEAD copy and the changed tree; the final run passed. The unchanged
TestRunReachesSoundStopAfterEarlierServiceStopError also failed once during
startup cancellation and passed in subsequent full-suite and race runs.

Both installed binaries were verified and the reader reloaded in its original
desktop session. The maintainer confirmed readable message text and later
working links after an earlier intermittent omission. That omission remains
untraced; repeat live acceptance and physical Braille verification remain open.
2026-10-20 10:41:38 -07:00
Storm Dragon 88e8627867 Updated docs. 2026-10-20 13:39:27 -04:00
Storm Dragon dcdeab256e Merge branch 'deedra' into testing
Combine relation-only edit-label capture while retaining bounded text reads,
password-target exclusion, UTF-8 output limits and menu checkability capture.
Keep both label regression fixtures and the existing foreground test dispatch.
Preserve Wine helper diagnostics and recovery documentation, and retain the
current parity records alongside the incoming edit-label entry.

Validation:
- go test ./... -count=1 -timeout=180s
- go vet ./...
- CTHULHU_NATIVE_EDIT_LABELS=1 python3 tests/native_atspi.py
- Isolated TestNativeTextLabelRelations
- python3 tests/native_atspi.py
- Parity ledger validation: 65 rows
- Python syntax and staged diff checks

Native GTK table fixtures emitted ATK warnings; all assertions passed.
Live speech and physical Braille were not retested.
2026-10-20 13:35:29 -04:00
deedra 8ef838e16e Speak relation-only labels for unnamed edit fields
Irctest exposes its settings-field labels through AT-SPI LABELLED_BY
relations while leaving the fields' accessible names empty. Cthulhu
previously captured only the name, so focus speech announced the text
role and contents without Nickname, Username, or Real name.

Resolve direct label targets in the shared native snapshot capture for
unnamed text, entry, and password-text objects. Preserve explicit names,
combine multiple label targets in relation order, and use label/static
text only when a target has no accessible name. Bound relation scans,
target queries, and UTF-8 output; release all native references and avoid
reading password targets. No application-specific handling is required.

Add an isolated GTK fixture and native regression test exercising capture
and speech formatting for single labels, multiple labels, explicit names,
unlabelled fields, and labelled password fields without password contents.
Expose the probe through CTHULHU_NATIVE_EDIT_LABELS=1 in native_atspi.py.
Record verification and installed-reader acceptance in the parity ledger.

Validation:
- go test ./... -count=1
- CTHULHU_NATIVE_EDIT_LABELS=1 python3 tests/native_atspi.py
- go vet ./...
- Build the reader and the brlapi-tagged Braille helper.
- Validate configuration and testdata/parity-ledger.csv.
- Read-only live irctest capture includes all three settings-field labels
  in formatted speech.
- Install both tested binaries and replace the reader in its original
  desktop session; verify service ownership and installed build hashes.
- Maintainer confirms the installed reader now speaks the field labels.

The full suite passes outside the sandbox; its socket and process checks
require access unavailable inside the sandbox. Physical Braille acceptance
remains pending. Preserve cthulhu.log outside the commit.
2026-10-20 09:29:24 -07:00
deedra 538ff88028 Document Go installation and standalone Wine helper recovery
Record the user-local Go installation used by the working reader: install
cthulhu and cthulhu-braille together, validate the configuration, and use
--replace from the original desktop session. Explain that another session
bus can start a second reader instead of replacing the intended instance.

Document the complete five-file standalone wine-access installation and
the legacy helper path supported by the Go supervisor. Older Python
Cthulhu builds can overwrite the launcher and sidecar at that path while
leaving the native hook files behind. Such a helper can connect to D-Bus
without supplying the current native menu and editor support.

Describe recovery by reinstalling the standalone helper and reloading the
reader, including restarting Wine applications when older hook DLLs are
already loaded. Keep the source/build distinction explicit: rebuilding
the Go reader alone does not refresh wine-access.

Validation for these documentation changes:
- Reviewed the complete diff and ran git diff --check.
- Checked the documented shell commands with bash -n.
- Installed both documented Go build outputs into a temporary directory,
  compared their bytes with the builds, and passed --check-config.
- Verified the installed reader, Braille helper, and all five Wine helper
  files match the builds used for the restored installation.

Runtime validation during the preceding repair:
- Cthulhu internal/wine and internal/remote tests passed; Wine-specific
  internal/app tests passed.
- The legacy installed helper failed the isolated 32-bit editor check;
  the standalone helper passed it.
- Standalone controller, 32-bit late-attachment/restart, and hook-safety
  checks passed on private displays and session buses.
- The user confirmed MUSHclient reading was restored. Physical Braille
  was not checked.

These are documentation changes; the installed behavior already comes
from the existing source revisions, with no new runtime source patch.
2026-10-20 02:44:48 -07:00
Storm Dragon f8efae9a92 Version bump and feature freeze. Until release bug fixes only. 2026-10-20 02:40:24 -04:00
Storm Dragon 82887b3897 Attempt to fix the rest of speech interrupting when it shouldn't. Also play radio buttons after the ui after they figure out if they are checked or not. 2026-10-19 19:25:11 -04:00
Storm Dragon 2c6ab2ce76 Copy settings over to lightdm with --greeter flag. 2026-10-19 18:08:22 -04:00
Storm Dragon ab14244404 Fixed character/word navigation inside links. 2026-10-18 23:43:16 -04:00
Storm Dragon 396efbd7c5 Version bump and some lable/relation fixes. 2026-10-18 22:11:54 -04:00
Storm Dragon d717b93849 Fixed terminal bug. Fixed tests which could leave the system without proper accessibility setup which could cause cthulhu to fail to start. 2026-10-18 19:18:57 -04:00
Storm Dragon 9e0ff41b16 Fixed a bug with removed or replaced form fields on some websites. 2026-10-18 17:02:37 -04:00
Storm Dragon 919b9e013b Fixes for mumble check/unchecked items and for menus that were not reading properly. 2026-10-18 12:39:26 -04:00
Storm Dragon 3db88abddb Title keybinding added. 2026-10-17 23:10:15 -04:00
ak47 53d14d561b Attempt to fix problems with flatpacks, e.g. Steam. 2026-10-17 20:58:35 -04:00
ak47 1c4e0a99bc Update caps notification preferences. 2026-10-17 20:16:43 -04:00
Storm Dragon 3df96145f2 Better handle some gtk tables that report themselves as lists. 2026-10-17 15:49:37 -04:00
Storm Dragon 824a4d2369 More browser work this time focusing on Firefox and Thunderbird. 2026-10-17 13:15:51 -04:00
Storm Dragon a763714fb4 Added some benchmarks. 2026-10-17 01:22:52 -04:00
Storm Dragon 37fdd4e114 Element list keys added. 2026-10-17 01:01:51 -04:00
Storm Dragon 25a1338222 A few edge case fixes for tentacles. 2026-10-16 23:59:22 -04:00
ak47 f753e9b505 More browser improvements. 2026-10-16 23:48:58 -04:00
Storm Dragon ebb9ad48d0 Better logging for browser. 2026-10-16 20:16:22 -04:00
Storm Dragon 423590e11a Browser updates. 2026-10-16 19:33:18 -04:00
Storm Dragon 2fa9bc8724 Fixed bug in tentacles. 2026-10-16 15:33:40 -04:00
Storm Dragon 4be35fcf9c Fixed a bug where key echo voice was getting cut off when reviewing text. 2026-10-16 12:38:31 -04:00
Storm Dragon 0834b47b55 Echo voice now used for its adjusters so prieview can be done while setting the voice. 2026-10-15 23:33:02 -04:00
ak47 70d447667e Keyboard echo revised with 3 versions. 2026-10-15 21:54:51 -04:00
Storm Dragon 04e6c08fff Review and strengthen LibreOffice code so far. 2026-10-15 21:32:44 -04:00
Storm Dragon f885333520 More LibreOffice changes. 2026-10-15 21:00:52 -04:00
Storm Dragon 3e0bdc578f Possibly make things a little better for wayland users. 2026-10-15 17:29:41 -04:00
Storm Dragon 70e8e14231 Version bump. 2026-10-15 12:51:35 -04:00
Storm Dragon d756ceb2b2 Integrate with wine-access logging. 2026-10-15 12:50:15 -04:00
Storm Dragon 8e98321e6b Hook to check for speech interruption regression. 2026-10-15 02:04:03 -04:00
Storm Dragon c0e4f7d292 Merge branch 'deedra' into testing 2026-10-15 01:49:44 -04:00
deedra 15d527c619 Respect Cthulhu key echo settings for Wine typing
Wine editor insertion events previously reached speech and Braille without
checking the user's typing echo preferences. Turning off key echo or an
individual character category therefore left Wine typing feedback enabled.

Read the live settings for each insertion and reuse the native text
presentation policy for alphabetic, numeric, punctuation, symbol, space and
diacritical input. Honor character echo and the master key echo switch;
apply the action-key setting to the helper's tab and new-line labels.
Reject unexpected multi-character insertion labels rather than treating
these ordered character events as paste notifications.

Preserve navigation, selection and deletion feedback when typing echo is
disabled. Retain repeated characters, case, uppercase/custom voice routing,
focus ordering and the existing stale-source/password protections.

Add regression coverage for live disable/re-enable, independent categories,
Unicode, character-echo overrides, and unaffected editor actions. Extend
the private D-Bus test to exercise settings changes through the real Wine
service signature. Document behavior, current word/sentence echo limits,
and live Notepad acceptance checks in the README.

Validation:
- Reproduced disabled typing reaching output with the new test before fixing.
- Full go test -race ./... -count=1 passed outside the socket-restricted sandbox.
- Private-session TestNativeSessionBusWineEvents passed with -race.
- Focused typing/editor regressions passed, including a fresh pre-commit run.
- go vet passed for internal/app, presentation, remote and wine.
- Reader and BrlAPI helper builds passed; reader --version succeeded.
- gofmt and git diff --check passed; independent review found no blockers.

Live audible speech, physical keyboard and physical Braille acceptance
remain pending. No running reader was replaced. Changes target deedra.
2026-10-14 22:32:37 -07:00
Storm Dragon b5a5b86dda More LibreOffice work. 2026-10-15 01:10:43 -04:00
Storm Dragon 4ac59d4ced More work on LibreOffice support. 2026-10-15 00:50:49 -04:00
Storm Dragon e0c8c6198c Fixed a regression in wine title reading. 2026-10-14 21:27:29 -04:00
ak47 a121c26d63 Code optimization. 2026-10-14 20:39:01 -04:00
Storm Dragon 12c514aab0 Sometimes when switching from steam to a different workspace and back only the outer window takes focus so some actions don't work. Tentative fix for that. 2026-10-14 19:51:07 -04:00
Storm Dragon 9205e7280a Progressbar fix. 2026-10-14 18:22:59 -04:00
deedra 6754c8ef6c Fix Wine window title announcements on foreground switches
Wine review establishes navigation ownership and stores the window title
without speaking an activation. The native title controller treated that
metadata as an already announced title, suppressing the introduction when
review focus arrived first. Frame-to-control focus updates also reset the
window title controller, cancelling pending introductions and discarding
duplicate history.

Distinguish Wine review ownership from spoken AT-SPI activations when
classifying and deduplicating native introductions. Use the native Wine
application identity when waiting for committed application preferences,
so introductions remain audible with automatic title changes disabled
while subsequent title changes honor that application's settings.

Separate object focus cleanup from window title cleanup. Wine review
revisions now retain the pending title and its duplicate history; actual
foreground transitions, native window lifecycle cleanup, screen lock,
and shutdown continue to reset title state. Preserve XTerm/Fenrir handoff
and ordinary AT-SPI activation deduplication.

Add regressions for both native/review arrival orders, ordinary Wine
windows and virtual desktop children, duplicate reports, return to the
same window, and application preference handoff. Add a private D-Bus
event-loop test for a frame-to-control focus burst and document focused
verification and live acceptance procedures in tests/window_titles.md.

Validation:
- Confirmed the new title introduction, preference handoff, and private
  focus-burst regressions fail before the fix and pass afterward.
- go test ./... -count=1 passed with local socket access; the sandboxed
  attempt was blocked by Unix and loopback speech fixture sockets.
- Focused Title, WineReview, XTerm, and Foreground tests passed with
  the race detector.
- Private D-Bus TestPrivateWineTitleSurvivesReviewFocusBurst passed
  with the race detector.
- go vet ./internal/app, the reader build, and git diff --check passed.

Installed-reader behavior, real Wine/X11 switching, physical Alt+Tab,
audible speech, and physical Braille acceptance remain pending. The
private fixture uses copied foreground metadata and a real registry,
not a real Wine window. No installed reader was replaced.
2026-10-14 16:38:37 -04:00
Storm Dragon 7f78177786 libreoffice support started, still broken. Some updates to how wine-access gets called. 2026-10-14 16:24:49 -04:00
Storm Dragon 8e76d2341c Fix panning sounds after scrolling. 2026-10-14 12:50:44 -04:00
Storm Dragon b2f558c26c Fixed some tests. 2026-10-14 01:22:04 -04:00
Storm Dragon 6613237233 Code fixes from old cthulhu-go name. 2026-10-14 01:08:50 -04:00
Storm Dragon ee4d50cacc Updated some docs. 2026-10-14 00:55:22 -04:00
Storm Dragon e5049b9f5e Version bump. 2026-10-14 00:22:42 -04:00
Storm Dragon 069fc674dc Cthulhu is no longer a fork. Now it is a screen reader written in Golang. 2026-10-14 00:16:34 -04:00
Storm Dragon a998fe67de Create testing branch with distro packaging only 2026-10-13 22:25:51 -04:00
7 changed files with 110 additions and 8 deletions

No files matched your search

+19
View File
@@ -48,6 +48,25 @@ go run ./cmd/parityledger validate testdata/parity-ledger.csv
Start verification with the affected packages; run broader checks when the change affects shared behavior or before submission where practical. Format edited Go files with `gofmt`; run `shellcheck` for edited shell scripts. Use deterministic tests and synchronization instead of timing sleeps. Keep fixtures generic, without real usernames or personal identifiers.
### Version update pre-commit hook
The optional `hooks/pre-commit` hook updates the Go `Version` constant to the
local date and `Channel` to the current branch, then stages the version file.
It skips merge commits and honors `SKIP_VERSION_UPDATE=1` for deliberate
version overrides. If an update is needed and the version file has unstaged
changes, the hook stops so those edits are not silently included in the commit.
In a clone with no existing pre-commit hook, enable it with:
```sh
cp hooks/pre-commit .git/hooks/pre-commit
```
The local copy stays active when switching to branches without the tracked
hook file; copy it again after updating the hook. Preserve and integrate an
existing hook rather than overwriting it. The old Python version hook and
`.git/versionpath` are not used by this Go hook.
### Speech regression push check
Run `python3 tests/check_speech.py` for speech queue, title, Wine review metadata,
@@ -4,7 +4,7 @@
pkgbase=cthulhu-git
pkgname=cthulhu-git
_pkgname=cthulhu
pkgver=2026.10.24.r77.g133953e
pkgver=2026.10.24.r478.g42afa2a
pkgrel=1
pkgdesc="Desktop-agnostic screen reader with speech, Braille, and Tentacle support"
url="https://git.stormux.org/storm/cthulhu"
@@ -58,11 +58,6 @@ options=(!debug !lto)
source=("${_pkgname}::git+https://git.stormux.org/storm/${_pkgname}.git#branch=master")
sha512sums=('SKIP')
prepare() {
cd "${_pkgname}"
git checkout -B testing origin/testing
}
pkgver() {
cd "${_pkgname}"
local projectVersion revisionCount commitHash
+55
View File
@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail
if [[ ${SKIP_VERSION_UPDATE:-0} == 1 ]]; then
exit 0
fi
gitRoot=$(git rev-parse --show-toplevel)
cd "$gitRoot"
if [[ -f $(git rev-parse --git-path MERGE_HEAD) ]]; then
exit 0
fi
versionFile=internal/version/version.go
if ! git cat-file -e ":$versionFile" 2>/dev/null; then
echo "Error: $versionFile must be present in the index." >&2
exit 1
fi
if ! branchName=$(git symbolic-ref --quiet --short HEAD); then
echo "Error: Check out a branch or set SKIP_VERSION_UPDATE=1." >&2
exit 1
fi
newVersion=$(date +%Y.%m.%d)
escapedChannel=${branchName//\\/\\\\}
escapedChannel=${escapedChannel//\"/\\\"}
if grep -Fxq "const Version = \"$newVersion\"" "$versionFile" &&
grep -Fxq "const Channel = \"$escapedChannel\"" "$versionFile"; then
exit 0
fi
if ! git diff --quiet -- "$versionFile"; then
echo "Error: Stage or save unstaged changes in $versionFile before its version update." >&2
exit 1
fi
if [[ $(grep -Ec '^const Version = ".*"$' "$versionFile") != 1 ]] ||
[[ $(grep -Ec '^const Channel = ".*"$' "$versionFile") != 1 ]]; then
echo "Error: Expected one Version constant and one Channel constant in $versionFile." >&2
exit 1
fi
sedChannel=${escapedChannel//\\/\\\\}
sedChannel=${sedChannel//&/\\&}
sedChannel=${sedChannel//|/\\|}
sed -i \
-e "s|^const Version = \".*\"$|const Version = \"$newVersion\"|" \
-e "s|^const Channel = \".*\"$|const Channel = \"$sedChannel\"|" \
"$versionFile"
git add -- "$versionFile"
echo "Updated Cthulhu version to $newVersion-$branchName."
+4
View File
@@ -256,6 +256,9 @@ func EventSpeechWithOptions(event atspi.Event, options Options) Speech {
return Speech{Text: event.Source.Text}
}
case atspi.TextInsertedEvent:
// Hypertext editors report paragraph creation as inserted object
// placeholders. These describe structure rather than typed text.
event.Payload = strings.ReplaceAll(event.Payload, "\ufffc", "")
if !shouldEchoInsertion(event.Payload, insertionEchoOptions(event, options)) {
return Speech{}
}
@@ -264,6 +267,7 @@ func EventSpeechWithOptions(event atspi.Event, options Options) Speech {
}
return Speech{Text: event.Payload}
case atspi.TextDeletedEvent:
event.Payload = strings.ReplaceAll(event.Payload, "\ufffc", "")
if utf8.RuneCountInString(event.Payload) == 1 && unicode.IsSpace(firstRune(event.Payload)) {
return Speech{Text: caretCharacterText(event.Payload)}
}
+6
View File
@@ -31,6 +31,12 @@ func TypingEchoText(event atspi.Event, previousText string, options Options) str
}
func TypingEcho(event atspi.Event, previousText string, options Options) (string, string) {
if event.Type == atspi.TextInsertedEvent || event.Type == atspi.TextDeletedEvent {
event.Payload = strings.ReplaceAll(event.Payload, "\ufffc", "")
if event.Payload == "" {
return "", ""
}
}
options = insertionEchoOptions(event, options)
kind := ""
if event.Type == atspi.TextInsertedEvent && utf8.RuneCountInString(event.Payload) == 1 {
+23
View File
@@ -164,3 +164,26 @@ func TestTypingEchoInEditFieldsOnly(t *testing.T) {
})
}
}
func TestEditorStructuralChangesDoNotSpeakObjectMarkers(t *testing.T) {
for _, eventType := range []string{atspi.TextInsertedEvent, atspi.TextDeletedEvent} {
for _, tc := range []struct{ payload, want string }{
{"\ufffc", ""},
{"\ufffc\ufffc", ""},
{"\ufffcDraft\ufffc", "Draft"},
{"ordinary text", "ordinary text"},
} {
t.Run(eventType+tc.payload, func(t *testing.T) {
event := atspi.NewEventWithPayload(eventType, atspi.Snapshot{
Role: "document web", Editable: true,
}, tc.payload)
if got := EventTextWithOptions(event, DefaultOptions()); got != tc.want {
t.Fatalf("structural change speech = %q, want %q", got, tc.want)
}
if got := TypingEchoText(event, "", DefaultOptions()); got != tc.want {
t.Fatalf("structural change echo = %q, want %q", got, tc.want)
}
})
}
}
}
+2 -2
View File
@@ -21,8 +21,8 @@ import "strings"
const Name = "Cthulhu"
const Version = "2026.10.24"
const Channel = "testing"
const Version = "2026.10.25"
const Channel = "master"
var Build = Version