From a4a86acb64a38fd5c0031656c3d3ca2d2ae6ac55 Mon Sep 17 00:00:00 2001 From: Igor Zinken <730069+igorski@users.noreply.github.com> Date: Sat, 25 Apr 2026 10:45:46 +0200 Subject: [PATCH] Fix issue where drag-to-cut-selection action would move the original Layer on long async operations --- src/model/actions/layer-drag-start.ts | 11 +++++++---- .../model/actions/layer-drag-start.spec.ts | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/model/actions/layer-drag-start.ts b/src/model/actions/layer-drag-start.ts index 9009433..d8a76b7 100644 --- a/src/model/actions/layer-drag-start.ts +++ b/src/model/actions/layer-drag-start.ts @@ -54,6 +54,10 @@ export function startLayerDrag( store: Store, layer: Layer, x: const orgSelection = clone( activeDocument.activeSelection ); const selectionBoundingBox = selectionToRectangle( orgSelection ); + if ( isPointerDrag ) { + pointerUp( renderer, x, y ); + } + copySelection( activeDocument, layer ) .then( selectionContent => { const bitmapWithoutSelection = deleteSelectionContent( activeDocument, layer ); @@ -77,19 +81,18 @@ export function startLayerDrag( store: Store, layer: Layer, x: renderer?.resetFilterAndRecache(); }; - const commit = (): void => { + const commit = ( maintainDrag = false ): void => { replaceSource( bitmapWithoutSelection ); store.commit( "insertLayerAtIndex", { index: insertIndex, layer: newLayer }); queueMicrotask(() => { store.commit( "setActiveSelection", [] ); - if ( isPointerDrag ) { - pointerUp( renderer, x, y ); + if ( isPointerDrag && maintainDrag ) { pointerDown( getRendererForLayer( newLayer ), x, y ); } }); }; - commit(); + commit( true ); enqueueState( `startLayerDrag_${layer.id}`, { undo(): void { diff --git a/tests/unit/model/actions/layer-drag-start.spec.ts b/tests/unit/model/actions/layer-drag-start.spec.ts index 7b685d4..fbcbdc6 100644 --- a/tests/unit/model/actions/layer-drag-start.spec.ts +++ b/tests/unit/model/actions/layer-drag-start.spec.ts @@ -268,5 +268,24 @@ describe( "layer drag start action", () => { expect( mockPointerUp ).not.toHaveBeenCalled(); }); }); + + describe( "and redo-ing the action", () => { + it( "should not invoke the pointer down event on the recreated Layer", async () => { + startLayerDrag( store, layer, 10, 10, true ); + + await flushPromises(); + + const { undo, redo } = mockEnqueueState.mock.calls[ 0 ][ 1 ]; + + undo(); + vi.resetAllMocks(); + + redo(); + + await flushPromises(); + + expect( mockPointerDown ).not.toHaveBeenCalled(); + }); + }); }); }); \ No newline at end of file