From 12047e4085ad71eacab4075094124b525629b05c Mon Sep 17 00:00:00 2001 From: Tommaso Bianchi Date: Sun, 23 Aug 2026 03:00:37 +0200 Subject: [PATCH] A bulk sketch_add no longer freezes the next gesture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) Claude-Session: https://claude.ai/code/session_01MrMzTpAf78U4NG2M8jfvHY --- scripts/gui-ladder.py | 11 +++++------ src/slic3r/GUI/CAD/DesignSketchTool.cpp | 9 +++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/scripts/gui-ladder.py b/scripts/gui-ladder.py index 05227a24df..bac00a72c4 100644 --- a/scripts/gui-ladder.py +++ b/scripts/gui-ladder.py @@ -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 diff --git a/src/slic3r/GUI/CAD/DesignSketchTool.cpp b/src/slic3r/GUI/CAD/DesignSketchTool.cpp index 6193c8e7a9..2ded2ad4d2 100644 --- a/src/slic3r/GUI/CAD/DesignSketchTool.cpp +++ b/src/slic3r/GUI/CAD/DesignSketchTool.cpp @@ -8956,6 +8956,15 @@ int DesignSketchTool::add_entities_scripted(const std::vector& 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; }