Browse Source

Merge pull request #67507 from Sauermann/fix-toplevel-root-control-node

Fix event propagation to child after set_as_toplevel
Rémi Verschelde 2 years ago
parent
commit
4cfdd25384
4 changed files with 29 additions and 0 deletions
  1. 6 0
      scene/gui/control.cpp
  2. 3 0
      scene/gui/control.h
  3. 17 0
      scene/main/canvas_item.cpp
  4. 3 0
      scene/main/canvas_item.h

+ 6 - 0
scene/gui/control.cpp

@@ -692,6 +692,12 @@ Transform2D Control::get_transform() const {
 	return xform;
 }
 
+void Control::_toplevel_changed_on_parent() {
+	// Update root control status.
+	_notification(NOTIFICATION_EXIT_CANVAS);
+	_notification(NOTIFICATION_ENTER_CANVAS);
+}
+
 /// Anchors and offsets.
 
 void Control::_set_anchor(Side p_side, real_t p_anchor) {

+ 3 - 0
scene/gui/control.h

@@ -292,6 +292,9 @@ private:
 	void _update_minimum_size();
 	void _size_changed();
 
+	void _toplevel_changed() override{}; // Controls don't need to do anything, only other CanvasItems.
+	void _toplevel_changed_on_parent() override;
+
 	void _clear_size_warning();
 
 	// Input events.

+ 17 - 0
scene/main/canvas_item.cpp

@@ -400,11 +400,28 @@ void CanvasItem::set_as_top_level(bool p_top_level) {
 
 	_exit_canvas();
 	top_level = p_top_level;
+	_toplevel_changed();
 	_enter_canvas();
 
 	_notify_transform();
 }
 
+void CanvasItem::_toplevel_changed() {
+	// Inform children that toplevel status has changed on a parent.
+	int childs = get_child_count();
+	for (int i = 0; i < childs; i++) {
+		CanvasItem *child = Object::cast_to<CanvasItem>(get_child(i));
+		if (child) {
+			child->_toplevel_changed_on_parent();
+		}
+	}
+}
+
+void CanvasItem::_toplevel_changed_on_parent() {
+	// Inform children that toplevel status has changed on a parent.
+	_toplevel_changed();
+}
+
 bool CanvasItem::is_set_as_top_level() const {
 	return top_level;
 }

+ 3 - 0
scene/main/canvas_item.h

@@ -125,6 +125,9 @@ private:
 	void _propagate_visibility_changed(bool p_parent_visible_in_tree);
 	void _handle_visibility_change(bool p_visible);
 
+	virtual void _toplevel_changed();
+	virtual void _toplevel_changed_on_parent();
+
 	void _redraw_callback();
 
 	void _enter_canvas();