2
0
Эх сурвалжийг харах

fixes to mouse warp

-can warp now from viewport and control, in their respective coordinate
systems
-warp is now local to the window on Windows and OSX.

IF YOU RUN OSX, PLEASE TEST THIS! And make sure it works!, new code is
in OS_OSX::warp_mouse_pos. I don't have OSX so i can't test!
Juan Linietsky 10 жил өмнө
parent
commit
d2f86cc09b

+ 12 - 1
platform/osx/os_osx.mm

@@ -1093,8 +1093,19 @@ void OS_OSX::warp_mouse_pos(const Point2& p_to) {
         mouse_y = p_to.y;
     }
     else{ //set OS position
-        CGPoint lMouseWarpPos = {p_to.x, p_to.y};
         
+	/* this code has not been tested, please be a kind soul and fix it if it fails! */
+
+	//local point in window coords
+	NSPoint localPoint = { p_to.x, p_to.y };
+
+	NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil];
+	NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(CGRect){.origin=pointInWindow}];
+
+	//point in scren coords
+	CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y};
+
+	//do the warping
         CGEventSourceRef lEventRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
         CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0);
         CGAssociateMouseAndMouseCursorPosition(false);

+ 6 - 1
platform/windows/os_windows.cpp

@@ -1432,7 +1432,12 @@ void OS_Windows::warp_mouse_pos(const Point2& p_to) {
 		old_y=p_to.y;
 	} else {
 
-		SetCursorPos(p_to.x, p_to.y);
+		POINT p;
+		p.x=p_to.x;
+		p.y=p_to.y;
+		ClientToScreen(hWnd,&p);
+
+		SetCursorPos(p.x,p.y);
 	}
 
 }

+ 5 - 1
platform/x11/os_x11.cpp

@@ -479,8 +479,12 @@ void OS_X11::warp_mouse_pos(const Point2& p_to) {
 		last_mouse_pos=p_to;
 	} else {
 
+		/*XWindowAttributes xwa;
+		XGetWindowAttributes(x11_display, x11_window, &xwa);
+		printf("%d %d\n", xwa.x, xwa.y); needed? */
+
 		XWarpPointer(x11_display, None, x11_window,
-			      0,0,0,0, (int)p_to.x, (int)p_to.y);
+			      0,0,0,0, (int)p_to.x , (int)p_to.y);
 	}
 
 }

+ 9 - 0
scene/gui/control.cpp

@@ -2688,6 +2688,12 @@ Control *Control::get_focus_owner() const {
 	return data.window->window->key_focus;
 }
 
+
+void Control::warp_mouse(const Point2& p_to_pos) {
+	ERR_FAIL_COND(!is_inside_tree());
+	get_viewport()->warp_mouse(get_global_transform().xform(p_to_pos));
+}
+
 void Control::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("_window_input_event"),&Control::_window_input_event);
@@ -2784,6 +2790,9 @@ void Control::_bind_methods() {
 
 	ObjectTypeDB::bind_method(_MD("set_drag_preview","control:Control"),&Control::set_drag_preview);
 
+	ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"),&Control::warp_mouse);
+
+
 	BIND_VMETHOD(MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event")));
 	BIND_VMETHOD(MethodInfo(Variant::VECTOR2,"get_minimum_size"));
 	BIND_VMETHOD(MethodInfo(Variant::OBJECT,"get_drag_data",PropertyInfo(Variant::VECTOR2,"pos")));

+ 1 - 1
scene/gui/control.h

@@ -380,7 +380,7 @@ public:
 
 	void grab_click_focus();
 
-
+	void warp_mouse(const Point2& p_to_pos);
 
 	Control();	
 	~Control();

+ 9 - 0
scene/main/viewport.cpp

@@ -29,6 +29,8 @@
 #include "viewport.h"
 #include "os/os.h"
 #include "scene/3d/spatial.h"
+#include "os/input.h"
+
 //#include "scene/3d/camera.h"
 
 #include "servers/spatial_sound_server.h"
@@ -1100,6 +1102,12 @@ void Viewport::_vp_unhandled_input(const InputEvent& p_ev) {
 
 }
 
+void Viewport::warp_mouse(const Vector2& p_pos) {
+
+	Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos);
+	Input::get_singleton()->warp_mouse_pos(gpos);
+}
+
 void Viewport::input(const InputEvent& p_event) {
 
 	ERR_FAIL_COND(!is_inside_tree());
@@ -1289,6 +1297,7 @@ void Viewport::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("is_audio_listener_2d","enable"), &Viewport::is_audio_listener_2d);
 	ObjectTypeDB::bind_method(_MD("set_render_target_to_screen_rect"), &Viewport::set_render_target_to_screen_rect);
 
+	ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"), &Viewport::warp_mouse);
 
 	ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"), _SCS("set_rect"), _SCS("get_rect") );
 	ADD_PROPERTY( PropertyInfo(Variant::BOOL,"own_world"), _SCS("set_use_own_world"), _SCS("is_using_own_world") );

+ 2 - 0
scene/main/viewport.h

@@ -246,6 +246,8 @@ public:
 	void set_render_target_to_screen_rect(const Rect2& p_rect);
 	Rect2 get_render_target_to_screen_rect() const;
 
+	void warp_mouse(const Vector2& p_pos);
+
 	void set_physics_object_picking(bool p_enable);
 	bool get_physics_object_picking();