diff --git a/CHANGES.md b/CHANGES.md index 1e1d96f2c..7d2e71504 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ - Fix crash on iOS when displaying viewer [#1522](https://github.com/penpot/penpot/issues/1522) - Fix problems with trackpad zoom and scroll in MacOS [#1161](https://github.com/penpot/penpot/issues/1161) +- Fix problem with copy/paste in Safari [#1209](https://github.com/penpot/penpot/issues/1209) ## 1.12.3-beta diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 2fce408fa..bedd0dd4c 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1548,13 +1548,10 @@ [] (letfn [;; Sort objects so they have the same relative ordering ;; when pasted later. - (sort-selected [state data] - (let [selected (:selected data) - page-id (:current-page-id state) - objects (get-in state [:workspace-data - :pages-index - page-id - :objects])] + (sort-selected-async [state data] + (let [selected (wsh/lookup-selected state) + objects (wsh/lookup-page-objects state) + page-id (:current-page-id state)] (->> (uw/ask! {:cmd :selection/query-z-index :page-id page-id :objects objects @@ -1566,6 +1563,24 @@ (map first) (into (d/ordered-set))))))))) + ;; We cannot call to a remote procedure in Safari (for the copy) so we need + ;; to calculate it here instead of on the worker + (sort-selected-sync [state data] + (let [selected (wsh/lookup-selected state) + objects (wsh/lookup-page-objects state) + z-index (cp/calculate-z-index objects) + z-values (->> selected + (map #(vector % + (+ (get z-index %) + (get z-index (get-in objects [% :frame-id])))))) + selected + (->> z-values + (sort-by second) + (map first) + (into (d/ordered-set)))] + + (assoc data :selected selected))) + ;; Retrieve all ids of selected shapes with corresponding ;; children; this is needed because each shape should be ;; processed one by one because of async events (data url @@ -1627,11 +1642,18 @@ :file-id (:current-file-id state) :selected selected :objects {} - :images #{}}] + :images #{}} + + sort-results + (fn [obs] + ;; Safari doesn't allow asynchronous sorting on the copy + (if (cfg/check-browser? :safari) + (rx/map (partial sort-selected-sync state) obs) + (rx/mapcat (partial sort-selected-async state) obs)))] (->> (rx/from (seq (vals pdata))) (rx/merge-map (partial prepare-object objects selected)) (rx/reduce collect-data initial) - (rx/mapcat (partial sort-selected state)) + (sort-results) (rx/map t/encode-str) (rx/map wapi/write-to-clipboard) (rx/catch on-copy-error)