openpencil/crates
Kayshen-X 33ee2f37ed refactor(shell): split web widget_host + harden layer-drag lifecycle
Three codex broad-review findings:

BLOCK — `openpencil-shell-web/src/widget_host.rs` was 886 lines
(over the 800 cap). Extracted `apply_press` + `apply_click`
(~301 lines combined) into a new sibling
`crates/openpencil-shell-web/src/widget_host/press.rs`,
mirroring the native split pattern. Spine drops to 590 lines.
Explicit `use super::{ChatDragState, DragState, LayerDragState,
MarqueeDragState, rect_contains, WidgetHost}` so the type
references inside the moved methods stay readable (Rust resolves
them via descendant module privacy, but the imports document
the dependency).

CONCERN — Stale `layer_drag` could outlive its dragged node if
the document mutated mid-drag (delete / cut / page switch).
Added a source-validity guard at three sites per host (native
+ web parity):
- `apply_cursor_move`: clears `layer_drag` if
  `active_page().find(d.source)` returns None.
- Both paint passes: suppress the drop-indicator when the
  source is no longer in the active page.
- `commit_layer_drag` already silently no-ops on missing
  source via the existing `reorder_before/after` guards.

CONCERN — Missing host-level end-to-end test for the drag-to-
reorder gesture. Added two tests in
`openpencil-shell-native/src/widget_host/input_tests.rs`:
- `layer_drag_to_reorder_commits_on_release_with_threshold_move`
  — full press → 4-px-threshold move → release; asserts the
  tree was reordered and `layer_drag` is cleared.
- `layer_drag_below_activation_threshold_is_a_click_not_a_reorder`
  — sub-threshold move; asserts click semantics (selection
  set, tree unchanged).

Verification:
- cargo test --workspace: all green (184+ tests).
- cargo fmt --all --check: clean.
- bash tools/check-widget-boundary.sh: PASS.
- find / awk file-size scan: zero files over 800 lines.
2026-05-12 02:18:01 +08:00
..
openpencil-app feat(openpencil-app): skeleton crate (Stage F entry placeholder) 2026-05-03 22:05:00 +08:00
openpencil-desktop feat(shell): selection handles + drag-create + per-node flags + LayerPanel polish 2026-05-11 21:30:06 +08:00
openpencil-shell-core fix(shell-core): drag-to-reorder drop-at-end + threshold doc 2026-05-11 22:14:38 +08:00
openpencil-shell-native refactor(shell): split web widget_host + harden layer-drag lifecycle 2026-05-12 02:18:01 +08:00
openpencil-shell-web refactor(shell): split web widget_host + harden layer-drag lifecycle 2026-05-12 02:18:01 +08:00
pen-codegen chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-core chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-engine chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-figma chore(workspace): cargo-deny 0.18 activation (Phase 1 Task 1.8 Step 6) 2026-05-03 23:05:00 +08:00
pen-types feat(pen-types): skeleton crate (bucket A) 2026-05-03 22:35:00 +08:00
wasm-libc-shim style(shell): cargo fmt --all (rustfmt-clean) 2026-05-10 18:47:33 +08:00
CLAUDE.md docs(shell): note document.rs directory split in crates/CLAUDE.md 2026-05-11 21:42:44 +08:00