Browse Source

Merge pull request #82800 from Sauermann/fix-screen-mousemotion

Add screen-related attributes to mouse input events
Rémi Verschelde 1 year ago
parent
commit
74b03edf1e

+ 20 - 4
core/input/input.cpp

@@ -130,6 +130,7 @@ void Input::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
 	ClassDB::bind_method(D_METHOD("set_magnetometer", "value"), &Input::set_magnetometer);
 	ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
 	ClassDB::bind_method(D_METHOD("set_gyroscope", "value"), &Input::set_gyroscope);
 	ClassDB::bind_method(D_METHOD("get_last_mouse_velocity"), &Input::get_last_mouse_velocity);
 	ClassDB::bind_method(D_METHOD("get_last_mouse_velocity"), &Input::get_last_mouse_velocity);
+	ClassDB::bind_method(D_METHOD("get_last_mouse_screen_velocity"), &Input::get_last_mouse_screen_velocity);
 	ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
 	ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
 	ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode);
 	ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode);
 	ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode);
 	ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode);
@@ -201,7 +202,7 @@ void Input::get_argument_options(const StringName &p_function, int p_idx, List<S
 	Object::get_argument_options(p_function, p_idx, r_options);
 	Object::get_argument_options(p_function, p_idx, r_options);
 }
 }
 
 
-void Input::VelocityTrack::update(const Vector2 &p_delta_p) {
+void Input::VelocityTrack::update(const Vector2 &p_delta_p, const Vector2 &p_screen_delta_p) {
 	uint64_t tick = OS::get_singleton()->get_ticks_usec();
 	uint64_t tick = OS::get_singleton()->get_ticks_usec();
 	uint32_t tdiff = tick - last_tick;
 	uint32_t tdiff = tick - last_tick;
 	float delta_t = tdiff / 1000000.0;
 	float delta_t = tdiff / 1000000.0;
@@ -210,12 +211,15 @@ void Input::VelocityTrack::update(const Vector2 &p_delta_p) {
 	if (delta_t > max_ref_frame) {
 	if (delta_t > max_ref_frame) {
 		// First movement in a long time, reset and start again.
 		// First movement in a long time, reset and start again.
 		velocity = Vector2();
 		velocity = Vector2();
+		screen_velocity = Vector2();
 		accum = p_delta_p;
 		accum = p_delta_p;
+		screen_accum = p_screen_delta_p;
 		accum_t = 0;
 		accum_t = 0;
 		return;
 		return;
 	}
 	}
 
 
 	accum += p_delta_p;
 	accum += p_delta_p;
+	screen_accum += p_screen_delta_p;
 	accum_t += delta_t;
 	accum_t += delta_t;
 
 
 	if (accum_t < min_ref_frame) {
 	if (accum_t < min_ref_frame) {
@@ -224,6 +228,7 @@ void Input::VelocityTrack::update(const Vector2 &p_delta_p) {
 	}
 	}
 
 
 	velocity = accum / accum_t;
 	velocity = accum / accum_t;
+	screen_velocity = screen_accum / accum_t;
 	accum = Vector2();
 	accum = Vector2();
 	accum_t = 0;
 	accum_t = 0;
 }
 }
@@ -594,7 +599,8 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 			set_mouse_position(position);
 			set_mouse_position(position);
 		}
 		}
 		Vector2 relative = mm->get_relative();
 		Vector2 relative = mm->get_relative();
