Browse Source

Merge pull request #79805 from kumikumi/fix-subviewport-cursor

Prevent SubViewportContainer overriding Subviewport's cursor with its own cursor
Yuri Sizov 2 years ago
parent
commit
d50c52652f
3 changed files with 46 additions and 1 deletions
  1. 4 0
      scene/gui/subviewport_container.cpp
  2. 1 1
      scene/main/viewport.cpp
  3. 41 0
      tests/scene/test_viewport.h

+ 4 - 0
scene/gui/subviewport_container.cpp

@@ -267,6 +267,10 @@ PackedStringArray SubViewportContainer::get_configuration_warnings() const {
 		warnings.push_back(RTR("This node doesn't have a SubViewport as child, so it can't display its intended content.\nConsider adding a SubViewport as a child to provide something displayable."));
 		warnings.push_back(RTR("This node doesn't have a SubViewport as child, so it can't display its intended content.\nConsider adding a SubViewport as a child to provide something displayable."));
 	}
 	}
 
 
+	if (get_default_cursor_shape() != Control::CURSOR_ARROW) {
+		warnings.push_back(RTR("The default mouse cursor shape of SubViewportContainer has no effect.\nConsider leaving it at its initial value `CURSOR_ARROW`."));
+	}
+
 	return warnings;
 	return warnings;
 }
 }
 
 

+ 1 - 1
scene/main/viewport.cpp

@@ -2089,7 +2089,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
 			}
 			}
 		}
 		}
 
 
-		if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE)) {
+		if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CURSOR_SHAPE) && !Object::cast_to<SubViewportContainer>(over)) {
 			DisplayServer::get_singleton()->cursor_set_shape(ds_cursor_shape);
 			DisplayServer::get_singleton()->cursor_set_shape(ds_cursor_shape);
 		}
 		}
 	}
 	}

+ 41 - 0
tests/scene/test_viewport.h

@@ -33,6 +33,7 @@
 
 
 #include "scene/2d/node_2d.h"
 #include "scene/2d/node_2d.h"
 #include "scene/gui/control.h"
 #include "scene/gui/control.h"
+#include "scene/gui/subviewport_container.h"
 #include "scene/main/window.h"
 #include "scene/main/window.h"
 
 
 #include "tests/test_macros.h"
 #include "tests/test_macros.h"
@@ -715,6 +716,46 @@ TEST_CASE("[SceneTree][Viewport] Controls and InputEvent handling") {
 	memdelete(node_a);
 	memdelete(node_a);
 }
 }
 
 
+TEST_CASE("[SceneTree][Viewport] Control mouse cursor shape") {
+	SUBCASE("[Viewport][CursorShape] Mouse cursor is not overridden by SubViewportContainer") {
+		SubViewportContainer *node_a = memnew(SubViewportContainer);
+		SubViewport *node_b = memnew(SubViewport);
+		Control *node_c = memnew(Control);
+
+		node_a->set_name("SubViewportContainer");
+		node_b->set_name("SubViewport");
+		node_c->set_name("Control");
+		node_a->set_position(Point2i(0, 0));
+		node_c->set_position(Point2i(0, 0));
+		node_a->set_size(Point2i(100, 100));
+		node_b->set_size(Point2i(100, 100));
+		node_c->set_size(Point2i(100, 100));
+		node_a->set_default_cursor_shape(Control::CURSOR_ARROW);
+		node_c->set_default_cursor_shape(Control::CURSOR_FORBIDDEN);
+		Window *root = SceneTree::get_singleton()->get_root();
+		DisplayServerMock *DS = (DisplayServerMock *)(DisplayServer::get_singleton());
+
+		// Scene tree:
+		// - root
+		//   - node_a (SubViewportContainer)
+		//     - node_b (SubViewport)
+		//       - node_c (Control)
+
+		root->add_child(node_a);
+		node_a->add_child(node_b);
+		node_b->add_child(node_c);
+
+		Point2i on_c = Point2i(5, 5);
+
+		SEND_GUI_MOUSE_MOTION_EVENT(on_c, MouseButtonMask::NONE, Key::NONE);
+		CHECK(DS->get_cursor_shape() == DisplayServer::CURSOR_FORBIDDEN); // GH-74805
+
+		memdelete(node_c);
+		memdelete(node_b);
+		memdelete(node_a);
+	}
+}
+
 } // namespace TestViewport
 } // namespace TestViewport
 
 
 #endif // TEST_VIEWPORT_H
 #endif // TEST_VIEWPORT_H