164 lines
9.8 KiB
Markdown
164 lines
9.8 KiB
Markdown
# Messaging support
|
||
|
||
Pidgin now uses the shared Go messaging history. This first port follows the
|
||
legacy defaults: announce inserted messages from all conversations, keep one
|
||
combined history for each running Pidgin accessibility provider, omit room-name
|
||
prefixes, and suppress typing-status announcements. History contains messages
|
||
received while this reader is running; it does not import an existing transcript.
|
||
|
||
The legacy controls for separate conversation histories, room-name prefixes,
|
||
typing announcements, and message verbosity are not yet ported.
|
||
|
||
When plain Enter clears the focused message entry, the deleted draft is no
|
||
longer spoken before the transcript announces the sent message. This shared
|
||
presentation rule requires a freshly observed plain Enter and a known empty
|
||
native text line at offset zero. It keeps deletion feedback when text was
|
||
selected, including when selection removal arrives before the deletion.
|
||
Backspace/Delete, cut/paste, undo/redo, modified Enter, unknown input/caret data,
|
||
autocomplete, terminals and document editors retain their existing behavior.
|
||
Caret and Braille updates still run before speech is suppressed. This does not
|
||
change word echo or Thunderbird foreground handling.
|
||
|
||
## Shortcuts
|
||
|
||
Both desktop and laptop layouts use:
|
||
|
||
- **Cthulhu+F1–F9**: review the newest through ninth-newest message.
|
||
- **Cthulhu+Shift+F1–F9**: copy that message and confirm after the write succeeds.
|
||
- **Cthulhu+H**: enter or exit learn mode. Cthulhu+F1 no longer opens it.
|
||
|
||
Empty history slots are silent. Chat commands act only when Pidgin owns the
|
||
reader's current focus. They are configurable in the existing key-binding page.
|
||
An explicit shortcut assignment takes precedence over an uncustomized chat
|
||
default, preserving existing configurations; the shortcut list reflects this.
|
||
Within temporary OCR review, Cthulhu+F5 retains its refresh behavior.
|
||
In learn mode, plain F1 still opens documentation, and F2/F3 retain their
|
||
existing functions.
|
||
|
||
Steam retains its existing notification support: **Cthulhu+N** for the latest
|
||
notification and **Cthulhu+Ctrl+N** for the notification list. Neither the legacy
|
||
Steam script nor this port provides F-key conversation review for Steam.
|
||
|
||
## Implementation boundary
|
||
|
||
- `internal/atspi/pidgin_native.go` recognizes the legacy transcript shape:
|
||
a noneditable, multiline text object directly inside a scroll pane, belonging
|
||
to a provider whose process name is `pidgin`. Its bounded ancestor scan copies
|
||
conversation/window identities and the room name. Typing status is identified
|
||
from the inserted range's smaller/lighter text attributes.
|
||
- `internal/messaging` stores copied messages without native handles or output
|
||
dependencies. It bounds each provider's history to nine messages and the number
|
||
of retained providers to 32. Provider identities prevent cross-instance replay.
|
||
- `internal/app/messaging.go` coordinates passive speech, one Braille flash,
|
||
review, and asynchronous clipboard copying on the reader event loop. A bounded
|
||
worker uses the shared clipboard writer; writes have a three-second deadline.
|
||
The event loop cancels pending copies when foreground ownership is cleared,
|
||
when another copy replaces them, on screen lock, and during shutdown.
|
||
- `internal/input/messaging.go` defines numbered semantic commands independently
|
||
of their physical shortcuts. Existing binding configuration and learn mode
|
||
describe the same commands.
|
||
|
||
Background chat never becomes focus or review ownership. Lock gates reject
|
||
messages; lock transitions clear history. Destruction of a known transcript or
|
||
window retires its messages. Ordinary edits, buddy-list activity, and unrelated
|
||
providers keep their existing event-filtering behavior. History is never saved.
|
||
|
||
Future application support should add its own verified native detector and
|
||
explicit dispatch to this shared message contract. Keep transcript identification
|
||
out of generic focus, speech, and history code. Steam conversation support needs
|
||
inspection of an actual chat accessibility tree before choosing its detector;
|
||
notification text alone does not establish conversation identity.
|
||
|
||
## Automated checks
|
||
|
||
From the repository root:
|
||
|
||
```sh
|
||
GOCACHE=/tmp/cthulhu-cache go test ./...
|
||
GOCACHE=/tmp/cthulhu-cache go test -race ./internal/messaging ./internal/input ./internal/atspi ./internal/app
|
||
python3 tests/native_test_session.py env GOCACHE=/tmp/cthulhu-cache CTHULHU_NATIVE_MESSAGING=1 go test ./internal/atspi -run '^TestNativePidginTranscriptCapture$' -count=1 -v
|
||
python3 tests/native_test_session.py env GOCACHE=/tmp/cthulhu-cache CTHULHU_NATIVE_MESSAGING=1 go test ./internal/app -run '^TestNativeMessagingCopyPreservesClipboardText$' -count=1 -v
|
||
python3 tests/native_test_session.py env GOCACHE=/tmp/cthulhu-cache CTHULHU_NATIVE_X11=1 go test ./internal/platform/xorg -run '^TestNativeLearnModeCapturesKeysAndRestoresCommands$' -count=1 -v
|
||
go test ./internal/input ./internal/app -run '^(TestPlainEnterActivityLifetime|TestSubmittedMessageIsAnnouncedOnce|TestSubmissionClearPreservesEditingFeedback)$' -count=1
|
||
python3 tests/native_test_session.py env CTHULHU_NATIVE_SUBMISSION_ECHO=1 go test ./internal/app -run '^TestNativeSubmissionClearAndSelectedReplacement$' -count=1 -v
|
||
```
|
||
|
||
Native checks use private X11 and D-Bus sessions. The transcript fixture sets its
|
||
own process name to exercise the Pidgin detector; it is not the actual Pidgin
|
||
client. These checks verify copied metadata, recorded presentation, synthetic
|
||
keys, and clipboard contents. They do not establish audible speech, physical
|
||
keyboard behavior, or a connected Braille display.
|
||
|
||
The submission replay test reproduces both announcements with the original
|
||
presenter and only the chat announcement with the fix. The GTK submission
|
||
fixture uses the real X11 input listener and native deletion snapshots, and
|
||
checks Enter replacing a selection separately. It does not send real messages.
|
||
|
||
## Human review and live acceptance
|
||
|
||
Review the diff before submission under the contribution policy. Build a reader
|
||
for testing, then load it using the normal authorized reader-replacement procedure.
|
||
The implementation work does not replace the running reader.
|
||
|
||
1. Open two Pidgin conversations. Receive distinct messages in each and verify
|
||
they speak once, including when a different application has focus. Confirm
|
||
keyboard focus remains in that other application.
|
||
2. Return to Pidgin. Check F1/F2 review the most recent messages across both
|
||
conversations. Receive more than nine messages and check the F9 boundary.
|
||
Send two identical messages and verify both occupy separate history slots.
|
||
3. Use Shift+F1/F2 to copy, then paste into a native editor. Check Unicode and
|
||
multiline content. Confirm the copy response follows a successful write.
|
||
4. Type in Pidgin's message entry and account/preferences fields. Check normal
|
||
echo and editing feedback. Buddy-list updates and remote typing status must
|
||
not enter chat history. Send an unselected draft with plain Enter and confirm
|
||
it is spoken once through the transcript. In a native text editor, check
|
||
Backspace/Delete, Ctrl+Backspace, cut/paste, undo/redo, typing over a selection,
|
||
and Enter replacing a selection. Verify the empty input is reflected on
|
||
Braille after sending. Modified Enter and sending selected drafts retain
|
||
their earlier behavior and need separate evidence before changing them.
|
||
5. Switch to another application and check chat commands do not replay Pidgin
|
||
history. Close a conversation window and check its messages are retired.
|
||
Lock/unlock and verify prior history is cleared and messages received while
|
||
locked are not replayed.
|
||
6. Check Cthulhu+H enters/exits learn mode, F1/F2 work inside it, and the shortcut
|
||
list identifies the chat commands. Check a saved custom F-key assignment still
|
||
works and the displaced default is not listed as active.
|
||
7. Check OCR F5 refresh, normal browser navigation, and Steam notifications with
|
||
their existing review/list commands. On Braille, check each message flashes
|
||
once and the normal focus display returns afterward.
|
||
|
||
Actual Pidgin listening, physical shortcuts, and Braille acceptance remain pending.
|
||
|
||
## Discord message focus
|
||
|
||
Named article ancestors are announced when focus enters their controls, matching
|
||
Python's article ancestor presentation. Discord supplies the message author,
|
||
contents, and timestamp in the article's accessible name. The message is spoken
|
||
once on entry, followed by the focused button. Moving between controls within
|
||
the same article does not repeat it. Leaving does not repeat the old message.
|
||
This also works in focus mode and while browser context discovery is pending.
|
||
Unnamed articles do not add announcements; other container preferences retain
|
||
their existing browse-mode policy. Native traversal retains its depth and time
|
||
limits and does not scan message descendants.
|
||
|
||
Automated checks:
|
||
|
||
```sh
|
||
go test ./internal/app -run '^TestMessageArticleAnnouncedOnceWhenTabbingIntoControls$' -count=1
|
||
CTHULHU_NATIVE_BROWSER_TESTS=article python3 tests/native_browser.py
|
||
```
|
||
|
||
Both tests fail without the corresponding fix. The private Chromium fixture
|
||
checks native capture of a message article labelled by author, body, and time.
|
||
The speech replay checks entry, movement within a message, movement to another
|
||
message, exit, and re-entry. Neither establishes audible Discord acceptance.
|
||
|
||
Before submission, review the diff and test a rebuilt reader in Discord with
|
||
Tab and Shift+Tab: enter a message's controls, move through Reply/Forward and
|
||
reactions, then enter another message. Confirm each message is read on entry,
|
||
control labels remain correct, and message contents do not repeat at each Tab
|
||
stop. Repeat in browse and focus modes; check the message composer, ordinary
|
||
browser buttons, and list/panel context announcements for regressions. Verify
|
||
physical Braille focus and routing separately. Installed-binary, physical-input,
|
||
audible-speech, and Braille-display acceptance remain pending.
|