diff options
Diffstat (limited to 'scene/main')
-rw-r--r-- | scene/main/canvas_item.cpp | 105 | ||||
-rw-r--r-- | scene/main/canvas_item.h | 5 | ||||
-rw-r--r-- | scene/main/canvas_layer.cpp | 23 | ||||
-rw-r--r-- | scene/main/canvas_layer.h | 2 | ||||
-rw-r--r-- | scene/main/http_request.cpp | 28 | ||||
-rw-r--r-- | scene/main/node.cpp | 62 | ||||
-rw-r--r-- | scene/main/node.h | 7 | ||||
-rw-r--r-- | scene/main/scene_tree.cpp | 16 | ||||
-rw-r--r-- | scene/main/scene_tree.h | 3 | ||||
-rw-r--r-- | scene/main/shader_globals_override.cpp | 36 | ||||
-rw-r--r-- | scene/main/timer.cpp | 4 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 37 | ||||
-rw-r--r-- | scene/main/viewport.h | 2 | ||||
-rw-r--r-- | scene/main/window.cpp | 29 |
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(); |