-		mouse_velocity_track.update(relative);
+		Vector2 screen_relative = mm->get_relative_screen_position();
+		mouse_velocity_track.update(relative, screen_relative);
 
 
 		if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
 		if (event_dispatch_function && emulate_touch_from_mouse && !p_is_emulated && mm->get_button_mask().has_flag(MouseButtonMask::LEFT)) {
 			Ref<InputEventScreenDrag> drag_event;
 			Ref<InputEventScreenDrag> drag_event;
@@ -602,10 +608,12 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 
 
 			drag_event->set_position(position);
 			drag_event->set_position(position);
 			drag_event->set_relative(relative);
 			drag_event->set_relative(relative);
+			drag_event->set_relative_screen_position(screen_relative);
 			drag_event->set_tilt(mm->get_tilt());
 			drag_event->set_tilt(mm->get_tilt());
 			drag_event->set_pen_inverted(mm->get_pen_inverted());
 			drag_event->set_pen_inverted(mm->get_pen_inverted());
 			drag_event->set_pressure(mm->get_pressure());
 			drag_event->set_pressure(mm->get_pressure());
 			drag_event->set_velocity(get_last_mouse_velocity());
 			drag_event->set_velocity(get_last_mouse_velocity());
+			drag_event->set_screen_velocity(get_last_mouse_screen_velocity());
 			drag_event->set_device(InputEvent::DEVICE_ID_EMULATION);
 			drag_event->set_device(InputEvent::DEVICE_ID_EMULATION);
 
 
 			_THREAD_SAFE_UNLOCK_
 			_THREAD_SAFE_UNLOCK_
@@ -669,8 +677,9 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 
 
 	if (sd.is_valid()) {
 	if (sd.is_valid()) {
 		VelocityTrack &track = touch_velocity_track[sd->get_index()];
 		VelocityTrack &track = touch_velocity_track[sd->get_index()];
-		track.update(sd->get_relative());
+		track.update(sd->get_relative(), sd->get_relative_screen_position());
 		sd->set_velocity(track.velocity);
 		sd->set_velocity(track.velocity);
+		sd->set_screen_velocity(track.screen_velocity);
 
 
 		if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) {
 		if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) {
 			Ref<InputEventMouseMotion> motion_event;
 			Ref<InputEventMouseMotion> motion_event;
@@ -683,7 +692,9 @@ void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_em
 			motion_event->set_position(sd->get_position());
 			motion_event->set_position(sd->get_position());
 			motion_event->set_global_position(sd->get_position());
 			motion_event->set_global_position(sd->get_position());
 			motion_event->set_relative(sd->get_relative());
 			motion_event->set_relative(sd->get_relative());
+			motion_event->set_relative_screen_position(sd->get_relative_screen_position());
 			motion_event->set_velocity(sd->get_velocity());
 			motion_event->set_velocity(sd->get_velocity());
+			motion_event->set_screen_velocity(sd->get_screen_velocity());
 			motion_event->set_button_mask(mouse_button_mask);
 			motion_event->set_button_mask(mouse_button_mask);
 
 
 			_parse_input_event_impl(motion_event, true);
 			_parse_input_event_impl(motion_event, true);
@@ -827,10 +838,15 @@ Point2 Input::get_mouse_position() const {
 }
 }
 
 
 Point2 Input::get_last_mouse_velocity() {
 Point2 Input::get_last_mouse_velocity() {
-	mouse_velocity_track.update(Vector2());
+	mouse_velocity_track.update(Vector2(), Vector2());
 	return mouse_velocity_track.velocity;
 	return mouse_velocity_track.velocity;
 }
 }
 
 
+Point2 Input::get_last_mouse_screen_velocity() {
+	mouse_velocity_track.update(Vector2(), Vector2());
+	return mouse_velocity_track.screen_velocity;
+}
+
 BitField<MouseButtonMask> Input::get_mouse_button_mask() const {
 BitField<MouseButtonMask> Input::get_mouse_button_mask() const {
 	return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
 	return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
 }
 }

+ 4 - 1
core/input/input.h

@@ -145,12 +145,14 @@ private:
 	struct VelocityTrack {
 	struct VelocityTrack {
 		uint64_t last_tick = 0;
 		uint64_t last_tick = 0;
 		Vector2 velocity;
 		Vector2 velocity;
+		Vector2 screen_velocity;
 		Vector2 accum;
 		Vector2 accum;
+		Vector2 screen_accum;
 		float accum_t = 0.0f;
 		float accum_t = 0.0f;
 		float min_ref_frame;
 		float min_ref_frame;
 		float max_ref_frame;
 		float max_ref_frame;
 
 
-		void update(const Vector2 &p_delta_p);
+		void update(const Vector2 &p_delta_p, const Vector2 &p_screen_delta_p);
 		void reset();
 		void reset();
 		VelocityTrack();
 		VelocityTrack();
 	};
 	};
@@ -302,6 +304,7 @@ public:
 
 
 	Point2 get_mouse_position() const;
 	Point2 get_mouse_position() const;
 	Vector2 get_last_mouse_velocity();
 	Vector2 get_last_mouse_velocity();
+	Vector2 get_last_mouse_screen_velocity();
 	BitField<MouseButtonMask> get_mouse_button_mask() const;
 	BitField<MouseButtonMask> get_mouse_button_mask() const;
 
 
 	void warp_mouse(const Vector2 &p_position);
 	void warp_mouse(const Vector2 &p_position);

+ 56 - 0
core/input/input_event.cpp

@@ -927,6 +927,14 @@ Vector2 InputEventMouseMotion::get_relative() const {
 	return relative;
 	return relative;
 }
 }
 
 
+void InputEventMouseMotion::set_relative_screen_position(const Vector2 &p_relative) {
+	screen_relative = p_relative;
+}
+
+Vector2 InputEventMouseMotion::get_relative_screen_position() const {
+	return screen_relative;
+}
+
 void InputEventMouseMotion::set_velocity(const Vector2 &p_velocity) {
 void InputEventMouseMotion::set_velocity(const Vector2 &p_velocity) {
 	velocity = p_velocity;
 	velocity = p_velocity;
 }
 }
@@ -935,6 +943,14 @@ Vector2 InputEventMouseMotion::get_velocity() const {
 	return velocity;
 	return velocity;
 }
 }
 
 
+void InputEventMouseMotion::set_screen_velocity(const Vector2 &p_velocity) {
+	screen_velocity = p_velocity;
+}
+
+Vector2 InputEventMouseMotion::get_screen_velocity() const {
+	return screen_velocity;
+}
+
 Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
 Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
 	Ref<InputEventMouseMotion> mm;
 	Ref<InputEventMouseMotion> mm;
 	mm.instantiate();
 	mm.instantiate();
