summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/multiplayer_api.cpp2
-rw-r--r--scene/main/node.cpp14
-rw-r--r--scene/main/scene_tree.cpp21
-rw-r--r--scene/main/scene_tree.h2
-rw-r--r--scene/main/viewport.cpp86
-rw-r--r--scene/main/viewport.h1
-rw-r--r--scene/main/window.cpp2
7 files changed, 71 insertions, 57 deletions
diff --git a/scene/main/multiplayer_api.cpp b/scene/main/multiplayer_api.cpp
index 946929aa89..8b4b98c172 100644
--- a/scene/main/multiplayer_api.cpp
+++ b/scene/main/multiplayer_api.cpp
@@ -39,7 +39,7 @@
#include "core/os/os.h"
#endif
-StringName MultiplayerAPI::default_interface = StringName();
+StringName MultiplayerAPI::default_interface;
void MultiplayerAPI::set_default_interface(const StringName &p_interface) {
ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_interface, MultiplayerAPI::get_class_static()), vformat("Can't make %s the default multiplayer interface since it does not extend MultiplayerAPI.", p_interface));
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 304504a82e..5dd0911694 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1759,11 +1759,11 @@ void Node::add_to_group(const StringName &p_identifier, bool p_persistent) {
}
void Node::remove_from_group(const StringName &p_identifier) {
- ERR_FAIL_COND(!data.grouped.has(p_identifier));
-
HashMap<StringName, GroupData>::Iterator E = data.grouped.find(p_identifier);
- ERR_FAIL_COND(!E);
+ if (!E) {
+ return;
+ }
if (data.tree) {
data.tree->remove_from_group(E->key, this);
@@ -2581,10 +2581,14 @@ void Node::print_orphan_nodes() {
}
void Node::queue_free() {
+ // There are users which instantiate multiple scene trees for their games.
+ // Use the node's own tree to handle its deletion when relevant.
if (is_inside_tree()) {
get_tree()->queue_delete(this);
} else {
- SceneTree::get_singleton()->queue_delete(this);
+ SceneTree *tree = SceneTree::get_singleton();
+ ERR_FAIL_NULL_MSG(tree, "Can't queue free a node when no SceneTree is available.");
+ tree->queue_delete(this);
}
}
@@ -2652,7 +2656,7 @@ PackedStringArray Node::get_configuration_warnings() const {
String Node::get_configuration_warnings_as_string() const {
PackedStringArray warnings = get_configuration_warnings();
- String all_warnings = String();
+ String all_warnings;
for (int i = 0; i < warnings.size(); i++) {
if (i > 0) {
all_warnings += "\n\n";
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 41eefe0f85..81a4e3073b 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -123,6 +123,9 @@ void SceneTree::tree_changed() {
void SceneTree::node_added(Node *p_node) {
emit_signal(node_added_name, p_node);
+ if (call_lock > 0) {
+ call_skip.erase(p_node->get_instance_id());
+ }
}
void SceneTree::node_removed(Node *p_node) {
@@ -131,7 +134,7 @@ void SceneTree::node_removed(Node *p_node) {
}
emit_signal(node_removed_name, p_node);
if (call_lock > 0) {
- call_skip.insert(p_node);
+ call_skip.insert(p_node->get_instance_id());
}
}
@@ -261,7 +264,7 @@ void SceneTree::call_group_flagsp(uint32_t p_call_flags, const StringName &p_gro
if (p_call_flags & GROUP_CALL_REVERSE) {
for (int i = gr_node_count - 1; i >= 0; i--) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -275,7 +278,7 @@ void SceneTree::call_group_flagsp(uint32_t p_call_flags, const StringName &p_gro
} else {
for (int i = 0; i < gr_node_count; i++) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -314,7 +317,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr
if (p_call_flags & GROUP_CALL_REVERSE) {
for (int i = gr_node_count - 1; i >= 0; i--) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -327,7 +330,7 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr
} else {
for (int i = 0; i < gr_node_count; i++) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -365,7 +368,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
if (p_call_flags & GROUP_CALL_REVERSE) {
for (int i = gr_node_count - 1; i >= 0; i--) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -378,7 +381,7 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
} else {
for (int i = 0; i < gr_node_count; i++) {
- if (call_lock && call_skip.has(gr_nodes[i])) {
+ if (call_lock && call_skip.has(gr_nodes[i]->get_instance_id())) {
continue;
}
@@ -854,7 +857,7 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
for (int i = 0; i < gr_node_count; i++) {
Node *n = gr_nodes[i];
- if (call_lock && call_skip.has(n)) {
+ if (call_lock && call_skip.has(n->get_instance_id())) {
continue;
}
@@ -904,7 +907,7 @@ void SceneTree::_call_input_pause(const StringName &p_group, CallInputType p_cal
}
Node *n = gr_nodes[i];
- if (call_lock && call_skip.has(n)) {
+ if (call_lock && call_skip.has(n->get_instance_id())) {
continue;
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index a460e40597..d4fcb288ae 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -135,7 +135,7 @@ private:
// Safety for when a node is deleted while a group is being called.
int call_lock = 0;
- HashSet<Node *> call_skip; // Skip erased nodes.
+ HashSet<ObjectID> call_skip; // Skip erased nodes. Store ID instead of pointer to avoid false positives when node is freed and a new node is allocated at the pointed address.
List<ObjectID> delete_queue;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index f8b0a66a71..4c2a761138 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -1561,44 +1561,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
set_input_as_handled();
}
- if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) {
+ if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) {
// Alternate drop use (when using force_drag(), as proposed by #5342).
- gui.drag_successful = false;
- if (gui.mouse_focus) {
- gui.drag_successful = _gui_drop(gui.mouse_focus, pos, false);
- }
-
- gui.drag_data = Variant();
- gui.dragging = false;
-
- Control *drag_preview = _gui_get_drag_preview();
- if (drag_preview) {
- memdelete(drag_preview);
- gui.drag_preview_id = ObjectID();
- }
- _propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- get_base_window()->update_mouse_cursor_shape();
+ _perform_drop(gui.mouse_focus, pos);
}
_gui_cancel_tooltip();
} else {
- if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == MouseButton::LEFT) {
- gui.drag_successful = false;
- if (gui.drag_mouse_over) {
- gui.drag_successful = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false);
- }
-
- Control *drag_preview = _gui_get_drag_preview();
- if (drag_preview) {
- memdelete(drag_preview);
- gui.drag_preview_id = ObjectID();
- }
-
- gui.drag_data = Variant();
- gui.dragging = false;
- gui.drag_mouse_over = nullptr;
- _propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- get_base_window()->update_mouse_cursor_shape();
+ if (gui.dragging && mb->get_button_index() == MouseButton::LEFT) {
+ _perform_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos);
}
gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask.
@@ -1682,7 +1653,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
gui.drag_attempted = true;
- if (gui.drag_data.get_type() != Variant::NIL) {
+ if (gui.dragging) {
_propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN);
}
}
@@ -1698,6 +1669,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
_gui_cancel_tooltip();
if (over) {
+ if (!gui.mouse_over) {
+ _drop_physics_mouseover();
+ }
_gui_call_notification(over, Control::NOTIFICATION_MOUSE_ENTER);
gui.mouse_over = over;
}
@@ -1795,7 +1769,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
- if (gui.drag_data.get_type() != Variant::NIL) {
+ if (gui.dragging) {
// Handle drag & drop.
Control *drag_preview = _gui_get_drag_preview();
@@ -1997,6 +1971,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (mm.is_null() && mb.is_null() && p_event->is_action_type()) {
+ if (gui.dragging && p_event->is_action_pressed("ui_cancel") && Input::get_singleton()->is_action_just_pressed("ui_cancel")) {
+ _perform_drop();
+ set_input_as_handled();
+ return;
+ }
+
if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) {
gui.key_focus->release_focus();
}
@@ -2078,6 +2058,27 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
}
+void Viewport::_perform_drop(Control *p_control, Point2 p_pos) {
+ // Without any arguments, simply cancel Drag and Drop.
+ if (p_control) {
+ gui.drag_successful = _gui_drop(p_control, p_pos, false);
+ } else {
+ gui.drag_successful = false;
+ }
+
+ Control *drag_preview = _gui_get_drag_preview();
+ if (drag_preview) {
+ memdelete(drag_preview);
+ gui.drag_preview_id = ObjectID();
+ }
+
+ gui.drag_data = Variant();
+ gui.dragging = false;
+ gui.drag_mouse_over = nullptr;
+ _propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
+ get_base_window()->update_mouse_cursor_shape();
+}
+
void Viewport::_gui_cleanup_internal_state(Ref<InputEvent> p_event) {
ERR_FAIL_COND(p_event.is_null());
@@ -2662,6 +2663,11 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
} else {
gui.subwindow_resize_mode = _sub_window_get_resize_margin(sw.window, mb->get_position());
if (gui.subwindow_resize_mode != SUB_WINDOW_RESIZE_DISABLED) {
+ if (gui.subwindow_focused != sw.window) {
+ // Refocus.
+ _sub_window_grab_focus(sw.window);
+ }
+
gui.subwindow_resize_from_rect = r;
gui.subwindow_drag_from = mb->get_position();
gui.subwindow_drag = SUB_WINDOW_DRAG_RESIZE;
@@ -3041,8 +3047,6 @@ bool Viewport::gui_is_drag_successful() const {
}
void Viewport::set_input_as_handled() {
- _drop_physics_mouseover();
-
if (!handle_input_locally) {
ERR_FAIL_COND(!is_inside_tree());
Viewport *vp = this;
@@ -4161,7 +4165,7 @@ DisplayServer::WindowID SubViewport::get_window_id() const {
}
Transform2D SubViewport::_stretch_transform() {
- Transform2D transform = Transform2D();
+ Transform2D transform;
Size2i view_size_2d_override = _get_size_2d_override();
if (size_2d_override_stretch && view_size_2d_override.width > 0 && view_size_2d_override.height > 0) {
Size2 scale = Size2(_get_size()) / Size2(view_size_2d_override);
@@ -4172,7 +4176,7 @@ Transform2D SubViewport::_stretch_transform() {
}
Transform2D SubViewport::get_screen_transform() const {
- Transform2D container_transform = Transform2D();
+ Transform2D container_transform;
SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
if (c) {
if (c->is_stretch_enabled()) {
@@ -4231,6 +4235,8 @@ void SubViewport::_bind_methods() {
BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
}
-SubViewport::SubViewport() {}
+SubViewport::SubViewport() {
+ RS::get_singleton()->viewport_set_size(get_viewport_rid(), get_size().width, get_size().height);
+}
SubViewport::~SubViewport() {}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 8911aea335..dc69ec24d8 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -405,6 +405,7 @@ private:
Control *_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform);
void _gui_input_event(Ref<InputEvent> p_event);
+ void _perform_drop(Control *p_control = nullptr, Point2 p_pos = Point2());
void _gui_cleanup_internal_state(Ref<InputEvent> p_event);
_FORCE_INLINE_ Transform2D _get_input_pre_xform() const;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index ebb11ecee8..aff2c594d9 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -1633,7 +1633,7 @@ void Window::_validate_property(PropertyInfo &p_property) const {
}
Transform2D Window::get_screen_transform() const {
- Transform2D embedder_transform = Transform2D();
+ Transform2D embedder_transform;
if (_get_embedder()) {
embedder_transform.translate_local(get_position());
embedder_transform = _get_embedder()->get_screen_transform() * embedder_transform;