Explorar o código

Fix scene reload crash caused by mouse cursor update

After a scene reload a mouse cursor updates is performed via a
InputEventMouseMotion, that is exposed to the user.
The state of Input is however not adjusted to this InputEventMouseMotion
which can lead to inconsistencies.
This PR makes sure, that it is not exposed to the user.
It utilizes the method of Viewport::_process_picking for marking
events that are not sent to the user, so that this function doesn't
need to be changed.
Markus Sauermann %!s(int64=2) %!d(string=hai) anos
pai
achega
5bb66d3cfb
Modificáronse 3 ficheiros con 24 adicións e 9 borrados
  1. 9 4
      scene/gui/control.cpp
  2. 12 4
      scene/main/node.cpp
  3. 3 1
      scene/main/window.cpp

+ 9 - 4
scene/gui/control.cpp

@@ -1735,13 +1735,18 @@ real_t Control::get_stretch_ratio() const {
 // Input events.
 
 void Control::_call_gui_input(const Ref<InputEvent> &p_event) {
-	emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); //signal should be first, so it's possible to override an event (and then accept it)
+	if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+		emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); // Signal should be first, so it's possible to override an event (and then accept it).
+	}
 	if (!is_inside_tree() || get_viewport()->is_input_handled()) {
-		return; //input was handled, abort
+		return; // Input was handled, abort.
+	}
+
+	if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+		GDVIRTUAL_CALL(_gui_input, p_event);
 	}
-	GDVIRTUAL_CALL(_gui_input, p_event);
 	if (!is_inside_tree() || get_viewport()->is_input_handled()) {
-		return; //input was handled, abort
+		return; // Input was handled, abort.
 	}
 	gui_input(p_event);
 }

+ 12 - 4
scene/main/node.cpp

@@ -2764,7 +2764,9 @@ void Node::request_ready() {
 }
 
 void Node::_call_input(const Ref<InputEvent> &p_event) {
-	GDVIRTUAL_CALL(_input, p_event);
+	if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+		GDVIRTUAL_CALL(_input, p_event);
+	}
 	if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
 		return;
 	}
@@ -2772,7 +2774,9 @@ void Node::_call_input(const Ref<InputEvent> &p_event) {
 }
 
 void Node::_call_shortcut_input(const Ref<InputEvent> &p_event) {
-	GDVIRTUAL_CALL(_shortcut_input, p_event);
+	if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+		GDVIRTUAL_CALL(_shortcut_input, p_event);
+	}
 	if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
 		return;
 	}
@@ -2780,7 +2784,9 @@ void Node::_call_shortcut_input(const Ref<InputEvent> &p_event) {
 }
 
 void Node::_call_unhandled_input(const Ref<InputEvent> &p_event) {
-	GDVIRTUAL_CALL(_unhandled_input, p_event);
+	if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+		GDVIRTUAL_CALL(_unhandled_input, p_event);
+	}
 	if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
 		return;
 	}
@@ -2788,7 +2794,9 @@ void Node::_call_unhandled_input(const Ref<InputEvent> &p_event) {
 }
 
 void Node::_call_unhandled_key_input(const Ref<InputEvent> &p_event) {
-	GDVIRTUAL_CALL(_unhandled_key_input, p_event);
+	if (p_event->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+		GDVIRTUAL_CALL(_unhandled_key_input, p_event);
+	}
 	if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
 		return;
 	}

+ 3 - 1
scene/main/window.cpp

@@ -1360,7 +1360,9 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
 		}
 	}
 
-	emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
+	if (p_ev->get_device() != InputEvent::DEVICE_ID_INTERNAL) {
+		emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
+	}
 
 	push_input(p_ev);
 	if (!is_input_handled()) {