diff options
18 files changed, 88 insertions, 28 deletions
diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h index b824044b82..5afdb884f6 100644 --- a/core/variant/variant_construct.h +++ b/core/variant/variant_construct.h @@ -153,11 +153,14 @@ public: class VariantConstructorObject { public: static void construct(Variant &r_ret, const Variant **p_args, Callable::CallError &r_error) { - VariantInternal::clear(&r_ret); if (p_args[0]->get_type() == Variant::NIL) { + VariantInternal::clear(&r_ret); + VariantTypeChanger<Object *>::change(&r_ret); VariantInternal::object_assign_null(&r_ret); r_error.error = Callable::CallError::CALL_OK; } else if (p_args[0]->get_type() == Variant::OBJECT) { + VariantInternal::clear(&r_ret); + VariantTypeChanger<Object *>::change(&r_ret); VariantInternal::object_assign(&r_ret, p_args[0]); r_error.error = Callable::CallError::CALL_OK; } else { @@ -169,6 +172,7 @@ public: static inline void validated_construct(Variant *r_ret, const Variant **p_args) { VariantInternal::clear(r_ret); + VariantTypeChanger<Object *>::change(r_ret); VariantInternal::object_assign(r_ret, p_args[0]); } static void ptr_construct(void *base, const void **p_args) { @@ -198,11 +202,13 @@ public: } VariantInternal::clear(&r_ret); + VariantTypeChanger<Object *>::change(&r_ret); VariantInternal::object_assign_null(&r_ret); } static inline void validated_construct(Variant *r_ret, const Variant **p_args) { VariantInternal::clear(r_ret); + VariantTypeChanger<Object *>::change(r_ret); VariantInternal::object_assign_null(r_ret); } static void ptr_construct(void *base, const void **p_args) { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 72eea8a27e..bd720cde93 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -1575,7 +1575,7 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) { } else { Node *node_owner = node->get_owner(); if (node == edited_scene || node_owner == edited_scene || (node_owner != nullptr && edited_scene->is_editable_instance(node_owner))) { - if (selection_results.has(node)) { + if (!selection_results.has(node)) { selection_results.append(node); } break; diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 28a030e492..822fc412b4 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -402,7 +402,9 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> } const Variant &var = gl_array[E.value]; - if (Object *obj = var) { + bool freed = false; + const Object *obj = var.get_validated_object_with_check(freed); + if (obj && !freed) { if (Object::cast_to<GDScriptNativeClass>(obj)) { continue; } diff --git a/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd new file mode 100644 index 0000000000..3724c8c713 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.gd @@ -0,0 +1,9 @@ +# https://github.com/godotengine/godot/issues/90086 + +class MyObj: + var obj: WeakRef + +func test(): + var obj_1 = MyObj.new() + var obj_2 = MyObj.new() + obj_1.obj = obj_2 diff --git a/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out new file mode 100644 index 0000000000..dfca5b1eca --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/errors/invalid_property_assignment.out @@ -0,0 +1,6 @@ +GDTEST_RUNTIME_ERROR +>> SCRIPT ERROR +>> on function: test() +>> runtime/errors/invalid_property_assignment.gd +>> 9 +>> Invalid assignment of property or key 'obj' with value of type 'RefCounted (MyObj)' on a base object of type 'RefCounted (MyObj)'. diff --git a/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd new file mode 100644 index 0000000000..e1aba83507 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.gd @@ -0,0 +1,11 @@ +# https://github.com/godotengine/godot/issues/90086 + +class MyObj: + var obj : WeakRef + +func test(): + var obj_1 = MyObj.new() + var obj_2 = MyObj.new() + assert(obj_2.get_reference_count() == 1) + obj_1.set(&"obj", obj_2) + assert(obj_2.get_reference_count() == 1) diff --git a/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out new file mode 100644 index 0000000000..d73c5eb7cd --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/set_does_not_leak.out @@ -0,0 +1 @@ +GDTEST_OK diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index d6eb101a68..4a52e26373 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -1735,7 +1735,7 @@ Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const { return ret; } -DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { +DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent) { _THREAD_SAFE_METHOD_ WindowID id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect); @@ -1749,6 +1749,11 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, V rendering_device->screen_create(id); } #endif + + if (p_transient_parent != INVALID_WINDOW_ID) { + window_set_transient(id, p_transient_parent); + } + return id; } diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 341ba5f079..0cbfbe51ef 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -438,7 +438,7 @@ public: virtual Vector<DisplayServer::WindowID> get_window_list() const override; - virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override; + virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID) override; virtual void show_window(WindowID p_id) override; virtual void delete_sub_window(WindowID p_id) override; diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index b4741dc08f..bd3c6af273 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -326,7 +326,7 @@ public: virtual Vector<int> get_window_list() const override; - virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override; + virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID) override; virtual void show_window(WindowID p_id) override; virtual void delete_sub_window(WindowID p_id) override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index da45391995..cd2d8a60ac 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1714,7 +1714,7 @@ Vector<DisplayServer::WindowID> DisplayServerMacOS::get_window_list() const { return ret; } -DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { +DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent) { _THREAD_SAFE_METHOD_ WindowID id = _create_window(p_mode, p_vsync_mode, p_rect); @@ -1728,6 +1728,12 @@ DisplayServer::WindowID DisplayServerMacOS::create_sub_window(WindowMode p_mode, rendering_device->screen_create(id); } #endif + + window_set_exclusive(id, p_exclusive); + if (p_transient_parent != INVALID_WINDOW_ID) { + window_set_transient(id, p_transient_parent); + } + return id; } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index f29048b16d..1f932b72b0 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1306,10 +1306,10 @@ DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(cons return INVALID_WINDOW_ID; } -DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { +DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent) { _THREAD_SAFE_METHOD_ - WindowID window_id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect); + WindowID window_id = _create_window(p_mode, p_vsync_mode, p_flags, p_rect, p_exclusive, p_transient_parent); ERR_FAIL_COND_V_MSG(window_id == INVALID_WINDOW_ID, INVALID_WINDOW_ID, "Failed to create sub window."); WindowData &wd = windows[window_id]; @@ -5326,7 +5326,7 @@ void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const } } -DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { +DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent) { DWORD dwExStyle; DWORD dwStyle; @@ -5376,6 +5376,18 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, WindowID id = window_id_counter; { + WindowData *wd_transient_parent = nullptr; + HWND owner_hwnd = nullptr; + if (p_transient_parent != INVALID_WINDOW_ID && !windows.has(p_transient_parent)) { + ERR_PRINT("Condition \"!windows.has(p_transient_parent)\" is true."); + p_transient_parent = INVALID_WINDOW_ID; + } else { + wd_transient_parent = &windows[p_transient_parent]; + if (p_exclusive) { + owner_hwnd = wd_transient_parent->hWnd; + } + } + WindowData &wd = windows[id]; wd.hWnd = CreateWindowExW( @@ -5386,7 +5398,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, WindowRect.top, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, - nullptr, + owner_hwnd, nullptr, hInstance, // tunnel the WindowData we need to handle creation message @@ -5408,6 +5420,12 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, wd.pre_fs_valid = true; } + wd.exclusive = p_exclusive; + if (wd_transient_parent) { + wd.transient_parent = p_transient_parent; + wd_transient_parent->transient_children.insert(id); + } + if (is_dark_mode_supported() && dark_title_available) { BOOL value = is_dark_mode(); ::DwmSetWindowAttribute(wd.hWnd, use_legacy_dark_mode_before_20H1 ? DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 : DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value)); @@ -6036,7 +6054,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win window_position = scr_rect.position + (scr_rect.size - p_resolution) / 2; } - WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution)); + WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution), false, INVALID_WINDOW_ID); ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window."); joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd); diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 650f0412ea..7b259def14 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -517,7 +517,7 @@ class DisplayServerWindows : public DisplayServer { uint64_t time_since_popup = 0; Ref<Image> icon; - WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect); + WindowID _create_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent); WindowID window_id_counter = MAIN_WINDOW_ID; RBMap<WindowID, WindowData> windows; @@ -652,7 +652,7 @@ public: virtual Vector<DisplayServer::WindowID> get_window_list() const override; - virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override; + virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID) override; virtual void show_window(WindowID p_window) override; virtual void delete_sub_window(WindowID p_window) override; diff --git a/scene/main/window.cpp b/scene/main/window.cpp index d409efbfab..e5873f0e9a 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -631,7 +631,7 @@ void Window::_make_window() { window_rect = Rect2i(DisplayServer::get_singleton()->screen_get_position(DisplayServer::SCREEN_WITH_KEYBOARD_FOCUS) + (DisplayServer::get_singleton()->screen_get_size(DisplayServer::SCREEN_WITH_KEYBOARD_FOCUS) - size) / 2, size); } - window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, window_rect); + window_id = DisplayServer::get_singleton()->create_sub_window(DisplayServer::WindowMode(mode), vsync_mode, f, window_rect, is_in_edited_scene_root() ? false : exclusive, transient_parent ? transient_parent->window_id : DisplayServer::INVALID_WINDOW_ID); ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID); DisplayServer::get_singleton()->window_set_max_size(Size2i(), window_id); DisplayServer::get_singleton()->window_set_min_size(Size2i(), window_id); @@ -639,18 +639,8 @@ void Window::_make_window() { DisplayServer::get_singleton()->window_set_title(tr_title, window_id); DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id); - if (is_in_edited_scene_root()) { - DisplayServer::get_singleton()->window_set_exclusive(window_id, false); - } else { - DisplayServer::get_singleton()->window_set_exclusive(window_id, exclusive); - } - _update_window_size(); - if (transient_parent && transient_parent->window_id != DisplayServer::INVALID_WINDOW_ID) { - DisplayServer::get_singleton()->window_set_transient(window_id, transient_parent->window_id); - } - if (transient_parent) { for (const Window *E : transient_children) { if (E->window_id != DisplayServer::INVALID_WINDOW_ID) { diff --git a/servers/display_server.cpp b/servers/display_server.cpp index d362a4073a..5451057645 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -570,7 +570,7 @@ int DisplayServer::get_screen_from_rect(const Rect2 &p_rect) const { return pos_screen; } -DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect) { +DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect, bool p_exclusive, WindowID p_transient_parent) { ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server."); } diff --git a/servers/display_server.h b/servers/display_server.h index 8c7e92fdc3..d0fe76faff 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -396,7 +396,7 @@ public: WINDOW_FLAG_MOUSE_PASSTHROUGH_BIT = (1 << WINDOW_FLAG_MOUSE_PASSTHROUGH), }; - virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()); + virtual WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID); virtual void show_window(WindowID p_id); virtual void delete_sub_window(WindowID p_id); diff --git a/servers/display_server_headless.h b/servers/display_server_headless.h index 60422c16cc..a5277479ca 100644 --- a/servers/display_server_headless.h +++ b/servers/display_server_headless.h @@ -85,7 +85,7 @@ public: Vector<DisplayServer::WindowID> get_window_list() const override { return Vector<DisplayServer::WindowID>(); } - WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override { return 0; } + WindowID create_sub_window(WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i(), bool p_exclusive = false, WindowID p_transient_parent = INVALID_WINDOW_ID) override { return 0; } void show_window(WindowID p_id) override {} void delete_sub_window(WindowID p_id) override {} diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 745dcf5392..568aec2ff6 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -7411,6 +7411,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return ERR_PARSE_ERROR; } tk = _get_token(); + } else { + _set_expected_error("("); + return ERR_PARSE_ERROR; } } } else { @@ -9520,6 +9523,9 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f _set_error(RTR("Array size mismatch.")); return ERR_PARSE_ERROR; } + } else { + _set_expected_error("("); + return ERR_PARSE_ERROR; } array_size = constant.array_size; |
