Replace the oversized header and reference rail with stable editor slots and a retained supporting drawer. Bind diagnostic, result and menu actions to their original publication and visit; preserve effective selections on navigation and dismiss Actions, Find and the drawer one surface per Escape. Retain exact Windows source captures, eight final gates (871 desktop passes), independent reviews, native selection/rename/recovery trials and the original failures. All 526 tested inputs and staged evidence were byte-checked before commit. Combined preview integration and packaging remain with issue 27; Linux remains paused.
3.7 KiB
Escape dismissal correction: independent static review
PASS — no actionable mismatch found within the bounded correction. Reviewed formatted C:/ar-text-9e8r6t source against exact attempt-5 captured files and the interaction contract. No builds, tests, native actions or production edits performed. Parent retains execution/acceptance ownership.
The production diff is confined to the ordinary Message::Escape arm at app.rs:1996: when Text navigation is admitted and Find is open, it closes Find without calling show_drawer(None). That preserves drawer visibility and visit. A later Escape with only the drawer open uses the existing hide operation, retaining presentation data while rotating the visit and revoking old row authority. Both admitted paths keep the existing focus-only restoration, preserving live Word/Line selection rather than roundtripping endpoints.
The existing Text-popup router returns before this arm; its captured-Escape bridge remains disabled while the popup owns the key. Architecture, model menu, busy/modal routing and source-rename dismissal likewise remain unchanged and return before ordinary Text dismissal where applicable (app.rs:1232,1287,1324,1393,1455). Thus this delta does not bypass their input priority. The contract's menu→Find→drawer sequence and Find-specific retained visit/data behavior match this implementation.
Generic source interaction still invalidates pending navigation/reveal before an ordinary Escape. It does not free the occupied worker slot. The migrated pending/completed query tests confirm that successive Find/drawer dismissal retains in-flight ownership, admits the later display completion without a jump/reopen and preserves raw source/Document identity/history.
The subscription evaluator is meaningful: it creates a real Iced TextInput, optionally focuses it, delivers Escape, obtains actual Captured or Ignored status from its Shell, and passes that status to the actual App subscription recipes. It checks exactly one Escape message in both ordinary status routes and no duplicate captured bridge under Text popup ownership. Tests preserve semantic selected bytes, raw cursor, result Arc, query text, grouping, saved 96px offset and visit after Find dismissal; they require visit rotation only on subsequent drawer dismissal. Hosted/file/pending modal cases assert that their first Escape preserves underlying surfaces and cannot mint editor focus.
Evidence limits: the popup test sends its actual tokened menu.on_close message, rather than mounting the Popup's own key handler. Saved 96px scroll is controller state, not measured native scrollbar retention. The helper uses the null renderer for TextInput status/focus protocol, polls only immediately available subscription output and does not run native input or returned editor-focus operations; existing dedicated focus tests cover those operations. Rename priority here is a source-routing check, not a newly mounted rename-modal test. No native acceptance or all-platform result is claimed.
Bindings
- Formatted
crates/oa-desktop/src/app.rs: 223,370 bytes; SHA-2564f4c1bb5f832601a072b5cd406a75731982e8b9955ee6af39a93f124496938f9. - Formatted
crates/oa-desktop/src/app/source_symbols/tests.rs: 84,817 bytes; SHA-256411a8b35fe1d3211daf165d1585d209df9961b0da59a969a856991508bbc29a6. harness/text-workspace-interaction-contract-20260912.md: 14,223 bytes; SHA-2567ee4df9c57e1fbe28cec27211945044ac2556f63442404d9fa6ffbd195095589(especially lines 21 and 53).- Attempt-5 baseline ZIP: SHA-256
83ff861fc27b7aead159fde12e6fd881ba6c3c02b29e7bf10bbc12c60b7e6067. - Baseline App: SHA-256
75ef46ef2789b32c5837ee33dfdc303eaba013ba75767138e4a19ba5113bc6ba; baseline tests:00cbacdd0af98858b5e74608720bd8251719c9926569a65a0ad777a40f1744c9.