Files

164 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.