@@ -952,7 +968,9 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
 
 
 	mm->set_button_mask(get_button_mask());
 	mm->set_button_mask(get_button_mask());
 	mm->set_relative(p_xform.basis_xform(get_relative()));
 	mm->set_relative(p_xform.basis_xform(get_relative()));
+	mm->set_relative_screen_position(get_relative_screen_position());
 	mm->set_velocity(p_xform.basis_xform(get_velocity()));
 	mm->set_velocity(p_xform.basis_xform(get_velocity()));
+	mm->set_screen_velocity(get_screen_velocity());
 
 
 	return mm;
 	return mm;
 }
 }
@@ -1027,7 +1045,9 @@ bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
 	set_position(motion->get_position());
 	set_position(motion->get_position());
 	set_global_position(motion->get_global_position());
 	set_global_position(motion->get_global_position());
 	set_velocity(motion->get_velocity());
 	set_velocity(motion->get_velocity());
+	set_screen_velocity(motion->get_screen_velocity());
 	relative += motion->get_relative();
 	relative += motion->get_relative();
+	screen_relative += motion->get_relative_screen_position();
 
 
 	return true;
 	return true;
 }
 }
@@ -1045,14 +1065,22 @@ void InputEventMouseMotion::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
 	ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
 	ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
 	ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
 
 
+	ClassDB::bind_method(D_METHOD("set_screen_relative", "relative"), &InputEventMouseMotion::set_relative_screen_position);
+	ClassDB::bind_method(D_METHOD("get_screen_relative"), &InputEventMouseMotion::get_relative_screen_position);
+
 	ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventMouseMotion::set_velocity);
 	ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventMouseMotion::set_velocity);
 	ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventMouseMotion::get_velocity);
 	ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventMouseMotion::get_velocity);
 
 
+	ClassDB::bind_method(D_METHOD("set_screen_velocity", "velocity"), &InputEventMouseMotion::set_screen_velocity);
+	ClassDB::bind_method(D_METHOD("get_screen_velocity"), &InputEventMouseMotion::get_screen_velocity);
+
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative", PROPERTY_HINT_NONE, "suffix:px"), "set_relative", "get_relative");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative", PROPERTY_HINT_NONE, "suffix:px"), "set_relative", "get_relative");
+	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "screen_relative", PROPERTY_HINT_NONE, "suffix:px"), "set_screen_relative", "get_screen_relative");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_velocity", "get_velocity");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_velocity", "get_velocity");
+	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "screen_velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_screen_velocity", "get_screen_velocity");
 }
 }
 
 
 ///////////////////////////////////
 ///////////////////////////////////
@@ -1422,6 +1450,14 @@ Vector2 InputEventScreenDrag::get_relative() const {
 	return relative;
 	return relative;
 }
 }
 
 
+void InputEventScreenDrag::set_relative_screen_position(const Vector2 &p_relative) {
+	screen_relative = p_relative;
+}
+
+Vector2 InputEventScreenDrag::get_relative_screen_position() const {
+	return screen_relative;
+}
+
 void InputEventScreenDrag::set_velocity(const Vector2 &p_velocity) {
 void InputEventScreenDrag::set_velocity(const Vector2 &p_velocity) {
 	velocity = p_velocity;
 	velocity = p_velocity;
 }
 }
@@ -1430,6 +1466,14 @@ Vector2 InputEventScreenDrag::get_velocity() const {
 	return velocity;
 	return velocity;
 }
 }
 
 
+void InputEventScreenDrag::set_screen_velocity(const Vector2 &p_velocity) {
+	screen_velocity = p_velocity;
+}
+
+Vector2 InputEventScreenDrag::get_screen_velocity() const {
+	return screen_velocity;
+}
+
 Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
 Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
 	Ref<InputEventScreenDrag> sd;
 	Ref<InputEventScreenDrag> sd;
 
 
@@ -1444,7 +1488,9 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con
 	sd->set_tilt(get_tilt());
 	sd->set_tilt(get_tilt());
 	sd->set_position(p_xform.xform(pos + p_local_ofs));
 	sd->set_position(p_xform.xform(pos + p_local_ofs));
 	sd->set_relative(p_xform.basis_xform(relative));
 	sd->set_relative(p_xform.basis_xform(relative));
+	sd->set_relative_screen_position(get_relative_screen_position());
 	sd->set_velocity(p_xform.basis_xform(velocity));
 	sd->set_velocity(p_xform.basis_xform(velocity));
+	sd->set_screen_velocity(get_screen_velocity());
 
 
 	return sd;
 	return sd;
 }
 }
@@ -1469,7 +1515,9 @@ bool InputEventScreenDrag::accumulate(const Ref<InputEvent> &p_event) {
 
 
 	set_position(drag->get_position());
 	set_position(drag->get_position());
 	set_velocity(drag->get_velocity());
 	set_velocity(drag->get_velocity());
+	set_screen_velocity(drag->get_screen_velocity());
 	relative += drag->get_relative();
 	relative += drag->get_relative();
+	screen_relative += drag->get_relative_screen_position();
 
 
 	return true;
 	return true;
 }
 }
