From 6b409d8d928d4efda645abebf4ba8ce17120dac4 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 18 Mar 2026 12:22:41 +0100 Subject: [PATCH] :bug: Fix embedded editor pasting text --- .../src/app/main/data/workspace/shapes.cljs | 7 ++- .../data/workspace/text_selrect_callback.cljs | 43 +++++++++++++++++++ frontend/src/app/render_wasm/api.cljs | 16 ++++--- 3 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 frontend/src/app/main/data/workspace/text_selrect_callback.cljs diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 989e85eb38..adcba1d85c 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -25,6 +25,7 @@ [app.main.data.workspace.edition :as dwe] [app.main.data.workspace.selection :as dws] [app.main.data.workspace.undo :as dwu] + [app.main.store :as st] [beicon.v2.core :as rx] [potok.v2.core :as ptk])) @@ -50,7 +51,7 @@ ([ids update-fn] (update-shapes ids update-fn nil)) ([ids update-fn {:keys [reg-objects? save-undo? stack-undo? attrs ignore-tree page-id - ignore-touched undo-group with-objects? changed-sub-attr] + ignore-touched undo-group with-objects? changed-sub-attr ignore-wasm?] :or {reg-objects? false save-undo? true stack-undo? false @@ -97,7 +98,9 @@ (rx/concat (if (seq (:redo-changes changes)) - (let [changes (cond-> changes reg-objects? (pcb/resize-parents ids))] + (let [changes (cond-> changes + reg-objects? (pcb/resize-parents ids) + ignore-wasm? (assoc :ignore-wasm? true))] (rx/of (dch/commit-changes changes))) (rx/empty)) diff --git a/frontend/src/app/main/data/workspace/text_selrect_callback.cljs b/frontend/src/app/main/data/workspace/text_selrect_callback.cljs new file mode 100644 index 0000000000..48e9c6b9c3 --- /dev/null +++ b/frontend/src/app/main/data/workspace/text_selrect_callback.cljs @@ -0,0 +1,43 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.data.workspace.text-selrect-callback + "Event to update text shape selrect from WASM dimensions. + Lives here so app.render-wasm.api can emit it without requiring shapes + (which would create a circular dependency: shapes -> changes -> render-wasm)." + (:require + [app.common.geom.matrix :as gmt] + [app.common.geom.rect :as grc] + [app.common.geom.shapes :as gsh] + [app.main.data.helpers :as dsh] + [app.main.store :as st] + [potok.v2.core :as ptk])) + +(defn update-text-shape-selrect + "Updates a text shape's selrect in the main store from WASM-computed dimensions. + Used when pasting text (no text shape selected) so the selection rect matches + the actual rendered text bounds. Emitted by app.render-wasm.api." + [shape-id dimensions] + (ptk/reify ::update-text-shape-selrect + ptk/UpdateEvent + (update [_ state] + (let [file-id (:current-file-id state) + page-id (:current-page-id state) + objects (dsh/lookup-page-objects state file-id page-id) + shape (get objects shape-id)] + (if (and shape dimensions (:width dimensions) (:height dimensions)) + (let [center (gsh/shape->center shape) + transform (:transform shape (gmt/matrix)) + rect (-> (grc/make-rect dimensions) + (grc/rect->points)) + points (gsh/transform-points rect center transform) + selrect (gsh/calculate-selrect points (gsh/points->center points)) + path [:files file-id :data :pages-index page-id :objects shape-id]] + (update-in state path assoc + :selrect selrect + :points points + :position-data nil)) + state))))) diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs index e4d097cc06..d433a0b3d3 100644 --- a/frontend/src/app/render_wasm/api.cljs +++ b/frontend/src/app/render_wasm/api.cljs @@ -22,6 +22,7 @@ [app.common.types.text :as txt] [app.common.uuid :as uuid] [app.config :as cf] + [app.main.data.workspace.text-selrect-callback :as text-selrect-cb] [app.main.refs :as refs] [app.main.render :as render] [app.main.store :as st] @@ -993,11 +994,16 @@ (defn update-text-rect! [id] (when wasm/context-initialized? - (mw/emit! - {:cmd :index/update-text-rect - :page-id (:current-page-id @st/state) - :shape-id id - :dimensions (get-text-dimensions id)}))) + (let [dimensions (get-text-dimensions id)] + (mw/emit! + {:cmd :index/update-text-rect + :page-id (:current-page-id @st/state) + :shape-id id + :dimensions dimensions}) + ;; Also update the main store so the selrect is correct when pasting text + ;; (no text shape selected). Event lives in text-selrect-callback to avoid + ;; circular dependency (shapes -> changes -> render-wasm). + (st/emit! (text-selrect-cb/update-text-shape-selrect id dimensions))))) (defn- ensure-text-content "Guarantee that the shape always sends a valid text tree to WASM. When the