From e8db3f577a8939545d0ee1924dc2cdaf22a55a0d Mon Sep 17 00:00:00 2001 From: Tanish Manku Date: Fri, 1 May 2026 04:57:07 -0700 Subject: [PATCH] PageScene: commit panel transform session on mouseup / Enter / Ctrl+Z MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to 72071c0066. The session-based panel transform recording fixed pollution but introduced a new bug: while editing the same object's panel without changing selection, the session never committed, so Ctrl+Z fell through to the most recent prior entry — typically the CreateAction for the shape, which deleted it on undo. Add three document-level commit triggers covering the natural editing boundaries the user expects: - mouseup (any document-level mouseup): catches the end of an InputVector numeric-scrub drag and any click that moves focus elsewhere after typing. - Enter key: explicit "done editing" commit even when the input retains focus. - Ctrl+Z / Ctrl+Y (capture phase): flushes the pending session before the engine's keymap handler runs undo/redo, so the pending edit is what gets reverted instead of the prior entry. Capture phase on the keydown listener is load-bearing: keymap.ts attaches its handler in bubble phase via useViewportKeyboard. Capture fires first, so the session commits before keymap dispatches. mouseup commit is a no-op when no session is open, so attaching it to document doesn't cost anything for unrelated clicks. Color session is unchanged (focus/blur boundaries on the color input still work and don't have this issue). --- .../ControlPanelSceneObject.tsx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/frontend/apps/artcraft/app/src/pages/PageScene/comps/ControlPanelSceneObject/ControlPanelSceneObject.tsx b/frontend/apps/artcraft/app/src/pages/PageScene/comps/ControlPanelSceneObject/ControlPanelSceneObject.tsx index cab0d6c34b..0c630831b8 100644 --- a/frontend/apps/artcraft/app/src/pages/PageScene/comps/ControlPanelSceneObject/ControlPanelSceneObject.tsx +++ b/frontend/apps/artcraft/app/src/pages/PageScene/comps/ControlPanelSceneObject/ControlPanelSceneObject.tsx @@ -172,6 +172,40 @@ export const ControlPanelSceneObject = () => { return () => commitPanelTransform(); }, []); + // Document-level commit triggers for the transform session. These + // are the natural "end of edit gesture" signals — without them, a + // pending session sits open during same-uuid editing and Ctrl+Z + // falls through to a prior entry (often the CreateAction that + // added the shape, so the shape disappears on undo). + // + // - mouseup: end of an InputVector numeric-scrub drag, OR a click + // that moves focus away after typing. + // - Enter: explicit "I'm done" without losing focus. + // - Ctrl+Z / Ctrl+Y / Ctrl+Shift+Z (capture phase): flush before the + // engine's keymap handler runs the undo, so the pending entry is + // the one being reverted. + useEffect(() => { + const flush = () => { + transformSessionRef.current?.commit(); + transformSessionRef.current = null; + }; + const onKeyDown = (e: KeyboardEvent) => { + if (e.key === "Enter") flush(); + if ( + (e.ctrlKey || e.metaKey) && + (e.code === "KeyZ" || e.code === "KeyY") + ) { + flush(); + } + }; + document.addEventListener("mouseup", flush); + document.addEventListener("keydown", onKeyDown, true); + return () => { + document.removeEventListener("mouseup", flush); + document.removeEventListener("keydown", onKeyDown, true); + }; + }, []); + if (!currentSceneObject) { return null; }