@@ -1493,16 +1541,24 @@ void InputEventScreenDrag::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventScreenDrag::set_relative);
 	ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventScreenDrag::set_relative);
 	ClassDB::bind_method(D_METHOD("get_relative"), &InputEventScreenDrag::get_relative);
 	ClassDB::bind_method(D_METHOD("get_relative"), &InputEventScreenDrag::get_relative);
 
 
+	ClassDB::bind_method(D_METHOD("set_screen_relative", "relative"), &InputEventScreenDrag::set_relative_screen_position);
+	ClassDB::bind_method(D_METHOD("get_screen_relative"), &InputEventScreenDrag::get_relative_screen_position);
+
 	ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventScreenDrag::set_velocity);
 	ClassDB::bind_method(D_METHOD("set_velocity", "velocity"), &InputEventScreenDrag::set_velocity);
 	ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventScreenDrag::get_velocity);
 	ClassDB::bind_method(D_METHOD("get_velocity"), &InputEventScreenDrag::get_velocity);
 
 
+	ClassDB::bind_method(D_METHOD("set_screen_velocity", "velocity"), &InputEventScreenDrag::set_screen_velocity);
+	ClassDB::bind_method(D_METHOD("get_screen_velocity"), &InputEventScreenDrag::get_screen_velocity);
+
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "tilt"), "set_tilt", "get_tilt");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
 	ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "pressure"), "set_pressure", "get_pressure");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pen_inverted"), "set_pen_inverted", "get_pen_inverted");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_NONE, "suffix:px"), "set_position", "get_position");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position", PROPERTY_HINT_NONE, "suffix:px"), "set_position", "get_position");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative", PROPERTY_HINT_NONE, "suffix:px"), "set_relative", "get_relative");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative", PROPERTY_HINT_NONE, "suffix:px"), "set_relative", "get_relative");
+	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "screen_relative", PROPERTY_HINT_NONE, "suffix:px"), "set_screen_relative", "get_screen_relative");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_velocity", "get_velocity");
 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_velocity", "get_velocity");
+	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "screen_velocity", PROPERTY_HINT_NONE, "suffix:px/s"), "set_screen_velocity", "get_screen_velocity");
 }
 }
 
 
 ///////////////////////////////////
 ///////////////////////////////////

+ 16 - 0
core/input/input_event.h

