Repository: flxzt/rnote (language: rust)

Issue:
Pasted content always appears in the top-left corner instead of at the cursor position
When pasting content (such as an image, text, or other elements) into the whiteboard, the pasted item consistently appears in the top-left corner of the document page. This behaviour can be unintuitive and disrupts the workflow, as users must manually reposition the content after pasting.

It would be more user-friendly for pasted content to appear at the location of the cursor, which aligns with user expectations in many other applications.


Discussion / hints:
Which method of pasting content are you referring to? with keyboard `ctrl-v` ?
> Which method of pasting content are you referring to? with keyboard `ctrl-v` ?

Yes
yess i also get this. Is there meant to be another method of pasting since I cant seem to right click int he document


Fix patch:
diff --git a/crates/rnote-ui/src/appwindow/actions.rs b/crates/rnote-ui/src/appwindow/actions.rs
index 8fdf17f621..6501b0b55d 100644
--- a/crates/rnote-ui/src/appwindow/actions.rs
+++ b/crates/rnote-ui/src/appwindow/actions.rs
@@ -11,6 +11,7 @@ use p2d::bounding_volume::BoundingVolume;
 use rnote_compose::penevent::ShortcutKey;
 use rnote_compose::SplitOrder;
 use rnote_engine::engine::StrokeContent;
+use rnote_engine::ext::GraphenePointExt;
 use rnote_engine::pens::PenStyle;
 use rnote_engine::strokes::resize::{ImageSizeOption, Resize};
 use rnote_engine::{Camera, Engine};
@@ -1083,7 +1084,33 @@ impl RnAppWindow {
             #[weak(rename_to=appwindow)]
             self,
             move |_, _| {
-                appwindow.clipboard_paste(None);
+                let Some(wrapper) = appwindow.active_tab_wrapper() else {
+                    return;
+                };
+                let canvas = wrapper.canvas();
+
+                let pointer_pos = wrapper.pointer_pos().and_then(|wrapper_point| {
+                    let canvas_point = wrapper
+                        .compute_point(&canvas, &graphene::Point::from_na_vec(wrapper_point));
+
+                    if let Some(point) = canvas_point {
+                        let x = point.x() as f64;
+                        let y = point.y() as f64;
+
+                        if canvas.contains(x, y) {
+                            let transformed_point =
+                                (canvas.engine_ref().camera.transform().inverse()
+                                    * na::point![x, y])
+                                .coords;
+
+                            return Some(transformed_point);
+                        }
+                    }
+
+                    return None;
+                });
+
+                appwindow.clipboard_paste(pointer_pos);
             }
         ));
 
diff --git a/crates/rnote-ui/src/canvaswrapper.rs b/crates/rnote-ui/src/canvaswrapper.rs
index e27f2229ff..224a1edb6d 100644
--- a/crates/rnote-ui/src/canvaswrapper.rs
+++ b/crates/rnote-ui/src/canvaswrapper.rs
@@ -807,6 +807,10 @@ impl RnCanvasWrapper {
         self.set_property("inertial-scrolling", inertial_scrolling);
     }
 
+    pub(crate) fn pointer_pos(&self) -> Option<na::Vector2<f64>> {
+        self.imp().pointer_pos.get()
+    }
+
     pub(crate) fn last_contextmenu_pos(&self) -> Option<na::Vector2<f64>> {
         self.imp().last_contextmenu_pos.get()
     }


Test patch: