Duplicate: Undo and Redo forget the last Duplicate's move

A shape added after an Undo can get an undone copy's id; duplicating it then
used the move measured from the old original.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Zetenypapp
2026-10-18 19:52:41 +02:00
co-authored by Claude Opus 5.5
parent 8e9c198c7c
commit 86e7879f5e
2 changed files with 9 additions and 0 deletions
+2
View File
@@ -51,6 +51,8 @@ fn restore(s: &mut Session, redo: bool) -> Result<Value> {
st.doc = e.doc;
st.selection = e.selection;
st.interaction = None;
// A later shape can get an undone copy's id: Duplicate starts over with the usual offset.
st.last_duplicate = None;
st.revision += 1;
Ok(json!({"label": e.label}))
}
+7
View File
@@ -4098,6 +4098,13 @@ fn duplicating_a_moved_copy_repeats_the_move() {
s.doc_mut().unwrap().selection.shapes = vec![ShapeId(a as u32)];
let e = dup(&mut s);
assert_eq!(boxed(&mut s, e), (100.0 + off, 100.0 + off));
// Undone, its id can go to a new shape: duplicating that one uses the usual offset too.
s.execute("edit.undo", &json!({})).unwrap();
let r = s.execute("shape.insert", &json!({"preset": "ellipse", "rect": [400, 300, 40, 40]})).unwrap();
let g = r["id"].as_u64().unwrap();
assert_eq!(g, e, "the new shape reuses the undone copy's id");
let h = dup(&mut s);
assert_eq!(boxed(&mut s, h), (400.0 + off, 300.0 + off));
// After Undo removed that copy, duplicating the last moved copy gets the usual offset too.
s.execute("edit.undo", &json!({})).unwrap();
s.doc_mut().unwrap().selection.shapes = vec![ShapeId(d as u32)];