@@ -271,7 +271,9 @@ class InputEventMouseMotion : public InputEventMouse {
 	Vector2 tilt;
 	Vector2 tilt;
 	float pressure = 0;
 	float pressure = 0;
 	Vector2 relative;
 	Vector2 relative;
+	Vector2 screen_relative;
 	Vector2 velocity;
 	Vector2 velocity;
+	Vector2 screen_velocity;
 	bool pen_inverted = false;
 	bool pen_inverted = false;
 
 
 protected:
 protected:
@@ -290,9 +292,15 @@ public:
 	void set_relative(const Vector2 &p_relative);
 	void set_relative(const Vector2 &p_relative);
 	Vector2 get_relative() const;
 	Vector2 get_relative() const;
 
 
+	void set_relative_screen_position(const Vector2 &p_relative);
+	Vector2 get_relative_screen_position() const;
+
 	void set_velocity(const Vector2 &p_velocity);
 	void set_velocity(const Vector2 &p_velocity);
 	Vector2 get_velocity() const;
 	Vector2 get_velocity() const;
 
 
+	void set_screen_velocity(const Vector2 &p_velocity);
+	Vector2 get_screen_velocity() const;
+
 	virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
 	virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
 	virtual String as_text() const override;
 	virtual String as_text() const override;
 	virtual String to_string() override;
 	virtual String to_string() override;
@@ -393,7 +401,9 @@ class InputEventScreenDrag : public InputEventFromWindow {
 	int index = 0;
 	int index = 0;
 	Vector2 pos;
 	Vector2 pos;
 	Vector2 relative;
 	Vector2 relative;
+	Vector2 screen_relative;
 	Vector2 velocity;
 	Vector2 velocity;
+	Vector2 screen_velocity;
 	Vector2 tilt;
 	Vector2 tilt;
 	float pressure = 0;
 	float pressure = 0;
 	bool pen_inverted = false;
 	bool pen_inverted = false;
@@ -420,9 +430,15 @@ public:
 	void set_relative(const Vector2 &p_relative);
 	void set_relative(const Vector2 &p_relative);
 	Vector2 get_relative() const;
 	Vector2 get_relative() const;
 
 
+	void set_relative_screen_position(const Vector2 &p_relative);
+	Vector2 get_relative_screen_position() const;
+
 	void set_velocity(const Vector2 &p_velocity);
 	void set_velocity(const Vector2 &p_velocity);
 	Vector2 get_velocity() const;
 	Vector2 get_velocity() const;
 
 
+	void set_screen_velocity(const Vector2 &p_velocity);
+	Vector2 get_screen_velocity() const;
+
 	virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
 	virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const override;
 	virtual String as_text() const override;
 	virtual String as_text() const override;
 	virtual String to_string() override;
 	virtual String to_string() override;

+ 6 - 0
doc/classes/Input.xml

@@ -156,6 +156,12 @@
 				Returns the strength of the joypad vibration: x is the strength of the weak motor, and y is the strength of the strong motor.
 				Returns the strength of the joypad vibration: x is the strength of the weak motor, and y is the strength of the strong motor.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="get_last_mouse_screen_velocity">
+			<return type="Vector2" />
+			<description>
+				Returns the last mouse velocity in screen coordinates. To provide a precise and jitter-free velocity, mouse velocity is only calculated every 0.1s. Therefore, mouse velocity will lag mouse movements.
+			</description>
+		</method>
 		<method name="get_last_mouse_velocity">
 		<method name="get_last_mouse_velocity">
 			<return type="Vector2" />
 			<return type="Vector2" />
 			<description>
 			<description>

+ 9 - 0
doc/classes/InputEventMouseMotion.xml

@@ -23,12 +23,21 @@
 		<member name="relative" type="Vector2" setter="set_relative" getter="get_relative" default="Vector2(0, 0)">
 		<member name="relative" type="Vector2" setter="set_relative" getter="get_relative" default="Vector2(0, 0)">
 			The mouse position relative to the previous position (position at the last frame).
 			The mouse position relative to the previous position (position at the last frame).
 			[b]Note:[/b] Since [InputEventMouseMotion] is only emitted when the mouse moves, the last event won't have a relative position of [code]Vector2(0, 0)[/code] when the user stops moving the mouse.
 			[b]Note:[/b] Since [InputEventMouseMotion] is only emitted when the mouse moves, the last event won't have a relative position of [code]Vector2(0, 0)[/code] when the user stops moving the mouse.
+			[b]Note:[/b] [member relative] is automatically scaled according to the content scale factor, which is defined by the project's stretch mode settings. This means mouse sensitivity will appear different depending on resolution when using [member relative] in a script that handles mouse aiming with the [constant Input.MOUSE_MODE_CAPTURED] mouse mode. To avoid this, use [member screen_relative] instead.
+		</member>
+		<member name="screen_relative" type="Vector2" setter="set_screen_relative" getter="get_screen_relative" default="Vector2(0, 0)">
+			The unscaled mouse position relative to the previous position in the coordinate system of the screen (position at the last frame).
+			[b]Note:[/b] Since [InputEventMouseMotion] is only emitted when the mouse moves, the last event won't have a relative position of [code]Vector2(0, 0)[/code] when the user stops moving the mouse. This coordinate is [i]not[/i] scaled according to the content scale factor or calls to [method InputEvent.xformed_by]. This should be preferred over [member relative] for mouse aiming when using the [constant Input.MOUSE_MODE_CAPTURED] mouse mode, regardless of the project's stretch mode.
+		</member>
+		<member name="screen_velocity" type="Vector2" setter="set_screen_velocity" getter="get_screen_velocity" default="Vector2(0, 0)">
+			The unscaled mouse velocity in pixels per second in screen coordinates. This velocity is [i]not[/i] scaled according to the content scale factor or calls to [method InputEvent.xformed_by]. This should be preferred over [member velocity] for mouse aiming when using the [constant Input.MOUSE_MODE_CAPTURED] mouse mode, regardless of the project's stretch mode.
 		</member>
 		</member>
 		<member name="tilt" type="Vector2" setter="set_tilt" getter="get_tilt" default="Vector2(0, 0)">
 		<member name="tilt" type="Vector2" setter="set_tilt" getter="get_tilt" default="Vector2(0, 0)">
 			Represents the angles of tilt of the pen. Positive X-coordinate value indicates a tilt to the right. Positive Y-coordinate value indicates a tilt toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both axes.
 			Represents the angles of tilt of the pen. Positive X-coordinate value indicates a tilt to the right. Positive Y-coordinate value indicates a tilt toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both axes.
 		</member>
 		</member>
 		<member name="velocity" type="Vector2" setter="set_velocity" getter="get_velocity" default="Vector2(0, 0)">
 		<member name="velocity" type="Vector2" setter="set_velocity" getter="get_velocity" default="Vector2(0, 0)">
 			The mouse velocity in pixels per second.
 			The mouse velocity in pixels per second.
+			[b]Note:[/b] [member velocity] is automatically scaled according to the content scale factor, which is defined by the project's stretch mode settings. This means mouse sensitivity will appear different depending on resolution when using [member velocity] in a script that handles mouse aiming with the [constant Input.MOUSE_MODE_CAPTURED] mouse mode. To avoid this, use [member screen_velocity] instead.
 		</member>
 		</member>
 	</members>
 	</members>
 </class>
 </class>

+ 8 - 0
doc/classes/InputEventScreenDrag.xml

@@ -24,12 +24,20 @@
 		</member>
 		</member>
 		<member name="relative" type="Vector2" setter="set_relative" getter="get_relative" default="Vector2(0, 0)">
 		<member name="relative" type="Vector2" setter="set_relative" getter="get_relative" default="Vector2(0, 0)">
 			The drag position relative to the previous position (position at the last frame).
 			The drag position relative to the previous position (position at the last frame).
+			[b]Note:[/b] [member relative] is automatically scaled according to the content scale factor, which is defined by the project's stretch mode settings. This means touch sensitivity will appear different depending on resolution when using [member relative] in a script that handles touch aiming. To avoid this, use [member screen_relative] instead.
+		</member>
+		<member name="screen_relative" type="Vector2" setter="set_screen_relative" getter="get_screen_relative" default="Vector2(0, 0)">
+			The unscaled drag position relative to the previous position in screen coordinates (position at the last frame). This position is [i]not[/i] scaled according to the content scale factor or calls to [method InputEvent.xformed_by]. This should be preferred over [member relative] for touch aiming regardless of the project's stretch mode.
+		</member>
+		<member name="screen_velocity" type="Vector2" setter="set_screen_velocity" getter="get_screen_velocity" default="Vector2(0, 0)">
+			The unscaled drag velocity in pixels per second in screen coordinates. This velocity is [i]not[/i] scaled according to the content scale factor or calls to [method InputEvent.xformed_by]. This should be preferred over [member velocity] for touch aiming regardless of the project's stretch mode.
 		</member>
 		</member>
 		<member name="tilt" type="Vector2" setter="set_tilt" getter="get_tilt" default="Vector2(0, 0)">
 		<member name="tilt" type="Vector2" setter="set_tilt" getter="get_tilt" default="Vector2(0, 0)">
 			Represents the angles of tilt of the pen. Positive X-coordinate value indicates a tilt to the right. Positive Y-coordinate value indicates a tilt toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both axes.
 			Represents the angles of tilt of the pen. Positive X-coordinate value indicates a tilt to the right. Positive Y-coordinate value indicates a tilt toward the user. Ranges from [code]-1.0[/code] to [code]1.0[/code] for both axes.
 		</member>
 		</member>
 		<member name="velocity" type="Vector2" setter="set_velocity" getter="get_velocity" default="Vector2(0, 0)">
 		<member name="velocity" type="Vector2" setter="set_velocity" getter="get_velocity" default="Vector2(0, 0)">
 			The drag velocity.
 			The drag velocity.
+			[b]Note:[/b] [member velocity] is automatically scaled according to the content scale factor, which is defined by the project's stretch mode settings. This means touch sensitivity will appear different depending on resolution when using [member velocity] in a script that handles touch aiming. To avoid this, use [member screen_velocity] instead.
 		</member>
 		</member>
 	</members>
 	</members>
 </class>
 </class>

+ 1 - 0
modules/webxr/webxr_interface_js.cpp

@@ -675,6 +675,7 @@ void WebXRInterfaceJS::_update_input_source(int p_input_source_id) {
 					event->set_index(touch_index);
 					event->set_index(touch_index);
 					event->set_position(position);
 					event->set_position(position);
 					event->set_relative(delta);
 					event->set_relative(delta);
+					event->set_relative_screen_position(delta);
 					Input::get_singleton()->parse_input_event(event);
 					Input::get_singleton()->parse_input_event(event);
 				}
 				}
 			}
 			}

