104 lines
6.0 KiB
Markdown
104 lines
6.0 KiB
Markdown
# Canvas focus continuity after accepted edits and history
|
|
|
|
Native parent observation at immutable `f7d84fa`: allocation work canvas click,
|
|
Delete placement, Save, Undo, Save, Redo, Save, Undo, then Shift+Delete produces
|
|
no dialog. Clicking the same work restores the expected model confirmation.
|
|
Parent evidence: `.local/native-qa/delete-20260912/evidence/03-shift-delete-after-undo-no-dialog.png`
|
|
and `04modelconfirmafterclick`.
|
|
|
|
Isolated worktree: `C:/Users/User/Documents/Git/ARCADIA-Studio/.local/delete-undo-focus-20260912`.
|
|
Branch: `codex/delete-undo-focus-956atf-20260912`, baseline `f7d84fa`.
|
|
Reviewed change commit: `7bf57db` (six production/test files; no runtime gate run
|
|
by this worker).
|
|
|
|
## Source diagnosis and change
|
|
|
|
`diagram::focus::Owner::diff` previously revoked keyboard focus whenever any
|
|
`route_edit::Context` field changed. The context includes document revision,
|
|
so accepting a placement removal or Undo/Redo revoked the focus that still
|
|
belonged to the displayed canvas. This is a production defect, unlike the
|
|
earlier retained-Apply evaluator ordering issue.
|
|
|
|
Owner now preserves its existing focused and traversing values across a revision
|
|
change only. It clears pointer history for every changed full context. It still
|
|
revokes focus on document, diagram or canvas epoch change, disabled input, window
|
|
loss/resize, a pointer press outside the canvas, and actual focus operations.
|
|
It never grants focus on a revision change. The inner canvas still receives the
|
|
new full context, and model/confirmation intent validation is unchanged.
|
|
|
|
A second necessary cause is passive Save: `save_to` sets `busy`, while the old
|
|
single enabled flag treated busy like a modal owner transfer. The shared keyboard
|
|
predicate now distinguishes logical owner availability from busy command
|
|
admission, with the previous command predicate behavior unchanged. Architecture
|
|
and state callers pass both owner availability and busy suspension to Owner.
|
|
Save/export suspension retains existing focus but denies keyboard/pointer
|
|
commands and focus acquisition. Explicit unfocus operations, outside clicks and
|
|
window loss still revoke the owner. No App save logic was changed.
|
|
Entering suspension recreates only the wrapped canvas child tree once, retiring
|
|
transient drags that could otherwise miss a release during I/O. Outer keyboard
|
|
focus and App-owned diagram presentation remain intact.
|
|
|
|
`refresh_draft` restores the selected architecture/state placement from the
|
|
preserved semantic selection after Undo; no selection-history rewrite is needed.
|
|
|
|
## Actual mounted regression changes
|
|
|
|
`app/diagram_removal_tests.rs` adds:
|
|
|
|
- OA and SA repeated placement Delete after Undo/Redo, then Shift+Delete without
|
|
another pointer event or explicit focus operation; exact bundle comparisons.
|
|
- Native allocation work click/hide/Undo/Redo/Undo/Shift+Delete sequence with the
|
|
expected work confirmation target and unchanged model/source bundle. Real
|
|
saves are included between history steps; each task is held while the actual
|
|
busy tree receives F2/Shift+Delete, then completed to a temporary source file.
|
|
- Persisted State placement hide/Undo/Shift+Delete, preserving the architecture
|
|
placement and correctly targeting the state.
|
|
- A canvas-versus-Inspector test that starts with actual pointer focus, accepts
|
|
an unrelated rename, traverses Undo/Redo/Undo, checks the real widget operation
|
|
focus witness, and verifies F2 reaches only the canvas. Repeated F2/Delete
|
|
cannot reach the diagram from either Inspector or the newly opened inline name.
|
|
- Actual Inspector click or programmatic field focus during a held Save must
|
|
revoke the retained canvas owner, including after the Save task completes.
|
|
- Passive Save cannot grant focus through either a focus operation or pointer
|
|
press, and cannot restore focus lost to a window Unfocused event while busy.
|
|
- An actual held diagram drag is released while Save is busy; later motion and
|
|
release must not commit that old gesture. A fresh drag must work and Undo must
|
|
restore the exact original source bundle.
|
|
|
|
Existing stale revision/epoch/document/selection intent, confirmation replay,
|
|
modal/window/dirty/modified-key, clean Inspector and Tab tests remain unchanged.
|
|
|
|
## Derived viewport assessment
|
|
|
|
The process/scenario Viewport has analogous revision revocation, but its Scope
|
|
epoch is `camera_epoch`, mixing revisions and keyboard ownership boundaries.
|
|
Passing `canvas_epoch` as a replacement focus lifetime is unsafe: process/scenario
|
|
ordinary pan, zoom, viewport sizing and scroll changes also increment that epoch.
|
|
A separate derived focus-lifetime contract needs a bounded follow-up; this patch
|
|
does not broaden to those views or weaken their current guards.
|
|
|
|
## Verification boundary
|
|
|
|
`git diff --check` passes. This worker has run no Cargo/compiler or native GUI
|
|
commands and made no Gitea changes. Parent owns executable gates and native
|
|
recheck. Fresh Astra/high source review found no issue in the revision-only
|
|
change, then identified a high-priority focus-theft bug in the first busy draft:
|
|
omitting the suspended canvas from focus operations and outside clicks prevented
|
|
Inspector acquisition from revoking retained canvas focus. The current change
|
|
keeps unfocus and outside-click revocation active, denies only acquisition, and
|
|
adds both actual click and operation regressions.
|
|
The same critic then identified the swallowed-release gesture risk described
|
|
above; the child-tree retirement and actual held/fresh drag regression address
|
|
it. The final Astra/high source re-review reports no further findings and judges
|
|
the actual gesture regression meaningful. No executable pass is claimed.
|
|
|
|
Recommended existing root Windows gate filters:
|
|
|
|
- `app::diagram_removal_tests::` (all affected actual-root tests)
|
|
- `app::architecture_authoring::tests::` (inline F2 and ownership dependents)
|
|
|
|
The new test is
|
|
`app::diagram_removal_tests::mounted_revision_and_history_preserve_the_actual_canvas_or_inspector_focus_owner`.
|
|
The original allocation filter remains
|
|
`app::diagram_removal_tests::mounted_allocation_work_click_then_delete_without_redraw_removes_placement_once`.
|