diff --git a/.serena/memories/common/component-data-model.md b/.serena/memories/common/component-data-model.md index 326965701d..9b9c4cbbc3 100644 --- a/.serena/memories/common/component-data-model.md +++ b/.serena/memories/common/component-data-model.md @@ -78,3 +78,6 @@ component. If the old position supplied rotation or flips that differ from that component's expected parent placement, the new nested copy needs a geometry-group override. Otherwise a later sync discards the orientation that update-main just pushed (F168). The source copy clears its overrides. +Compare against the parent's pushed frame: the inverse sync has already +written its new rotation, while the original container still has the old +one. Using that old frame creates phantom geometry overrides (F172). diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index 4816bf7b0d..6f066313fd 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -777,13 +777,23 @@ (ctf/find-content-ref-shape nil container libraries child-inst :include-deleted? true :with-context? true)) + ;; The parent's inverse sync already pushed its geometry. Compare + ;; against that frame, rather than its original container value. + placement-container + (cond-> main-container + content-main + (assoc-in [:objects (:id parent-main)] + (-> (ctn/get-shape container (:parent-id child-inst)) + (reposition-shape root-inst root-main) + (assoc :id (:id parent-main) + :shape-ref (:shape-ref parent-main))))) update-new-shape (fn [new-shape original-shape] (cond-> (reposition-shape new-shape root-inst root-main) (and (= (:id original-shape) (:id child-inst)) (ctk/swapped? child-inst) (not swap-in-copy?)) - (rehead-pushed-swap content-main main-container))) + (rehead-pushed-swap content-main placement-container))) ;; the copy now follows the main, swap included update-original-shape (fn [original-shape new-shape] diff --git a/common/test/common_tests/logic/swap_group_test.cljc b/common/test/common_tests/logic/swap_group_test.cljc index 8682181ae0..7a5b46a607 100644 --- a/common/test/common_tests/logic/swap_group_test.cljc +++ b/common/test/common_tests/logic/swap_group_test.cljc @@ -917,3 +917,19 @@ (:points (ths/get-shape-by-id full (:id head))) 0.001)) (t/is (= (thn/normalize-file (tm/file swapped)) (thn/normalize-file (tm/file (r/step updated (n/undo))))))))) + +(t/deftest pushing-a-swap-uses-the-parents-updated-orientation + (let [swapped (-> (tm/make-situation (setup-sized)) + (r/step (n/swap-shape :copy-star :heart)) r/settle + (r/step (n/rotate :copy 45)) r/settle) + updated (-> swapped (r/step (n/update-main :copy)) r/settle) + file (tm/file updated) + head (tm/resolve-shape updated :copy-star) + main (tm/shape-by-id updated (:shape-ref head)) + full (:file (r/sync-cascade file {} (keys (get-in file [:data :components]))))] + (t/is (empty? (:touched main))) + (t/is (mth/close? 45 (:rotation main) 0.001)) + (t/is (gsh/close-attrs? :points (:points head) + (:points (ths/get-shape-by-id full (:id head))) 0.001)) + (t/is (= (thn/normalize-file (tm/file swapped)) + (thn/normalize-file (tm/file (r/step updated (n/undo))))))))