From f5109c7df20df896fb5b5ef14f75295c5d9f1eb7 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 24 Feb 2026 13:38:07 +0100 Subject: [PATCH 1/3] :tada: Refactor caret blinking to reduce CPU usage --- .../app/render_wasm/text_editor_input.cljs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/render_wasm/text_editor_input.cljs b/frontend/src/app/render_wasm/text_editor_input.cljs index f2979b935a..7eced4ab16 100644 --- a/frontend/src/app/render_wasm/text_editor_input.cljs +++ b/frontend/src/app/render_wasm/text_editor_input.cljs @@ -19,6 +19,8 @@ [rumext.v2 :as mf]) (:import goog.events.EventType)) +(def caret-blink-interval-ms 250) + (defn- sync-wasm-text-editor-content! "Sync WASM text editor content back to the shape via the standard commit pipeline. Called after every text-modifying input." @@ -54,18 +56,17 @@ (.focus node)) js/undefined)) - ;; Animation loop for cursor blink (mf/use-effect (fn [] - (let [raf-id (atom nil) - animate (fn animate [] - (when (text-editor/text-editor-is-active?) - (wasm.api/request-render "cursor-blink") - (reset! raf-id (js/requestAnimationFrame animate))))] - (animate) + (let [timeout-id (atom nil) + schedule-blink (fn schedule-blink [] + (when (text-editor/text-editor-is-active?) + (wasm.api/request-render "cursor-blink")) + (reset! timeout-id (js/setTimeout schedule-blink caret-blink-interval-ms)))] + (schedule-blink) (fn [] - (when @raf-id - (js/cancelAnimationFrame @raf-id)))))) + (when @timeout-id + (js/clearTimeout @timeout-id)))))) ;; Document-level keydown handler for control keys (mf/use-effect From 40233e3316da32436cdc0d3a598a95a52e357a27 Mon Sep 17 00:00:00 2001 From: Aitor Moreno Date: Wed, 25 Feb 2026 12:47:07 +0100 Subject: [PATCH 2/3] :bug: Fix text alignment options --- .../text-editor/src/editor/controllers/SelectionController.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/text-editor/src/editor/controllers/SelectionController.js b/frontend/text-editor/src/editor/controllers/SelectionController.js index 683a887203..ba06969893 100644 --- a/frontend/text-editor/src/editor/controllers/SelectionController.js +++ b/frontend/text-editor/src/editor/controllers/SelectionController.js @@ -1958,6 +1958,8 @@ export class SelectionController extends EventTarget { this.startOffset === this.endOffset && this.endOffset === endNode.nodeValue?.length ) { + const paragraph = this.startParagraph; + setParagraphStyles(paragraph, newStyles); const newTextSpan = createVoidTextSpan(newStyles); this.endTextSpan.after(newTextSpan); this.setSelection(newTextSpan.firstChild, 0, newTextSpan.firstChild, 0); From f41eca12f4e5db11b1be1d58c84de4af16d7f280 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Wed, 25 Feb 2026 13:47:40 +0100 Subject: [PATCH 3/3] :bug: Fix problem with frame title movement --- common/src/app/common/types/shape_tree.cljc | 32 +++++++++++-------- .../main/ui/workspace/viewport/widgets.cljs | 2 +- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/common/src/app/common/types/shape_tree.cljc b/common/src/app/common/types/shape_tree.cljc index 20f542fbbe..92732e18a1 100644 --- a/common/src/app/common/types/shape_tree.cljc +++ b/common/src/app/common/types/shape_tree.cljc @@ -115,21 +115,25 @@ (defn get-frames "Retrieves all frame objects as vector" ([objects] (get-frames objects nil)) - ([objects {:keys [skip-components? skip-copies?] + ([objects {:keys [skip-components? skip-copies? ignore-index?] :or {skip-components? false - skip-copies? false}}] - (->> (or (-> objects meta ::index-frames) - (let [lookup (d/getf objects) - xform (comp (remove #(= uuid/zero %)) - (keep lookup) - (filter cfh/frame-shape?))] - (->> (keys objects) - (sequence xform)))) - (remove #(or (and ^boolean skip-components? - ^boolean (ctk/instance-head? %)) - (and ^boolean skip-copies? - (and ^boolean (ctk/instance-head? %) - (not ^boolean (ctk/main-instance? %))))))))) + skip-copies? false + ignore-index? false}}] + (let [frame-index + (if (and (not ignore-index?) (-> objects meta ::index-frames)) + (-> objects meta ::index-frames) + (let [lookup (d/getf objects) + xform (comp (remove #(= uuid/zero %)) + (keep lookup) + (filter cfh/frame-shape?))] + (->> (keys objects) + (sequence xform))))] + (->> frame-index + (remove #(or (and ^boolean skip-components? + ^boolean (ctk/instance-head? %)) + (and ^boolean skip-copies? + (and ^boolean (ctk/instance-head? %) + (not ^boolean (ctk/main-instance? %)))))))))) (defn get-frames-ids "Retrieves all frame ids as vector" diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index 9d101982a7..f3dd84ca4e 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -242,7 +242,7 @@ [{:keys [objects zoom selected focus is-show-artboard-names on-frame-enter on-frame-leave on-frame-select]}] (let [selected (or selected #{}) - shapes (ctt/get-frames objects {:skip-copies? true}) + shapes (ctt/get-frames objects {:skip-copies? true :ignore-index? true}) shapes (if (dbg/enabled? :shape-titles) (into (set shapes) (map (d/getf objects))