summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorMarkus Sauermann <6299227+Sauermann@users.noreply.github.com>2022-10-16 19:41:42 +0200
committerMarkus Sauermann <6299227+Sauermann@users.noreply.github.com>2022-10-16 21:42:16 +0200
commit13b87c13c7de36e5258ff16500ae15a9a9041525 (patch)
treebe1b3bca5705b243459a39ea845b1a159993480b /scene
parent3a59c833f1b7e34ddef57522800288a0dee8562d (diff)
Fix set_as_toplevel event propagation to child
In certain conditions events did not get propagated to Control childs of Node2D nodes when setting a parent of the Node2D to toplevel. This patch makes sure that such Control nodes become root control in the viewport.
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/control.cpp6
-rw-r--r--scene/gui/control.h3
-rw-r--r--scene/main/canvas_item.cpp17
-rw-r--r--scene/main/canvas_item.h3
4 files changed, 29 insertions, 0 deletions
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 565e450d60..0e4a6ab0e4 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -679,6 +679,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) {
diff --git a/scene/gui/control.h b/scene/gui/control.h
index e526690cbe..97b5c54d18 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -288,6 +288,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.
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 05d86f77f2..c4bf56c16f 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -401,11 +401,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;
}
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index b80289fdb4..e4470e0bd9 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -110,6 +110,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();