summaryrefslogtreecommitdiff
path: root/scene/main
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main')
-rw-r--r--scene/main/canvas_item.cpp105
-rw-r--r--scene/main/canvas_item.h5
-rw-r--r--scene/main/canvas_layer.cpp23
-rw-r--r--scene/main/canvas_layer.h2
-rw-r--r--scene/main/http_request.cpp28
-rw-r--r--scene/main/node.cpp62
-rw-r--r--scene/main/node.h7
-rw-r--r--scene/main/scene_tree.cpp16
-rw-r--r--scene/main/scene_tree.h3
-rw-r--r--scene/main/shader_globals_override.cpp36
-rw-r--r--scene/main/timer.cpp4
-rw-r--r--scene/main/viewport.cpp37
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/main/window.cpp29
14 files changed, 209 insertions, 150 deletions
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index a62bbb146c..26b67b763c 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -56,43 +56,21 @@ Transform2D CanvasItem::_edit_get_transform() const {
#endif
bool CanvasItem::is_visible_in_tree() const {
- if (!is_inside_tree()) {
- return false;
- }
-
- const CanvasItem *p = this;
-
- while (p) {
- if (!p->visible) {
- return false;
- }
- if (p->window && !p->window->is_visible()) {
- return false;
- }
- p = p->get_parent_item();
- }
-
- const Node *n = get_parent();
- while (n) {
- const CanvasLayer *c = Object::cast_to<CanvasLayer>(n);
- if (c && !c->is_visible()) {
- return false;
- }
- n = n->get_parent();
- }
-
- return true;
+ return visible && parent_visible_in_tree;
}
-void CanvasItem::_propagate_visibility_changed(bool p_visible) {
- if (p_visible && first_draw) { //avoid propagating it twice
+void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_is_source) {
+ if (p_visible && first_draw) { // Avoid propagating it twice.
first_draw = false;
}
+ if (!p_is_source) {
+ parent_visible_in_tree = p_visible;
+ }
notification(NOTIFICATION_VISIBILITY_CHANGED);
- if (p_visible) {
- update(); //todo optimize
- } else {
+ if (visible && p_visible) {
+ update();
+ } else if (!p_visible && (visible || p_is_source)) {
emit_signal(SceneStringNames::get_singleton()->hidden);
}
_block();
@@ -100,8 +78,12 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible) {
for (int i = 0; i < get_child_count(); i++) {
CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
- if (c && c->visible) { //should the top_levels stop propagation? i think so but..
- c->_propagate_visibility_changed(p_visible);
+ if (c) { // Should the top_levels stop propagation? I think so, but...
+ if (c->visible) {
+ c->_propagate_visibility_changed(p_visible);
+ } else {
+ c->parent_visible_in_tree = p_visible;
+ }
}
}
@@ -116,11 +98,12 @@ void CanvasItem::set_visible(bool p_visible) {
visible = p_visible;
RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible);
- if (!is_inside_tree()) {
+ if (!parent_visible_in_tree) {
+ notification(NOTIFICATION_VISIBILITY_CHANGED);
return;
}
- _propagate_visibility_changed(p_visible);
+ _propagate_visibility_changed(p_visible, true);
}
void CanvasItem::show() {
@@ -148,7 +131,7 @@ void CanvasItem::_update_callback() {
RenderingServer::get_singleton()->canvas_item_clear(get_canvas_item());
//todo updating = true - only allow drawing here
- if (is_visible_in_tree()) { //todo optimize this!!
+ if (is_visible_in_tree()) {
if (first_draw) {
notification(NOTIFICATION_VISIBILITY_CHANGED);
first_draw = false;
@@ -282,32 +265,44 @@ void CanvasItem::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
ERR_FAIL_COND(!is_inside_tree());
first_draw = true;
+
Node *parent = get_parent();
if (parent) {
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
+
if (ci) {
+ parent_visible_in_tree = ci->is_visible_in_tree();
C = ci->children_items.push_back(this);
- }
- if (!ci) {
- //look for a window
- Viewport *viewport = nullptr;
-
- while (parent) {
- viewport = Object::cast_to<Viewport>(parent);
- if (viewport) {
- break;
+ } else {
+ CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent);
+
+ if (cl) {
+ parent_visible_in_tree = cl->is_visible();
+ } else {
+ // Look for a window.
+ Viewport *viewport = nullptr;
+
+ while (parent) {
+ viewport = Object::cast_to<Viewport>(parent);
+ if (viewport) {
+ break;
+ }
+ parent = parent->get_parent();
}
- parent = parent->get_parent();
- }
- ERR_FAIL_COND(!viewport);
+ ERR_FAIL_COND(!viewport);
- window = Object::cast_to<Window>(viewport);
- if (window) {
- window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
+ window = Object::cast_to<Window>(viewport);
+ if (window) {
+ window->connect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
+ parent_visible_in_tree = window->is_visible();
+ } else {
+ parent_visible_in_tree = true;
+ }
}
}
}
+
_enter_canvas();
_update_texture_filter_changed(false);
@@ -317,6 +312,7 @@ void CanvasItem::_notification(int p_what) {
get_tree()->xform_change_list.add(&xform_change);
}
} break;
+
case NOTIFICATION_MOVED_IN_PARENT: {
if (!is_inside_tree()) {
break;
@@ -329,8 +325,8 @@ void CanvasItem::_notification(int p_what) {
ERR_FAIL_COND(!p);
RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index());
}
-
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (xform_change.in_list()) {
get_tree()->xform_change_list.remove(&xform_change);
@@ -344,10 +340,9 @@ void CanvasItem::_notification(int p_what) {
window->disconnect(SceneStringNames::get_singleton()->visibility_changed, callable_mp(this, &CanvasItem::_window_visibility_changed));
}
global_invalid = true;
+ parent_visible_in_tree = false;
} break;
- case NOTIFICATION_DRAW:
- case NOTIFICATION_TRANSFORM_CHANGED: {
- } break;
+
case NOTIFICATION_VISIBILITY_CHANGED: {
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
} break;
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 08fea52c3a..c0558b6be2 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -32,10 +32,8 @@
#define CANVAS_ITEM_H
#include "scene/main/node.h"
-#include "scene/main/scene_tree.h"
#include "scene/resources/canvas_item_material.h"
#include "scene/resources/font.h"
-#include "servers/text_server.h"
class CanvasLayer;
class MultiMesh;
@@ -87,6 +85,7 @@ private:
Window *window = nullptr;
bool first_draw = false;
bool visible = true;
+ bool parent_visible_in_tree = false;
bool clip_children = false;
bool pending_update = false;
bool top_level = false;
@@ -109,7 +108,7 @@ private:
void _top_level_raise_self();
- void _propagate_visibility_changed(bool p_visible);
+ void _propagate_visibility_changed(bool p_visible, bool p_is_source = false);
void _update_callback();
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index 3f3e72357b..be24620904 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -29,8 +29,10 @@
/*************************************************************************/
#include "canvas_layer.h"
-#include "canvas_item.h"
-#include "viewport.h"
+
+#include "scene/main/canvas_item.h"
+#include "scene/main/viewport.h"
+#include "scene/resources/world_2d.h"
void CanvasLayer::set_layer(int p_xform) {
layer = p_xform;
@@ -59,12 +61,20 @@ void CanvasLayer::set_visible(bool p_visible) {
if (c->is_visible()) {
c->_propagate_visibility_changed(p_visible);
} else {
- c->notification(CanvasItem::NOTIFICATION_VISIBILITY_CHANGED);
+ c->parent_visible_in_tree = p_visible;
}
}
}
}
+void CanvasLayer::show() {
+ set_visible(true);
+}
+
+void CanvasLayer::hide() {
+ set_visible(false);
+}
+
bool CanvasLayer::is_visible() const {
return visible;
}
@@ -164,8 +174,8 @@ void CanvasLayer::_notification(int p_what) {
RenderingServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_index());
RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
_update_follow_viewport();
-
} break;
+
case NOTIFICATION_EXIT_TREE: {
ERR_FAIL_NULL_MSG(vp, "Viewport is not initialized.");
@@ -173,13 +183,12 @@ void CanvasLayer::_notification(int p_what) {
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, canvas);
viewport = RID();
_update_follow_viewport(false);
-
} break;
+
case NOTIFICATION_MOVED_IN_PARENT: {
if (is_inside_tree()) {
RenderingServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_index());
}
-
} break;
}
}
@@ -293,6 +302,8 @@ void CanvasLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_visible", "visible"), &CanvasLayer::set_visible);
ClassDB::bind_method(D_METHOD("is_visible"), &CanvasLayer::is_visible);
+ ClassDB::bind_method(D_METHOD("show"), &CanvasLayer::show);
+ ClassDB::bind_method(D_METHOD("hide"), &CanvasLayer::hide);
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &CanvasLayer::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &CanvasLayer::get_transform);
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index b7bd793440..2493675b31 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -72,6 +72,8 @@ public:
void set_visible(bool p_visible);
bool is_visible() const;
+ void show();
+ void hide();
void set_transform(const Transform2D &p_xform);
Transform2D get_transform() const;
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index 4e91548d14..700ba761f6 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -464,20 +464,22 @@ void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArra
}
void HTTPRequest::_notification(int p_what) {
- if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
- if (use_threads.is_set()) {
- return;
- }
- bool done = _update_connection();
- if (done) {
- set_process_internal(false);
- }
- }
+ switch (p_what) {
+ case NOTIFICATION_INTERNAL_PROCESS: {
+ if (use_threads.is_set()) {
+ return;
+ }
+ bool done = _update_connection();
+ if (done) {
+ set_process_internal(false);
+ }
+ } break;
- if (p_what == NOTIFICATION_EXIT_TREE) {
- if (requesting) {
- cancel_request();
- }
+ case NOTIFICATION_EXIT_TREE: {
+ if (requesting) {
+ cancel_request();
+ }
+ } break;
}
}
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 6b9d8ab211..211667ce38 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -30,6 +30,7 @@
#include "node.h"
+#include "core/config/project_settings.h"
#include "core/core_string_names.h"
#include "core/io/resource_loader.h"
#include "core/multiplayer/multiplayer_api.h"
@@ -53,12 +54,12 @@ void Node::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_PROCESS: {
GDVIRTUAL_CALL(_process, get_process_delta_time());
-
} break;
+
case NOTIFICATION_PHYSICS_PROCESS: {
GDVIRTUAL_CALL(_physics_process, get_physics_process_delta_time());
-
} break;
+
case NOTIFICATION_ENTER_TREE: {
ERR_FAIL_COND(!get_viewport());
ERR_FAIL_COND(!get_tree());
@@ -87,8 +88,8 @@ void Node::_notification(int p_notification) {
get_tree()->node_count++;
orphan_node_count--;
-
} break;
+
case NOTIFICATION_EXIT_TREE: {
ERR_FAIL_COND(!get_viewport());
ERR_FAIL_COND(!get_tree());
@@ -112,12 +113,14 @@ void Node::_notification(int p_notification) {
data.path_cache = nullptr;
}
} break;
+
case NOTIFICATION_PATH_RENAMED: {
if (data.path_cache) {
memdelete(data.path_cache);
data.path_cache = nullptr;
}
} break;
+
case NOTIFICATION_READY: {
if (GDVIRTUAL_IS_OVERRIDDEN(_input)) {
set_process_input(true);
@@ -140,9 +143,11 @@ void Node::_notification(int p_notification) {
GDVIRTUAL_CALL(_ready);
} break;
+
case NOTIFICATION_POSTINITIALIZE: {
data.in_constructor = false;
} break;
+
case NOTIFICATION_PREDELETE: {
if (data.parent) {
data.parent->remove_child(this);
@@ -612,14 +617,15 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallEr
return Variant();
}
- if (p_args[0]->get_type() != Variant::STRING_NAME) {
+ Variant::Type type = p_args[0]->get_type();
+ if (type != Variant::STRING_NAME && type != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING_NAME;
return Variant();
}
- StringName method = *p_args[0];
+ StringName method = (*p_args[0]).operator StringName();
rpcp(0, method, &p_args[1], p_argcount - 1);
@@ -641,7 +647,8 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal
return Variant();
}
- if (p_args[1]->get_type() != Variant::STRING_NAME) {
+ Variant::Type type = p_args[1]->get_type();
+ if (type != Variant::STRING_NAME && type != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING_NAME;
@@ -649,7 +656,7 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal
}
int peer_id = *p_args[0];
- StringName method = *p_args[1];
+ StringName method = (*p_args[1]).operator StringName();
rpcp(peer_id, method, &p_args[2], p_argcount - 2);
@@ -1337,27 +1344,45 @@ bool Node::has_node(const NodePath &p_path) const {
return get_node_or_null(p_path) != nullptr;
}
-Node *Node::find_node(const String &p_mask, bool p_recursive, bool p_owned) const {
+TypedArray<Node> Node::find_nodes(const String &p_mask, const String &p_type, bool p_recursive, bool p_owned) const {
+ TypedArray<Node> ret;
+ ERR_FAIL_COND_V(p_mask.is_empty() && p_type.is_empty(), ret);
+
Node *const *cptr = data.children.ptr();
int ccount = data.children.size();
for (int i = 0; i < ccount; i++) {
if (p_owned && !cptr[i]->data.owner) {
continue;
}
- if (cptr[i]->data.name.operator String().match(p_mask)) {
- return cptr[i];
+
+ if (!p_mask.is_empty()) {
+ if (!cptr[i]->data.name.operator String().match(p_mask)) {
+ continue;
+ } else if (p_type.is_empty()) {
+ ret.append(cptr[i]);
+ }
}
- if (!p_recursive) {
- continue;
+ if (cptr[i]->is_class(p_type)) {
+ ret.append(cptr[i]);
+ } else if (cptr[i]->get_script_instance()) {
+ Ref<Script> script = cptr[i]->get_script_instance()->get_script();
+ while (script.is_valid()) {
+ if ((ScriptServer::is_global_class(p_type) && ScriptServer::get_global_class_path(p_type) == script->get_path()) || p_type == script->get_path()) {
+ ret.append(cptr[i]);
+ break;
+ }
+
+ script = script->get_base_script();
+ }
}
- Node *ret = cptr[i]->find_node(p_mask, true, p_owned);
- if (ret) {
- return ret;
+ if (p_recursive) {
+ ret.append_array(cptr[i]->find_nodes(p_mask, p_type, true, p_owned));
}
}
- return nullptr;
+
+ return ret;
}
Node *Node::get_parent() const {
@@ -2699,7 +2724,7 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_node", "path"), &Node::get_node);
ClassDB::bind_method(D_METHOD("get_node_or_null", "path"), &Node::get_node_or_null);
ClassDB::bind_method(D_METHOD("get_parent"), &Node::get_parent);
- ClassDB::bind_method(D_METHOD("find_node", "mask", "recursive", "owned"), &Node::find_node, DEFVAL(true), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("find_nodes", "mask", "type", "recursive", "owned"), &Node::find_nodes, DEFVAL(""), DEFVAL(true), DEFVAL(true));
ClassDB::bind_method(D_METHOD("find_parent", "mask"), &Node::find_parent);
ClassDB::bind_method(D_METHOD("has_node_and_resource", "path"), &Node::has_node_and_resource);
ClassDB::bind_method(D_METHOD("get_node_and_resource", "path"), &Node::_get_node_and_resource);
@@ -2838,6 +2863,9 @@ void Node::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_WM_CLOSE_REQUEST);
BIND_CONSTANT(NOTIFICATION_WM_GO_BACK_REQUEST);
BIND_CONSTANT(NOTIFICATION_WM_SIZE_CHANGED);
+ BIND_CONSTANT(NOTIFICATION_WM_DPI_CHANGE);
+ BIND_CONSTANT(NOTIFICATION_VP_MOUSE_ENTER);
+ BIND_CONSTANT(NOTIFICATION_VP_MOUSE_EXIT);
BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
diff --git a/scene/main/node.h b/scene/main/node.h
index 0ac10f4381..8e49f871a7 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -31,9 +31,6 @@
#ifndef NODE_H
#define NODE_H
-#include "core/config/project_settings.h"
-#include "core/object/class_db.h"
-#include "core/object/script_language.h"
#include "core/string/node_path.h"
#include "core/templates/map.h"
#include "core/variant/typed_array.h"
@@ -271,6 +268,8 @@ public:
NOTIFICATION_WM_GO_BACK_REQUEST = 1007,
NOTIFICATION_WM_SIZE_CHANGED = 1008,
NOTIFICATION_WM_DPI_CHANGE = 1009,
+ NOTIFICATION_VP_MOUSE_ENTER = 1010,
+ NOTIFICATION_VP_MOUSE_EXIT = 1011,
NOTIFICATION_OS_MEMORY_WARNING = MainLoop::NOTIFICATION_OS_MEMORY_WARNING,
NOTIFICATION_TRANSLATION_CHANGED = MainLoop::NOTIFICATION_TRANSLATION_CHANGED,
@@ -302,7 +301,7 @@ public:
bool has_node(const NodePath &p_path) const;
Node *get_node(const NodePath &p_path) const;
Node *get_node_or_null(const NodePath &p_path) const;
- Node *find_node(const String &p_mask, bool p_recursive = true, bool p_owned = true) const;
+ TypedArray<Node> find_nodes(const String &p_mask, const String &p_type = "", bool p_recursive = true, bool p_owned = true) const;
bool has_node_and_resource(const NodePath &p_path) const;
Node *get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property = true) const;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 0e4a6a4b5c..2b4d7d8331 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -44,10 +44,13 @@
#include "node.h"
#include "scene/animation/tween.h"
#include "scene/debugger/scene_debugger.h"
+#include "scene/main/viewport.h"
#include "scene/resources/font.h"
#include "scene/resources/material.h"
#include "scene/resources/mesh.h"
#include "scene/resources/packed_scene.h"
+#include "scene/resources/world_2d.h"
+#include "scene/resources/world_3d.h"
#include "scene/scene_string_names.h"
#include "servers/display_server.h"
#include "servers/navigation_server_3d.h"
@@ -613,6 +616,7 @@ void SceneTree::_notification(int p_notification) {
get_root()->propagate_notification(p_notification);
}
} break;
+
case NOTIFICATION_OS_MEMORY_WARNING:
case NOTIFICATION_OS_IME_UPDATE:
case NOTIFICATION_WM_ABOUT:
@@ -621,13 +625,11 @@ void SceneTree::_notification(int p_notification) {
case NOTIFICATION_APPLICATION_PAUSED:
case NOTIFICATION_APPLICATION_FOCUS_IN:
case NOTIFICATION_APPLICATION_FOCUS_OUT: {
- get_root()->propagate_notification(p_notification); //pass these to nodes, since they are mirrored
+ // Pass these to nodes, since they are mirrored.
+ get_root()->propagate_notification(p_notification);
} break;
-
- default:
- break;
- };
-};
+ }
+}
void SceneTree::set_auto_accept_quit(bool p_enable) {
accept_quit = p_enable;
@@ -1165,7 +1167,7 @@ void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
ERR_FAIL_COND(!p_multiplayer.is_valid());
multiplayer = p_multiplayer;
- multiplayer->set_root_node(root);
+ multiplayer->set_root_path("/" + root->get_name());
}
void SceneTree::_bind_methods() {
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index a5cd52b4ca..5f7c1729e8 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -35,8 +35,6 @@
#include "core/os/thread_safe.h"
#include "core/templates/self_list.h"
#include "scene/resources/mesh.h"
-#include "scene/resources/world_2d.h"
-#include "scene/resources/world_3d.h"
#undef Window
@@ -48,6 +46,7 @@ class Mesh;
class MultiplayerAPI;
class SceneDebugger;
class Tween;
+class Viewport;
class SceneTreeTimer : public RefCounted {
GDCLASS(SceneTreeTimer, RefCounted);
diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp
index 240e662efb..5387dc01e2 100644
--- a/scene/main/shader_globals_override.cpp
+++ b/scene/main/shader_globals_override.cpp
@@ -221,6 +221,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
}
void ShaderGlobalsOverride::_activate() {
+ ERR_FAIL_NULL(get_tree());
List<Node *> nodes;
get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes);
if (nodes.size() == 0) {
@@ -246,26 +247,29 @@ void ShaderGlobalsOverride::_activate() {
}
void ShaderGlobalsOverride::_notification(int p_what) {
- if (p_what == Node3D::NOTIFICATION_ENTER_TREE) {
- add_to_group(SceneStringNames::get_singleton()->shader_overrides_group);
- _activate();
+ switch (p_what) {
+ case Node3D::NOTIFICATION_ENTER_TREE: {
+ add_to_group(SceneStringNames::get_singleton()->shader_overrides_group);
+ _activate();
+ } break;
- } else if (p_what == Node3D::NOTIFICATION_EXIT_TREE) {
- if (active) {
- //remove overrides
- const StringName *K = nullptr;
- while ((K = overrides.next(K))) {
- Override *o = overrides.getptr(*K);
- if (o->in_use) {
- RS::get_singleton()->global_variable_set_override(*K, Variant());
+ case Node3D::NOTIFICATION_EXIT_TREE: {
+ if (active) {
+ //remove overrides
+ const StringName *K = nullptr;
+ while ((K = overrides.next(K))) {
+ Override *o = overrides.getptr(*K);
+ if (o->in_use) {
+ RS::get_singleton()->global_variable_set_override(*K, Variant());
+ }
}
}
- }
- remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active);
- remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group);
- get_tree()->call_group(SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed
- active = false;
+ remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group_active);
+ remove_from_group(SceneStringNames::get_singleton()->shader_overrides_group);
+ get_tree()->call_group(SceneStringNames::get_singleton()->shader_overrides_group, "_activate"); //another may want to activate when this is removed
+ active = false;
+ } break;
}
}
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index babe62f453..120b537e4f 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -43,6 +43,7 @@ void Timer::_notification(int p_what) {
autostart = false;
}
} break;
+
case NOTIFICATION_INTERNAL_PROCESS: {
if (!processing || timer_process_callback == TIMER_PROCESS_PHYSICS || !is_processing_internal()) {
return;
@@ -58,8 +59,8 @@ void Timer::_notification(int p_what) {
emit_signal(SNAME("timeout"));
}
-
} break;
+
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (!processing || timer_process_callback == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) {
return;
@@ -74,7 +75,6 @@ void Timer::_notification(int p_what) {
}
emit_signal(SNAME("timeout"));
}
-
} break;
}
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 522997cdf5..ca817b17bc 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -30,6 +30,7 @@
#include "viewport.h"
+#include "core/config/project_settings.h"
#include "core/core_string_names.h"
#include "core/debugger/engine_debugger.h"
#include "core/object/message_queue.h"
@@ -405,8 +406,8 @@ void Viewport::_notification(int p_what) {
#endif // _3D_DISABLED
set_physics_process_internal(true);
}
-
} break;
+
case NOTIFICATION_READY: {
#ifndef _3D_DISABLED
if (audio_listener_3d_set.size() && !audio_listener_3d) {
@@ -437,6 +438,7 @@ void Viewport::_notification(int p_what) {
}
#endif // _3D_DISABLED
} break;
+
case NOTIFICATION_EXIT_TREE: {
_gui_cancel_tooltip();
@@ -460,6 +462,7 @@ void Viewport::_notification(int p_what) {
RS::get_singleton()->viewport_set_active(viewport, false);
RenderingServer::get_singleton()->viewport_set_parent_viewport(viewport, RID());
} break;
+
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (!get_tree()) {
return;
@@ -492,17 +495,20 @@ void Viewport::_notification(int p_what) {
}
#endif // _3D_DISABLED
} break;
- case NOTIFICATION_WM_MOUSE_ENTER: {
- gui.mouse_in_window = true;
+
+ case NOTIFICATION_VP_MOUSE_ENTER: {
+ gui.mouse_in_viewport = true;
} break;
- case NOTIFICATION_WM_MOUSE_EXIT: {
- gui.mouse_in_window = false;
+
+ case NOTIFICATION_VP_MOUSE_EXIT: {
+ gui.mouse_in_viewport = false;
_drop_physics_mouseover();
_drop_mouse_over();
- // When the mouse exits the window, we want to end mouse_over, but
+ // When the mouse exits the viewport, we want to end mouse_over, but
// not mouse_focus, because, for example, we want to continue
- // dragging a scrollbar even if the mouse has left the window.
+ // dragging a scrollbar even if the mouse has left the viewport.
} break;
+
case NOTIFICATION_WM_WINDOW_FOCUS_OUT: {
_drop_physics_mouseover();
if (gui.mouse_focus && !gui.forced_mouse_focus) {
@@ -1677,7 +1683,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = nullptr;
if (gui.mouse_focus) {
over = gui.mouse_focus;
- } else if (gui.mouse_in_window) {
+ } else if (gui.mouse_in_viewport) {
over = gui_find_control(mpos);
}
@@ -1713,7 +1719,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.tooltip_popup) {
if (gui.tooltip_control) {
String tooltip = _gui_get_tooltip(over, gui.tooltip_control->get_global_transform().xform_inv(mpos));
-
+ tooltip = tooltip.strip_edges();
if (tooltip.length() == 0) {
_gui_cancel_tooltip();
} else if (gui.tooltip_label) {
@@ -3938,11 +3944,14 @@ Transform2D SubViewport::_stretch_transform() {
}
void SubViewport::_notification(int p_what) {
- if (p_what == NOTIFICATION_ENTER_TREE) {
- RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
- }
- if (p_what == NOTIFICATION_EXIT_TREE) {
- RS::get_singleton()->viewport_set_active(get_viewport_rid(), false);
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
+ } break;
+
+ case NOTIFICATION_EXIT_TREE: {
+ RS::get_singleton()->viewport_set_active(get_viewport_rid(), false);
+ } break;
}
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 3a71745f44..93e42f1838 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -335,7 +335,7 @@ private:
// info used when this is a window
bool forced_mouse_focus = false; //used for menu buttons
- bool mouse_in_window = true;
+ bool mouse_in_viewport = true;
bool key_event_accepted = false;
Control *mouse_focus = nullptr;
Control *last_mouse_focus = nullptr;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index f2ebe50fa3..0ce556d36c 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -30,6 +30,7 @@
#include "window.h"
+#include "core/config/project_settings.h"
#include "core/debugger/engine_debugger.h"
#include "core/string/translation.h"
#include "scene/gui/control.h"
@@ -254,6 +255,7 @@ void Window::_make_window() {
#endif
DisplayServer::get_singleton()->window_set_title(tr_title, window_id);
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
+ DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive);
_update_window_size();
@@ -338,9 +340,11 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: {
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
emit_signal(SNAME("mouse_entered"));
+ notification(NOTIFICATION_VP_MOUSE_ENTER);
DisplayServer::get_singleton()->cursor_set_shape(DisplayServer::CURSOR_ARROW); //restore cursor shape
} break;
case DisplayServer::WINDOW_EVENT_MOUSE_EXIT: {
+ notification(NOTIFICATION_VP_MOUSE_EXIT);
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_EXIT);
emit_signal(SNAME("mouse_exited"));
} break;
@@ -522,6 +526,10 @@ void Window::set_exclusive(bool p_exclusive) {
exclusive = p_exclusive;
+ if (!embedder && window_id != DisplayServer::INVALID_WINDOW_ID) {
+ DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive);
+ }
+
if (transient_parent) {
if (p_exclusive && is_inside_tree() && is_visible()) {
ERR_FAIL_COND_MSG(transient_parent->exclusive_child && transient_parent->exclusive_child != this, "Transient parent has another exclusive child.");
@@ -732,18 +740,16 @@ void Window::_notification(int p_what) {
bool embedded = false;
{
embedder = _get_embedder();
-
if (embedder) {
embedded = true;
-
if (!visible) {
- embedder = nullptr; //not yet since not visible
+ embedder = nullptr; // Not yet since not visible.
}
}
}
if (embedded) {
- //create as embedded
+ // Create as embedded.
if (embedder) {
embedder->_sub_window_register(this);
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
@@ -751,22 +757,22 @@ void Window::_notification(int p_what) {
}
} else {
- if (get_parent() == nullptr) {
- //it's the root window!
- visible = true; //always visible
+ if (!get_parent()) {
+ // It's the root window!
+ visible = true; // Always visible.
window_id = DisplayServer::MAIN_WINDOW_ID;
DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id);
_update_from_window();
- //since this window already exists (created on start), we must update pos and size from it
+ // Since this window already exists (created on start), we must update pos and size from it.
{
position = DisplayServer::get_singleton()->window_get_position(window_id);
size = DisplayServer::get_singleton()->window_get_size(window_id);
}
- _update_viewport_size(); //then feed back to the viewport
+ _update_viewport_size(); // Then feed back to the viewport.
_update_window_callbacks();
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
} else {
- //create
+ // Create.
if (visible) {
_make_window();
}
@@ -782,11 +788,13 @@ void Window::_notification(int p_what) {
RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
}
} break;
+
case NOTIFICATION_READY: {
if (wrap_controls) {
_update_child_controls();
}
} break;
+
case NOTIFICATION_TRANSLATION_CHANGED: {
if (embedder) {
embedder->_sub_window_update(this);
@@ -805,6 +813,7 @@ void Window::_notification(int p_what) {
child_controls_changed();
} break;
+
case NOTIFICATION_EXIT_TREE: {
if (transient) {
_clear_transient();