+ 4 - 0
platform/android/android_input_handler.cpp

@@ -207,6 +207,7 @@ void AndroidInputHandler::process_touch_event(int p_event, int p_pointer, const
 				ev->set_index(touch[i].id);
 				ev->set_index(touch[i].id);
 				ev->set_position(p_points[idx].pos);
 				ev->set_position(p_points[idx].pos);
 				ev->set_relative(p_points[idx].pos - touch[i].pos);
 				ev->set_relative(p_points[idx].pos - touch[i].pos);
+				ev->set_relative_screen_position(ev->get_relative());
 				Input::get_singleton()->parse_input_event(ev);
 				Input::get_singleton()->parse_input_event(ev);
 				touch.write[i].pos = p_points[idx].pos;
 				touch.write[i].pos = p_points[idx].pos;
 			}
 			}
@@ -306,6 +307,7 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an
 			ev->set_position(p_event_pos);
 			ev->set_position(p_event_pos);
 			ev->set_global_position(p_event_pos);
 			ev->set_global_position(p_event_pos);
 			ev->set_relative(p_event_pos - hover_prev_pos);
 			ev->set_relative(p_event_pos - hover_prev_pos);
+			ev->set_relative_screen_position(ev->get_relative());
 			Input::get_singleton()->parse_input_event(ev);
 			Input::get_singleton()->parse_input_event(ev);
 			hover_prev_pos = p_event_pos;
 			hover_prev_pos = p_event_pos;
 		} break;
 		} break;
