diff --git a/crates/engine/src/canvas/tools/draw.rs b/crates/engine/src/canvas/tools/draw.rs index b594ae273..69c62ef9a 100644 --- a/crates/engine/src/canvas/tools/draw.rs +++ b/crates/engine/src/canvas/tools/draw.rs @@ -98,6 +98,10 @@ impl Session { } pub(super) fn up(&mut self, ev: &PointerEvent) -> Result<()> { + // Alt went down or up since the last move: the drop is a copy or a move as the release has it. + if matches!(&self.tool.gesture, Gesture::Move { moved: true, duplicate, .. } if *duplicate != ev.alt) { + self.drag(ev)?; + } let g = std::mem::take(&mut self.tool.gesture); self.tool.overlay.marquee = None; self.tool.overlay.guides.clear(); diff --git a/crates/engine/src/duplicate_spacing_tests.rs b/crates/engine/src/duplicate_spacing_tests.rs index 817681b9a..c46ab05c8 100644 --- a/crates/engine/src/duplicate_spacing_tests.rs +++ b/crates/engine/src/duplicate_spacing_tests.rs @@ -212,6 +212,13 @@ fn alt_pressed_during_a_drag_turns_the_move_into_a_copy() { s.undo().unwrap(); drag_alt_when(&mut s, (50.0, 50.0), (250.0, 52.0), |k| k == 1 || k >= 4); assert_eq!((layers(&s), at(&s, a)), (2, (0.0, 0.0))); + // Alt changed only by the release (no move in between): the release decides. + s.undo().unwrap(); + drag_alt_when(&mut s, (50.0, 50.0), (250.0, 52.0), |k| k == 5); + assert_eq!((layers(&s), at(&s, a), last_step(&s).as_str()), (2, (0.0, 0.0), "Duplicate"), "Alt down at the release: a copy"); + s.undo().unwrap(); + drag_alt_when(&mut s, (50.0, 50.0), (250.0, 52.0), |k| k < 5); + assert_eq!((layers(&s), at(&s, a), last_step(&s).as_str()), (1, (200.0, 2.0), "Move"), "Alt up at the release: a move"); } /// The reported path (#567): Cmd+D, drag the copy with the mouse, Cmd+D again. The other tests