Files
cthulhu/docs/testing/flat-review-tables.md

110 lines
7.1 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.
# Flat review in scrolling tables
Flat review captures the visible cells of selectable tables through AT-SPI
table coordinates and component hit testing. It does not enumerate the model's
offscreen rows. Visible column headers and compound cells remain available.
The first selected cell is retained as a focus anchor if horizontal scrolling
hides its column; its offscreen text does not enter review output.
New flat-review objects retain libatspi's event-maintained provider cache.
Clearing that cache forced redundant child-count requests even for known leaves,
which could abort capture when a provider was briefly unresponsive. Objects
already marked dirty in the owned tree still refresh their native snapshot.
Long text geometry queries are bounded to 128 characters per provider call.
Their rectangles are combined across every chunk, including interior bidi runs.
For partially clipped lines, offscreen chunks are rejected before querying
individual character rectangles. This preserves native offsets and visible text
without measuring thousands of characters in one synchronous request.
Exact range rectangles are reused only within one object's synchronous text
capture, including zero-area rectangles. This avoids querying the same 128-character
blocks once to combine line bounds and again to clip the line. The map is discarded
when that object's text capture returns; a changed viewport or later command does
not reuse it. Failed requests are not stored, and cancellation is checked before
using a saved rectangle. Individual glyph checks for clipped text remain intact.
In the live FastSMRW investigation, measuring an entire 3,424-character line took
about 0.9 seconds, exceeding the adapter's 0.8-second provider timeout. A later
child-count query then reported that the process appeared hung, masking the
earlier text-geometry timeout. The same read-only capture probe failed before
bounded measurement and completed after it. That is provider-capture evidence;
speech, keyboard response and physical Braille still require live acceptance.
Three subsequent read-only review-worker runs completed line, word, character,
window-start and window-end commands. Initial capture took roughly 4–6 seconds;
cached commands took about one millisecond. One earlier worker probe returned a
negative child count, which did not recur in those three runs. Negative-count
errors now include the same object metadata as provider-error responses so a
recurrence can be located. Initial-capture latency remains a live acceptance
concern.
Debug logs include one `flat review capture timing` record for each capture
attempt, including a timed-out attempt while a native call is still running.
It reports request-lock and GLib queue wait, root selection, cache preparation,
snapshot, geometry, visible-text, table-viewport, child-count, child-enumeration,
installation and reference-cleanup timings. Each stage has a total, invocation
count, and longest invocation with its bus/path/role. These are helper-stage
timings: a visible-text invocation can contain several native range queries.
`last_stage`, `stage_duration` and the object identity describe the stage at
completion or timeout; on timeout its elapsed portion is included in totals.
`root_scope` distinguishes a focused-window root from the desktop fallback.
Captured/pending object counts and text byte counts show traversal progress.
No names or text contents are added. Diagnostics allocate no per-capture trace
unless debug logging is enabled, and do not issue additional provider queries.
Late native completion cannot overwrite the timeout record.
A descendant which becomes defunct during capture is removed from its parent's
child list. A defunct root still fails capture. Other provider failures still
fail capture rather than presenting an old snapshot. Child-count errors include
the object's bus, path, role and the number of objects already captured, without
logging its name or text.
Run the native viewport regression on a private display and accessibility bus:
```sh
python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_TABLE=1 go test ./internal/atspi -run '^TestNativeFlatReviewLargeGTKTable$' -count=1 -timeout=150s -v
python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_CACHE=1 go test -race ./internal/atspi -run '^TestNativeFlatReviewPreservesProviderCache$' -count=1 -timeout=30s -v
python3 tests/native_test_session.py env CTHULHU_NATIVE_REVIEW_BOUNDS=1 go test -race ./internal/atspi -run '^TestNativeFlatReviewBoundsSlowLongRanges$' -count=1 -timeout=30s -v
python3 tests/native_atspi.py
```
The viewport test covers a 6,000-row GTK table scrolled to its middle, a changed
viewport and updated row text, a small table, an empty table with headers,
horizontal scrolling, and cells with multiple renderers. It checks that a small
viewport captures fewer than 100 objects. Before the change, the large case
captured 6,006 objects. The existing suite covers flat-review cursor movement,
text changes, terminal viewport capture, password exclusion, and ordinary
single/multiple GTK table selections.
The cache regression uses a GTK label whose initial cache reports zero children,
then arms a deliberately slow child-count getter. Before cache preservation,
capture failed on that redundant query. The test requires capture to succeed
without invoking the getter, then changes the label and checks that dirty text
is refreshed. The C fixture is compiled with the existing GTK development
dependencies during the test.
The long-range regression uses a horizontally clipped 3,424-character GTK label.
Its provider deliberately stalls when a range query exceeds 128 characters.
Capture must retain visible text and never trigger that large request. The fixture
also counts repeated native range requests: the original implementation repeats
36 requests, while capture-local reuse makes none. Unit
tests also cover Unicode offsets, offscreen query counts, interior bidi bounds,
zero-size chunks, cancellation and provider errors.
For live acceptance, use a user-started updated reader and:
1. In FastSMRW, review lines, words and characters in both directions, including
window start/end. Repeat after changing the selected post and after a timeline
update. Responses should complete without a long pause or a location error.
2. Scroll the table away from its original viewport. Review should contain the
currently visible rows. Check another GTK table, its column headers, and a
horizontally scrolled table.
3. Check ordinary Up/Down selection speech, menus, preferences notebooks and
terminal flat review. Semantic browser navigation and table speech should
continue to work because their captures retain the complete semantic tree.
4. Confirm audible output and physical Braille separately. Private native tests
do not establish these outcomes or prove that the live FastSMRW timeout is
resolved. Preserve fresh logs if a failure remains; the object metadata will
identify where capture stopped. Inspect `flat review capture timing` to
compare the failed initial capture with a successful retry, including root
scope, queue wait, stage totals and the slowest object in each stage.