@@ -342,10 +344,12 @@ void AndroidInputHandler::process_mouse_event(int p_event_action, int p_event_an
 				ev->set_position(hover_prev_pos);
 				ev->set_position(hover_prev_pos);
 				ev->set_global_position(hover_prev_pos);
 				ev->set_global_position(hover_prev_pos);
 				ev->set_relative(p_event_pos);
 				ev->set_relative(p_event_pos);
+				ev->set_relative_screen_position(p_event_pos);
 			} else {
 			} else {
 				ev->set_position(p_event_pos);
 				ev->set_position(p_event_pos);
 				ev->set_global_position(p_event_pos);
 				ev->set_global_position(p_event_pos);
 				ev->set_relative(p_event_pos - hover_prev_pos);
 				ev->set_relative(p_event_pos - hover_prev_pos);
+				ev->set_relative_screen_position(ev->get_relative());
 				mouse_event_info.pos = p_event_pos;
 				mouse_event_info.pos = p_event_pos;
 				hover_prev_pos = p_event_pos;
 				hover_prev_pos = p_event_pos;
 			}
 			}

+ 1 - 0
platform/ios/display_server_ios.mm

@@ -236,6 +236,7 @@ void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x
 	ev->set_tilt(p_tilt);
 	ev->set_tilt(p_tilt);
 	ev->set_position(Vector2(p_x, p_y));
 	ev->set_position(Vector2(p_x, p_y));
 	ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
 	ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
+	ev->set_relative_screen_position(ev->get_relative());
 	perform_event(ev);
 	perform_event(ev);
 }
 }
 
 

+ 4 - 0
platform/linuxbsd/wayland/wayland_thread.cpp

@@ -1514,6 +1514,8 @@ void WaylandThread::_wl_pointer_on_frame(void *data, struct wl_pointer *wl_point
 			mm->set_relative(pd.position - old_pd.position);
 			mm->set_relative(pd.position - old_pd.position);
 			mm->set_velocity((Vector2)pos_delta / time_delta);
 			mm->set_velocity((Vector2)pos_delta / time_delta);
 		}
 		}
+		mm->set_relative_screen_position(mm->get_relative());
+		mm->set_screen_velocity(mm->get_velocity());
 
 
 		Ref<InputEventMessage> msg;
 		Ref<InputEventMessage> msg;
 		msg.instantiate();
 		msg.instantiate();
@@ -2411,11 +2413,13 @@ void WaylandThread::_wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_
 		mm->set_pen_inverted(td.is_eraser);
 		mm->set_pen_inverted(td.is_eraser);
 
 
 		mm->set_relative(td.position - old_td.position);
 		mm->set_relative(td.position - old_td.position);
+		mm->set_relative_screen_position(mm->get_relative());
 
 
 		// FIXME: Stop doing this to calculate speed.
 		// FIXME: Stop doing this to calculate speed.
 		// FIXME2: It has been done, port this from the pointer logic once this works again.
 		// FIXME2: It has been done, port this from the pointer logic once this works again.
 		Input::get_singleton()->set_mouse_position(td.position);
 		Input::get_singleton()->set_mouse_position(td.position);
 		mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
 		mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
+		mm->set_screen_velocity(mm->get_velocity());
 
 
 		Ref<InputEventMessage> inputev_msg;
 		Ref<InputEventMessage> inputev_msg;
 		inputev_msg.instantiate();
 		inputev_msg.instantiate();

+ 3 - 0
platform/linuxbsd/x11/display_server_x11.cpp

@@ -4524,6 +4524,7 @@ void DisplayServerX11::process_events() {
 							sd->set_index(index);
 							sd->set_index(index);
 							sd->set_position(pos);
 							sd->set_position(pos);
 							sd->set_relative(pos - curr_pos_elem->value);
 							sd->set_relative(pos - curr_pos_elem->value);
+							sd->set_relative_screen_position(sd->get_relative());
 							Input::get_singleton()->parse_input_event(sd);
 							Input::get_singleton()->parse_input_event(sd);
 
 
 							curr_pos_elem->value = pos;
 							curr_pos_elem->value = pos;
@@ -4945,8 +4946,10 @@ void DisplayServerX11::process_events() {
 				mm->set_position(pos);
 				mm->set_position(pos);
 				mm->set_global_position(pos);
 				mm->set_global_position(pos);
 				mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
 				mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
+				mm->set_screen_velocity(mm->get_velocity());
 
 
 				mm->set_relative(rel);
 				mm->set_relative(rel);
+				mm->set_relative_screen_position(rel);
 
 
 				last_mouse_pos = pos;
 				last_mouse_pos = pos;
 
 

+ 2 - 0
platform/macos/godot_content_view.mm

@@ -448,8 +448,10 @@
 	}
 	}
 	mm->set_global_position(wd.mouse_pos);
 	mm->set_global_position(wd.mouse_pos);
 	mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
 	mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
+	mm->set_screen_velocity(mm->get_velocity());
 	const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * ds->screen_get_max_scale();
 	const Vector2i relativeMotion = Vector2i(delta.x, delta.y) * ds->screen_get_max_scale();
 	mm->set_relative(relativeMotion);
 	mm->set_relative(relativeMotion);
+	mm->set_relative_screen_position(relativeMotion);
 	ds->get_key_modifier_state([event modifierFlags], mm);
 	ds->get_key_modifier_state([event modifierFlags], mm);
 
 
 	Input::get_singleton()->parse_input_event(mm);
 	Input::get_singleton()->parse_input_event(mm);

