A bulk sketch_add no longer freezes the next gesture

Draw-then-edit is armed from a jump in the entity count: render() sees n > m_autoedit_seen,
selects the last entity and schedules open_primary_autoedit. A scripted add made while a
creation tool was armed looked exactly like a drawn gesture, so it opened that tool's value
field — and an open field freezes the canvas (on_mouse_impl returns early on m_awaiting_length)
and swallows every letter (in_text includes inline_busy()). Measured on the rig: after
sketch_add, 'p' + click added nothing (4 entities before, 4 after); one Escape and the identical
sequence gave 5. It also explains the selection = [last index] that sketch_describe reported
although action_sketch_add never selects anything — the render pass wrote it.

Escape worked because it sequences two set_tool calls: the pending CallAfter fires between them,
so the second one commits the field it finds open. Arming a tool directly is one call, and the
CallAfter fires after it.

Fix: resync m_autoedit_seen at the end of add_entities_scripted, so a scripted add is not read as
something the user just drew. An already-open field is left alone. Covers sketch_add,
sketch_mirror and sketch_offset — the three callers.

The scale rung's Escape workaround is deleted, which is the issue's acceptance criterion; it is
now the regression test. Gesture ladder 93/93 on the rig.

snaporca-j7gc

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MrMzTpAf78U4NG2M8jfvHY
This commit is contained in:
Tommaso Bianchi
2026-08-23 03:00:37 +02:00
co-authored by Claude Opus 5
parent bc1606a4d0
commit 12047e4085
2 changed files with 14 additions and 6 deletions
+5 -6
View File
@@ -1060,12 +1060,11 @@ def rung_scale():
f"every cut-out is exactly {side:.6f} squared")
# Now the part that matters: draw ONE more entity by hand, on top of all that.
#
# The Escape is a WORKAROUND, not decoration: after a bulk sketch_add the next tool key and
# click are swallowed — the preview is drawn, its value field opens, and no entity is ever
# committed — until one Escape has been pressed. It is reachable only by mixing the socket
# into a live gesture session, which is exactly what this rung does. snaporca-j7gc; when that
# is fixed, delete this line and the rung must still pass.
key("Escape", 0.8)
# No Escape here, deliberately: this rung is the regression test for snaporca-j7gc, where a
# bulk sketch_add made while a creation tool is armed was read as a drawn gesture, opened that
# tool's value field and swallowed the next key and click until one Escape dismissed it. The
# gesture below has to land on the FIRST try. Fixed by resyncing m_autoedit_seen in
# add_entities_scripted; if this rung ever needs an Escape again, the bug is back.
key("l", 0.8)
global PACE
PACE = 6.0 # a thousand entities re-solve between fields
+9
View File
@@ -8956,6 +8956,15 @@ int DesignSketchTool::add_entities_scripted(const std::vector<SketchEntity>& ent
// scripted profile closed — a ring's last point IS its first point.
infer_auto_constraints(base, 0.0, 0.0);
resolve_live();
// A scripted add is not a drawn gesture, and draw-then-edit must not fire for it. The render
// pass arms that on a jump in the entity count (see the m_autoedit_seen block in render()),
// so a bulk load made while a creation tool is armed selected the last scripted entity and
// opened that tool's value field — which freezes the canvas (on_mouse_impl returns early
// while m_awaiting_length) and swallows every letter (in_text includes inline_busy()). The
// symptom was that the first key and click after sketch_add did nothing until one Escape had
// dismissed the field. Resyncing the baseline here leaves an ALREADY open field alone; it
// only stops this add from being read as something the user just drew. snaporca-j7gc.
m_autoedit_seen = int(m_entities.size());
return base;
}