Files
ARCADIA-Studio/harness/picker-escape-20260923.md
T

75 lines
4.4 KiB
Markdown

# Picker Escape ownership — issue 35
Branch-specific design above `301126f6098286bf440c1bd1b1ed685753984723`.
[Issue 35](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/issues/35)
owns live scope, progress and acceptance. This document records the selected
contract; it does not assert completed implementation, execution or integration.
## Required interaction
An open picker owns Escape: close its popup, request redraw and consume the key.
Publish its optional close notification at most once; do not select an option
or change the surrounding draft, model, source, history, selection or camera.
A later Escape follows the existing surrounding workflow's policy. Reopening,
selection and outside-click dismissal retain their existing behavior. Selection
does not gain a new close callback as an incidental change to this repair.
Event batches matter. A popup already closed by Escape must not select a stale
option or emit another close notification when later queued events reach the
same overlay object. This does not introduce a new global keyboard-repeat policy.
## Decision and evidence
The shared picker and its menu overlay currently omit Escape handling. Adding
widget capture alone is insufficient: application subscriptions translate some
captured Escape events back into modal cancellation. Those bridges also preserve
legitimate cancellation from focused text inputs, so simply removing them loses
existing behavior.
The selected design gives dismissal to the picker overlay and moves the existing
captured-key forwarding into a scoped wrapper around the ordinary application
widget tree. Keep the wrapper structurally present even when inactive, preserve
the existing activation predicates and message priorities, and delegate widget
state, operations, layout and overlays transparently.
The locked Iced 0.14 runtime processes overlays first and skips ordinary root
updates for events captured by an overlay (`user_interface.rs`). Nested overlays
likewise give their deepest child first refusal (`overlay/nested.rs`). Thus the
Escape from an already mounted picker cannot reach ordinary-tree forwarding,
while focused text-input cancellation can retain its previous policy. The runtime
can reuse an overlay across an event batch; close-state checks must cover that
case. Conversely, opening a picker and pressing Escape in the same batch can
reach the ordinary tree before the runtime constructs its overlay. The wrapper
therefore offers the currently available nested overlay first refusal for Escape
before forwarding to ordinary children; the picker also handles base delivery.
An overlay that already ignored Escape may receive this narrow preflight again.
Audited reachable passive overlays perform no selection or draft action; the
source-navigation observer can advance its conservative focus-freshness epoch
again. Regression checks must retain stale-focus rejection and observable state.
Do not generalize this replay to other keyboard or pointer events.
Alternatives rejected: a widget-only patch leaves outer-draft cancellation;
global open-picker bookkeeping duplicates widget state and requires coordinating
every open/select/close/removal path; per-text-input forwarding can work but
spreads the existing policy across many controls. Revisit the wrapper choice if
runtime delivery changes or actual mounted tests contradict these assumptions.
## Acceptance
Use mounted runtime delivery for open/dismiss/reopen/select, optional callbacks,
outside click and same-batch Escape/click sequences. Exercise the real application
subscriptions with returned event status, including focused text cancellation,
architecture editing, behavior drafts and Text workflows. Compare complete model
and source state where dismissal must conserve them; direct helper calls alone
do not establish event ownership.
Native coverage should include the State hidden-element picker and the Add
existing chooser's filter dropdown with a retained query: first Escape dismisses
the picker, then a distinct Escape follows the chooser policy. Behavior creation,
behavior source forms and Text Find/rename currently have no internal dropdown;
picker coexistence there is composed mounted coverage, not a claim of a native
control that does not exist. Verify their ordinary focused-text Escape behavior.
Linux remains user-paused. Shared integration and release acceptance remain with
the integration owner; this branch does not establish combined-release behavior.