+ 3 - 0
platform/web/display_server_web.cpp

@@ -328,7 +328,9 @@ void DisplayServerWeb::_mouse_move_callback(double p_x, double p_y, double p_rel
 	ev->set_global_position(pos);
 	ev->set_global_position(pos);
 
 
 	ev->set_relative(Vector2(p_rel_x, p_rel_y));
 	ev->set_relative(Vector2(p_rel_x, p_rel_y));
+	ev->set_relative_screen_position(ev->get_relative());
 	ev->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
 	ev->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
+	ev->set_screen_velocity(ev->get_velocity());
 
 
 	Input::get_singleton()->parse_input_event(ev);
 	Input::get_singleton()->parse_input_event(ev);
 }
 }
@@ -707,6 +709,7 @@ void DisplayServerWeb::_touch_callback(int p_type, int p_count) {
 
 
 			Point2 &prev = ds->touches[i];
 			Point2 &prev = ds->touches[i];
 			ev->set_relative(ev->get_position() - prev);
 			ev->set_relative(ev->get_position() - prev);
+			ev->set_relative_screen_position(ev->get_relative());
 			prev = ev->get_position();
 			prev = ev->get_position();
 
 
 			Input::get_singleton()->parse_input_event(ev);
 			Input::get_singleton()->parse_input_event(ev);

+ 9 - 0
platform/windows/display_server_windows.cpp

@@ -2913,6 +2913,7 @@ void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y,
 	event->set_index(idx);
 	event->set_index(idx);
 	event->set_position(Vector2(p_x, p_y));
 	event->set_position(Vector2(p_x, p_y));
 	event->set_relative(Vector2(p_x, p_y) - curr->get());
 	event->set_relative(Vector2(p_x, p_y) - curr->get());
+	event->set_relative_screen_position(event->get_relative());
 
 
 	Input::get_singleton()->parse_input_event(event);
 	Input::get_singleton()->parse_input_event(event);
 
 
@@ -3425,6 +3426,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 				mm->set_position(c);
 				mm->set_position(c);
 				mm->set_global_position(c);
 				mm->set_global_position(c);
 				mm->set_velocity(Vector2(0, 0));
 				mm->set_velocity(Vector2(0, 0));
+				mm->set_screen_velocity(Vector2(0, 0));
 
 
 				if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) {
 				if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) {
 					mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY));
 					mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY));
@@ -3449,6 +3451,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 					old_x = coords.x;
 					old_x = coords.x;
 					old_y = coords.y;
 					old_y = coords.y;
 				}
 				}
+				mm->set_relative_screen_position(mm->get_relative());
 
 
 				if ((windows[window_id].window_has_focus || windows[window_id].is_popup) && mm->get_relative() != Vector2()) {
 				if ((windows[window_id].window_has_focus || windows[window_id].is_popup) && mm->get_relative() != Vector2()) {
 					Input::get_singleton()->parse_input_event(mm);
 					Input::get_singleton()->parse_input_event(mm);
@@ -3536,6 +3539,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 					}
 					}
 
 
 					mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
 					mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
+					mm->set_screen_velocity(mm->get_velocity());
 
 
 					if (old_invalid) {
 					if (old_invalid) {
 						old_x = mm->get_position().x;
 						old_x = mm->get_position().x;
@@ -3544,6 +3548,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 					}
 					}
 
 
 					mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
 					mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
+					mm->set_relative_screen_position(mm->get_relative());
 					old_x = mm->get_position().x;
 					old_x = mm->get_position().x;
 					old_y = mm->get_position().y;
 					old_y = mm->get_position().y;
 					if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
 					if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
@@ -3683,6 +3688,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 			}
 			}
 
 
 			mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
 			mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
+			mm->set_screen_velocity(mm->get_velocity());
 
 
 			if (old_invalid) {
 			if (old_invalid) {
 				old_x = mm->get_position().x;
 				old_x = mm->get_position().x;
@@ -3691,6 +3697,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 			}
 			}
 
 
 			mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
 			mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
+			mm->set_relative_screen_position(mm->get_relative());
 			old_x = mm->get_position().x;
 			old_x = mm->get_position().x;
 			old_y = mm->get_position().y;
 			old_y = mm->get_position().y;
 			if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
 			if (windows[window_id].window_has_focus || window_get_active_popup() == window_id) {
@@ -3802,6 +3809,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 			}
 			}
 
 
 			mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
 			mm->set_velocity(Input::get_singleton()->get_last_mouse_velocity());
+			mm->set_screen_velocity(mm->get_velocity());
 
 
 			if (old_invalid) {
 			if (old_invalid) {
 				old_x = mm->get_position().x;
 				old_x = mm->get_position().x;
@@ -3810,6 +3818,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
 			}
 			}
 
 
 			mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
 			mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
+			mm->set_relative_screen_position(mm->get_relative());
 			old_x = mm->get_position().x;
 			old_x = mm->get_position().x;
 			old_y = mm->get_position().y;
 			old_y = mm->get_position().y;