From e290448fe3295b43f06f23eacb7a07cdc3d064a8 Mon Sep 17 00:00:00 2001 From: Abdulrahman Al Zeidi Date: Mon, 27 Feb 2023 02:44:23 +0000 Subject: Fix glTF mesh importer not freeing nodes correctly on import (cherry picked from commit 5e0641ea9af03491889d89f9bdac0785e5bc3158) --- .../gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp index 388c3ec740..2af716b867 100644 --- a/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp +++ b/modules/gltf/extensions/gltf_document_extension_convert_importer_mesh.cpp @@ -70,7 +70,7 @@ Error GLTFDocumentExtensionConvertImporterMesh::import_post(Ref p_sta } queue.pop_front(); } - while (!queue.is_empty()) { + while (!delete_queue.is_empty()) { List::Element *E = delete_queue.front(); Node *node = E->get(); memdelete(node); -- cgit v1.2.3 From 466d226a4acc66fc1c1c4faf8d9da68e6c84fbda Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Tue, 21 Feb 2023 09:43:54 +0200 Subject: [TextServer] Ensure ICU data is initialised only one and cleaned only at exit. (cherry picked from commit 7f24433e15081044aa8bcc3a646ded5129048bf5) --- modules/text_server_adv/text_server_adv.cpp | 5 ++++- modules/text_server_adv/text_server_adv.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 22652daa24..007f439a89 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -334,6 +334,8 @@ _FORCE_INLINE_ bool is_connected_to_prev(char32_t p_chr, char32_t p_pchr) { /*************************************************************************/ +bool TextServerAdvanced::icu_data_loaded = false; + bool TextServerAdvanced::_has_feature(Feature p_feature) const { switch (p_feature) { case FEATURE_SIMPLE_LAYOUT: @@ -6599,5 +6601,6 @@ TextServerAdvanced::~TextServerAdvanced() { uset_close(allowed); allowed = nullptr; } - u_cleanup(); + + std::atexit(u_cleanup); } diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 02244a294e..f092fa8cca 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -158,7 +158,7 @@ class TextServerAdvanced : public TextServerExtension { // ICU support data. - bool icu_data_loaded = false; + static bool icu_data_loaded; mutable USet *allowed = nullptr; mutable USpoofChecker *sc_spoof = nullptr; mutable USpoofChecker *sc_conf = nullptr; -- cgit v1.2.3 From f55c61d6011551eb1ca4eb840ff2b3ccc62a5fcb Mon Sep 17 00:00:00 2001 From: Nicholas Huelin <62965063+SirQuartz@users.noreply.github.com> Date: Wed, 22 Feb 2023 05:33:04 -0500 Subject: Modify the default theme GraphNode close_h_offset Modifies the close_h_offset to be 12 instead of 22. This better aligns the default position. (cherry picked from commit 961d6763fbfca8b94565079b3c15606bdac9b7c8) --- doc/classes/GraphNode.xml | 2 +- scene/resources/default_theme/default_theme.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/classes/GraphNode.xml b/doc/classes/GraphNode.xml index 8c0e8dc3c3..f97fc78b23 100644 --- a/doc/classes/GraphNode.xml +++ b/doc/classes/GraphNode.xml @@ -342,7 +342,7 @@ Color of the title text. - + The vertical offset of the close button. diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 7a865691d9..cc606b5b88 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -720,7 +720,7 @@ void fill_default_theme(Ref &theme, const Ref &default_font, const theme->set_constant("title_offset", "GraphNode", 26 * scale); theme->set_constant("title_h_offset", "GraphNode", 0); theme->set_constant("close_offset", "GraphNode", 22 * scale); - theme->set_constant("close_h_offset", "GraphNode", 22 * scale); + theme->set_constant("close_h_offset", "GraphNode", 12 * scale); theme->set_constant("port_offset", "GraphNode", 0); // Tree -- cgit v1.2.3 From 1d21652f80458d73394f7fb8e4cf1cf907a098da Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 2 Mar 2023 10:25:50 +0200 Subject: [Linux/X11] Check if required xkb functions exist before using it. (cherry picked from commit 8a675f3824db71f0fc3268a95b73af3a50800c2f) --- platform/linuxbsd/x11/display_server_x11.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index dff2f536a8..d1f1115aad 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -5258,6 +5258,9 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode } #ifdef XKB_ENABLED xkb_loaded = (initialize_xkbcommon(dylibloader_verbose) == 0); + if (!xkb_context_new || !xkb_compose_table_new_from_locale || !xkb_compose_table_unref || !xkb_context_unref || !xkb_compose_state_feed || !xkb_compose_state_unref || !xkb_compose_state_new || !xkb_compose_state_get_status || !xkb_compose_state_get_utf8 || !xkb_keysym_to_utf32 || !xkb_keysym_to_upper) { + xkb_loaded = false; + } #endif if (initialize_xext(dylibloader_verbose) != 0) { r_error = ERR_UNAVAILABLE; -- cgit v1.2.3 From 5662542526f95c57cb43c72e8f9804cdb2cd8906 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Tue, 7 Mar 2023 10:33:48 -0800 Subject: Avoid copying CanvasTexture when updating proxy (cherry picked from commit 84482ef90bf5f902f14594d957af8c0e3866f88c) --- drivers/gles3/storage/texture_storage.cpp | 2 ++ servers/rendering/renderer_rd/storage_rd/texture_storage.cpp | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index ce66943328..dae722186c 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -832,6 +832,8 @@ void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { tex->is_render_target = false; tex->is_proxy = true; tex->proxies.clear(); + tex->canvas_texture = nullptr; + tex->tex_id = 0; proxy_to->proxies.push_back(p_texture); } diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 50b324a9fd..a1346661e1 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -1193,6 +1193,9 @@ void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { prev_tex->proxies.erase(p_texture); } + // Copy canvas_texture so it doesn't leak. + CanvasTexture *canvas_texture = tex->canvas_texture; + *tex = *proxy_to; tex->proxy_to = p_proxy_to; @@ -1200,6 +1203,7 @@ void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) { tex->is_proxy = true; tex->proxies.clear(); proxy_to->proxies.push_back(p_texture); + tex->canvas_texture = canvas_texture; tex->rd_view.format_override = tex->rd_format; tex->rd_texture = RD::get_singleton()->texture_create_shared(tex->rd_view, proxy_to->rd_texture); -- cgit v1.2.3 From 2d0d07f51b5caf16d43eab7e8526250e371942d5 Mon Sep 17 00:00:00 2001 From: Haoyu Qiu Date: Wed, 8 Mar 2023 12:30:37 +0800 Subject: Fix crash when dumping extension API in a non-writable directory (cherry picked from commit 49400e0c1c2c745942133cd63daefad82608958c) --- core/extension/extension_api_dump.cpp | 1 + core/extension/make_interface_dumper.py | 1 + 2 files changed, 2 insertions(+) diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index e26ead6d8c..79b0ebc641 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -1052,6 +1052,7 @@ void GDExtensionAPIDump::generate_extension_json_file(const String &p_path) { String text = json->stringify(api, "\t", false) + "\n"; Ref fa = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); fa->store_string(text); } diff --git a/core/extension/make_interface_dumper.py b/core/extension/make_interface_dumper.py index a8af0e9ff6..a604112d13 100644 --- a/core/extension/make_interface_dumper.py +++ b/core/extension/make_interface_dumper.py @@ -27,6 +27,7 @@ class GDExtensionInterfaceDump { public: static void generate_gdextension_interface_file(const String &p_path) { Ref fa = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_MSG(fa.is_null(), vformat("Cannot open file '%s' for writing.", p_path)); CharString cs(gdextension_interface_dump); fa->store_buffer((const uint8_t *)cs.ptr(), cs.length()); }; -- cgit v1.2.3 From 755a86f5025e9166e3c5b140d0bf5650166f0db1 Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Tue, 7 Mar 2023 15:31:19 +0100 Subject: Generate empty textures for theme icons if the SVG module is disabled (cherry picked from commit 64215ad1192878b72e784c5a62ea9b2dba0520dd) --- editor/editor_themes.cpp | 16 ++++++++++------ scene/resources/default_theme/default_theme.cpp | 4 ++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 2ab15c1c2c..3e6b0ee07f 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -231,11 +231,11 @@ static Ref make_line_stylebox(Color p_color, int p_thickness = 1, return style; } -#ifdef MODULE_SVG_ENABLED // See also `generate_icon()` in `scene/resources/default_theme.cpp`. static Ref editor_generate_icon(int p_index, float p_scale, float p_saturation, const HashMap &p_convert_colors = HashMap()) { Ref img = memnew(Image); +#ifdef MODULE_SVG_ENABLED // Upsample icon generation only if the editor scale isn't an integer multiplier. // Generating upsampled icons is slower, and the benefit is hardly visible // with integer editor scales. @@ -246,13 +246,16 @@ static Ref editor_generate_icon(int p_index, float p_scale, float if (p_saturation != 1.0) { img->adjust_bcs(1.0, 1.0, p_saturation); } +#else + // If the SVG module is disabled, we can't really display the UI well, but at least we won't crash. + // 16 pixels is used as it's the most common base size for Godot icons. + img = Image::create_empty(16 * p_scale, 16 * p_scale, false, Image::FORMAT_RGBA8); +#endif return ImageTexture::create_from_image(img); } -#endif void editor_register_and_generate_icons(Ref p_theme, bool p_dark_theme, float p_icon_saturation, int p_thumb_size, bool p_only_thumbs = false) { -#ifdef MODULE_SVG_ENABLED // Before we register the icons, we adjust their colors and saturation. // Most icons follow the standard rules for color conversion to follow the editor // theme's polarity (dark/light). We also adjust the saturation for most icons, @@ -379,9 +382,6 @@ void editor_register_and_generate_icons(Ref p_theme, bool p_dark_theme, f p_theme->set_icon(editor_icons_names[index], SNAME("EditorIcons"), icon); } } -#else - WARN_PRINT("SVG support disabled, editor icons won't be rendered."); -#endif } Ref create_editor_theme(const Ref p_theme) { @@ -618,6 +618,10 @@ Ref create_editor_theme(const Ref p_theme) { regenerate_thumb_icons = !Math::is_equal_approx(prev_thumb_size, thumb_size); } +#ifndef MODULE_SVG_ENABLED + WARN_PRINT("SVG support disabled, editor icons won't be rendered."); +#endif + if (keep_old_icons) { for (int i = 0; i < editor_icons_count; i++) { theme->set_icon(editor_icons_names[i], SNAME("EditorIcons"), p_theme->get_icon(editor_icons_names[i], SNAME("EditorIcons"))); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index cc606b5b88..2e1ba96d11 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -86,6 +86,10 @@ static Ref generate_icon(int p_index) { ImageLoaderSVG img_loader; Error err = img_loader.create_image_from_string(img, default_theme_icons_sources[p_index], scale, upsample, HashMap()); ERR_FAIL_COND_V_MSG(err != OK, Ref(), "Failed generating icon, unsupported or invalid SVG data in default theme."); +#else + // If the SVG module is disabled, we can't really display the UI well, but at least we won't crash. + // 16 pixels is used as it's the most common base size for Godot icons. + img = Image::create_empty(16 * scale, 16 * scale, false, Image::FORMAT_RGBA8); #endif return ImageTexture::create_from_image(img); -- cgit v1.2.3 From 41f4068a6e81f5f0e94428ddc04330f6a154ee70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Fertyk?= Date: Sun, 6 Nov 2022 13:02:16 +0100 Subject: Fix RichTextLabel crash with out of bound exception Fixes #68242. (cherry picked from commit 44592c8c197b072d5beee3f14c9c6869a94e9671) --- scene/gui/rich_text_label.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 44478d45cc..ec1fbb7e28 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2375,7 +2375,7 @@ int RichTextLabel::_find_list(Item *p_item, Vector &r_index, Vectorline + 1; i <= prev_item->line; i++) { + for (int i = list->line + 1; i <= prev_item->line && i < (int)frame->lines.size(); i++) { if (_find_list_item(frame->lines[i].from) == list) { index++; } -- cgit v1.2.3 From 7490f892387662bc14b77b4992fe66a9c678fb5c Mon Sep 17 00:00:00 2001 From: Hayden Leete Date: Wed, 8 Mar 2023 19:22:58 +1300 Subject: Fix crash when revealing file in floating FileSystem Dock When selecting "Show in FileSystem" from the context menu of a resource in the inspector, the engine would crash if the FileSystem dock was floating because it was trying to focus the FileSystem tab, but floating docks don't use Tab Containers. This commit makes the FileSystem dock's window grab focus instead if it's floating. (cherry picked from commit c4d1513e15e1f3e599030a98cf425177c3d1eb24) --- editor/editor_resource_picker.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 86ffbccefd..a83db21f20 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -399,8 +399,12 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) { file_system_dock->navigate_to_path(edited_resource->get_path()); // Ensure that the FileSystem dock is visible. - TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); - tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); + if (file_system_dock->get_window() == get_tree()->get_root()) { + TabContainer *tab_container = (TabContainer *)file_system_dock->get_parent_control(); + tab_container->set_current_tab(tab_container->get_tab_idx_from_control(file_system_dock)); + } else { + file_system_dock->get_window()->grab_focus(); + } } break; default: { -- cgit v1.2.3 From 048c252602aa9e21175b7e125dbcae204e303b1f Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Wed, 8 Mar 2023 19:46:55 +0100 Subject: Prevent cache corruption when saving resources in the editor (cherry picked from commit 496bd94c21dbda01fc7d9d0a108eecef21924024) --- editor/editor_node.cpp | 17 +++++++++++++++++ editor/editor_node.h | 1 + modules/gdscript/gdscript.cpp | 6 ++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6fcf092834..2834a086b8 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -1233,6 +1233,12 @@ void EditorNode::edit_resource(const Ref &p_resource) { void EditorNode::save_resource_in_path(const Ref &p_resource, const String &p_path) { editor_data.apply_changes_in_editors(); + + if (saving_resources_in_path.has(p_resource)) { + return; + } + saving_resources_in_path.insert(p_resource); + int flg = 0; if (EDITOR_GET("filesystem/on_save/compress_binary_resources")) { flg |= ResourceSaver::FLAG_COMPRESS; @@ -1247,10 +1253,16 @@ void EditorNode::save_resource_in_path(const Ref &p_resource, const St } else { show_accept(TTR("Error saving resource!"), TTR("OK")); } + + saving_resources_in_path.erase(p_resource); return; } ((Resource *)p_resource.ptr())->set_path(path); + saving_resources_in_path.erase(p_resource); + + _resource_saved(p_resource, path); + emit_signal(SNAME("resource_saved"), p_resource); editor_data.notify_resource_saved(p_resource); } @@ -6441,6 +6453,11 @@ void EditorNode::_renderer_selected(int p_which) { } void EditorNode::_resource_saved(Ref p_resource, const String &p_path) { + if (singleton->saving_resources_in_path.has(p_resource)) { + // This is going to be handled by save_resource_in_path when the time is right. + return; + } + if (EditorFileSystem::get_singleton()) { EditorFileSystem::get_singleton()->update_file(p_path); } diff --git a/editor/editor_node.h b/editor/editor_node.h index 8ad5969249..6a9d052791 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -485,6 +485,7 @@ private: Object *current = nullptr; Ref saving_resource; + HashSet> saving_resources_in_path; uint64_t update_spinner_step_msec = 0; uint64_t update_spinner_step_frame = 0; diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index b6caefbdb5..1a1d021dbc 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1010,12 +1010,14 @@ void GDScript::_bind_methods() { } void GDScript::set_path(const String &p_path, bool p_take_over) { - String old_path = path; if (is_root_script()) { Script::set_path(p_path, p_take_over); } - this->path = p_path; + + String old_path = path; + path = p_path; GDScriptCache::move_script(old_path, p_path); + for (KeyValue> &kv : subclasses) { kv.value->set_path(p_path, p_take_over); } -- cgit v1.2.3 From d83245f2f94410768016899df91ce3134091bb7b Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Fri, 10 Mar 2023 09:10:12 +0200 Subject: [TextServer] Add invalid font scaling check, restrict Linux/BSD system fonts lookup to TrueType/CFF only. (cherry picked from commit 8d501a2dc31f3bef6d5a7f6b0d060c8915082011) --- modules/text_server_adv/text_server_adv.cpp | 4 +- modules/text_server_fb/text_server_fb.cpp | 4 +- platform/linuxbsd/os_linuxbsd.cpp | 137 +++++++++++++++------------- 3 files changed, 79 insertions(+), 66 deletions(-) diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 007f439a89..50aea3da2e 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -1386,7 +1386,9 @@ _FORCE_INLINE_ bool TextServerAdvanced::_ensure_cache_for_size(FontAdvanced *p_f FT_Select_Size(fd->face, best_match); } else { FT_Set_Pixel_Sizes(fd->face, 0, double(fd->size.x * fd->oversampling)); - fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + if (fd->face->size->metrics.y_ppem != 0) { + fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + } } fd->hb_handle = hb_ft_font_create(fd->face, nullptr); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 240ae8310a..d67ae6b45b 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -825,7 +825,9 @@ _FORCE_INLINE_ bool TextServerFallback::_ensure_cache_for_size(FontFallback *p_f FT_Select_Size(fd->face, best_match); } else { FT_Set_Pixel_Sizes(fd->face, 0, Math::round(fd->size.x * fd->oversampling)); - fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + if (fd->face->size->metrics.y_ppem != 0) { + fd->scale = ((double)fd->size.x * fd->oversampling) / (double)fd->face->size->metrics.y_ppem; + } } fd->ascent = (fd->face->size->metrics.ascender / 64.0) / fd->oversampling * fd->scale; diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 54bb34ef73..88c3d2cc14 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -677,40 +677,45 @@ Vector OS_LinuxBSD::get_system_font_path_for_text(const String &p_font_n } Vector ret; - FcPattern *pattern = FcPatternCreate(); - if (pattern) { - FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); - FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); - FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); - FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); - - FcCharSet *char_set = FcCharSetCreate(); - for (int i = 0; i < p_text.size(); i++) { - FcCharSetAddChar(char_set, p_text[i]); - } - FcPatternAddCharSet(pattern, FC_CHARSET, char_set); - - FcLangSet *lang_set = FcLangSetCreate(); - FcLangSetAdd(lang_set, reinterpret_cast(p_locale.utf8().get_data())); - FcPatternAddLangSet(pattern, FC_LANG, lang_set); - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - FcResult result; - FcPattern *match = FcFontMatch(0, pattern, &result); - if (match) { - char *file_name = nullptr; - if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { - if (file_name) { - ret.push_back(String::utf8(file_name)); + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast(allowed_formats[i])); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); + FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + + FcCharSet *char_set = FcCharSetCreate(); + for (int j = 0; j < p_text.size(); j++) { + FcCharSetAddChar(char_set, p_text[j]); + } + FcPatternAddCharSet(pattern, FC_CHARSET, char_set); + + FcLangSet *lang_set = FcLangSetCreate(); + FcLangSetAdd(lang_set, reinterpret_cast(p_locale.utf8().get_data())); + FcPatternAddLangSet(pattern, FC_LANG, lang_set); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { + if (file_name) { + ret.push_back(String::utf8(file_name)); + } } + FcPatternDestroy(match); } - FcPatternDestroy(match); + FcPatternDestroy(pattern); + FcCharSetDestroy(char_set); + FcLangSetDestroy(lang_set); } - FcPatternDestroy(pattern); - FcCharSetDestroy(char_set); - FcLangSetDestroy(lang_set); } return ret; @@ -725,47 +730,51 @@ String OS_LinuxBSD::get_system_font_path(const String &p_font_name, int p_weight ERR_FAIL_V_MSG(String(), "Unable to load fontconfig, system font support is disabled."); } - String ret; - FcPattern *pattern = FcPatternCreate(); - if (pattern) { - bool allow_substitutes = (p_font_name.to_lower() == "sans-serif") || (p_font_name.to_lower() == "serif") || (p_font_name.to_lower() == "monospace") || (p_font_name.to_lower() == "cursive") || (p_font_name.to_lower() == "fantasy"); - - FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); - FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); - FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); - FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); - FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); - - FcConfigSubstitute(0, pattern, FcMatchPattern); - FcDefaultSubstitute(pattern); - - FcResult result; - FcPattern *match = FcFontMatch(0, pattern, &result); - if (match) { - if (!allow_substitutes) { - char *family_name = nullptr; - if (FcPatternGetString(match, FC_FAMILY, 0, reinterpret_cast(&family_name)) == FcResultMatch) { - if (family_name && String::utf8(family_name).to_lower() != p_font_name.to_lower()) { + static const char *allowed_formats[] = { "TrueType", "CFF" }; + for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) { + FcPattern *pattern = FcPatternCreate(); + if (pattern) { + bool allow_substitutes = (p_font_name.to_lower() == "sans-serif") || (p_font_name.to_lower() == "serif") || (p_font_name.to_lower() == "monospace") || (p_font_name.to_lower() == "cursive") || (p_font_name.to_lower() == "fantasy"); + + FcPatternAddBool(pattern, FC_SCALABLE, FcTrue); + FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast(allowed_formats[i])); + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast(p_font_name.utf8().get_data())); + FcPatternAddInteger(pattern, FC_WEIGHT, _weight_to_fc(p_weight)); + FcPatternAddInteger(pattern, FC_WIDTH, _stretch_to_fc(p_stretch)); + FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + if (match) { + if (!allow_substitutes) { + char *family_name = nullptr; + if (FcPatternGetString(match, FC_FAMILY, 0, reinterpret_cast(&family_name)) == FcResultMatch) { + if (family_name && String::utf8(family_name).to_lower() != p_font_name.to_lower()) { + FcPatternDestroy(match); + FcPatternDestroy(pattern); + continue; + } + } + } + char *file_name = nullptr; + if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { + if (file_name) { + String ret = String::utf8(file_name); FcPatternDestroy(match); FcPatternDestroy(pattern); - - return String(); + return ret; } } + FcPatternDestroy(match); } - char *file_name = nullptr; - if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast(&file_name)) == FcResultMatch) { - if (file_name) { - ret = String::utf8(file_name); - } - } - - FcPatternDestroy(match); + FcPatternDestroy(pattern); } - FcPatternDestroy(pattern); } - return ret; + return String(); #else ERR_FAIL_V_MSG(String(), "Godot was compiled without fontconfig, system font support is disabled."); #endif -- cgit v1.2.3 From 3c2e952889e5a75b97b0750dc714af181a79eeb7 Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Tue, 7 Mar 2023 19:10:54 +0100 Subject: Prevent crashing on startup if project has scripted theme types Also avoid order of operation conflicts by moving C# binding generation hook to main.cpp (cherry picked from commit 8402927d3f55f06651045a6a94e163327e26c2ab) --- main/main.cpp | 17 ++++++++++++++++- modules/mono/csharp_script.cpp | 8 -------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index b15588e700..f4d2dbef52 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -108,6 +108,10 @@ #include "modules/modules_enabled.gen.h" // For mono. +#if defined(MODULE_MONO_ENABLED) && defined(TOOLS_ENABLED) +#include "modules/mono/editor/bindings_generator.h" +#endif + /* Static members */ // Singletons @@ -312,7 +316,6 @@ void finalize_navigation_server() { void initialize_theme_db() { theme_db = memnew(ThemeDB); - theme_db->initialize_theme(); } void finalize_theme_db() { @@ -532,6 +535,7 @@ Error Main::test_setup() { // Theme needs modules to be initialized so that sub-resources can be loaded. initialize_theme_db(); + theme_db->initialize_theme(); register_scene_singletons(); ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE); @@ -2314,6 +2318,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { register_platform_apis(); // Theme needs modules to be initialized so that sub-resources can be loaded. + // Default theme is initialized later, after ScriptServer is ready. initialize_theme_db(); register_scene_singletons(); @@ -2341,8 +2346,18 @@ Error Main::setup2(Thread::ID p_main_tid_override) { // This loads global classes, so it must happen before custom loaders and savers are registered ScriptServer::init_languages(); + theme_db->initialize_theme(); audio_server->load_default_bus_layout(); +#if defined(MODULE_MONO_ENABLED) && defined(TOOLS_ENABLED) + // Hacky to have it here, but we don't have good facility yet to let modules + // register command line options to call at the right time. This needs to happen + // after init'ing the ScriptServer, but also after init'ing the ThemeDB, + // for the C# docs generation in the bindings. + List cmdline_args = OS::get_singleton()->get_cmdline_args(); + BindingsGenerator::handle_cmdline_args(cmdline_args); +#endif + if (use_debug_profiler && EngineDebugger::is_active()) { // Start the "scripts" profiler, used in local debugging. // We could add more, and make the CLI arg require a comma-separated list of profilers. diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 872e803b9c..9159f308a2 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -42,7 +42,6 @@ #ifdef TOOLS_ENABLED #include "core/os/keyboard.h" -#include "editor/bindings_generator.h" #include "editor/editor_internal_calls.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" @@ -102,13 +101,6 @@ void CSharpLanguage::init() { } #endif -#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) - // Generate the bindings here, before loading assemblies. The Godot assemblies - // may be missing if the glue wasn't generated yet in order to build them. - List cmdline_args = OS::get_singleton()->get_cmdline_args(); - BindingsGenerator::handle_cmdline_args(cmdline_args); -#endif - GLOBAL_DEF("dotnet/project/assembly_name", ""); #ifdef TOOLS_ENABLED GLOBAL_DEF("dotnet/project/solution_directory", ""); -- cgit v1.2.3 From 234c601a61d7ec5c0165fa6cb277fae430557e88 Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Tue, 7 Mar 2023 17:22:58 +0100 Subject: Improve logic related to editing audio buses (and prevent crashes) (cherry picked from commit 68c18c0e2b8cb7c0e0f850f9bbdde31e30d166cf) --- editor/editor_audio_buses.cpp | 44 +++++++++++++++++++++++++++++++++++++------ editor/editor_audio_buses.h | 3 +++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index ed7638414c..ece5537ff3 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -257,7 +257,14 @@ void EditorAudioBus::update_bus() { } void EditorAudioBus::_name_changed(const String &p_new_name) { + if (updating_bus) { + return; + } + updating_bus = true; + track_name->release_focus(); + if (p_new_name == AudioServer::get_singleton()->get_bus_name(get_index())) { + updating_bus = false; return; } @@ -280,12 +287,15 @@ void EditorAudioBus::_name_changed(const String &p_new_name) { attempts++; attempt = p_new_name + " " + itos(attempts); } - updating_bus = true; EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); StringName current = AudioServer::get_singleton()->get_bus_name(get_index()); + ur->create_action(TTR("Rename Audio Bus")); + ur->add_do_method(buses, "_set_renaming_buses", true); + ur->add_undo_method(buses, "_set_renaming_buses", true); + ur->add_do_method(AudioServer::get_singleton(), "set_bus_name", get_index(), attempt); ur->add_undo_method(AudioServer::get_singleton(), "set_bus_name", get_index(), current); @@ -301,11 +311,12 @@ void EditorAudioBus::_name_changed(const String &p_new_name) { ur->add_do_method(buses, "_update_sends"); ur->add_undo_method(buses, "_update_sends"); + + ur->add_do_method(buses, "_set_renaming_buses", false); + ur->add_undo_method(buses, "_set_renaming_buses", false); ur->commit_action(); updating_bus = false; - - track_name->release_focus(); } void EditorAudioBus::_volume_changed(float p_normalized) { @@ -995,12 +1006,31 @@ void EditorAudioBusDrop::_bind_methods() { EditorAudioBusDrop::EditorAudioBusDrop() { } +void EditorAudioBuses::_set_renaming_buses(bool p_renaming) { + renaming_buses = p_renaming; +} + void EditorAudioBuses::_update_buses() { - while (bus_hb->get_child_count() > 0) { - memdelete(bus_hb->get_child(0)); + if (renaming_buses) { + // This case will be handled more gracefully, no need to trigger a full rebuild. + // This is possibly a mistake in the AudioServer, which fires bus_layout_changed + // on a rename. This may not be intended, but no way to tell at the moment. + return; } - drop_end = nullptr; + for (int i = bus_hb->get_child_count() - 1; i >= 0; i--) { + EditorAudioBus *audio_bus = Object::cast_to(bus_hb->get_child(i)); + if (audio_bus) { + bus_hb->remove_child(audio_bus); + audio_bus->queue_free(); + } + } + + if (drop_end) { + bus_hb->remove_child(drop_end); + drop_end->queue_free(); + drop_end = nullptr; + } for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) { bool is_master = (i == 0); @@ -1033,6 +1063,7 @@ void EditorAudioBuses::_notification(int p_what) { case NOTIFICATION_DRAG_END: { if (drop_end) { + bus_hb->remove_child(drop_end); drop_end->queue_free(); drop_end = nullptr; } @@ -1259,6 +1290,7 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) { } void EditorAudioBuses::_bind_methods() { + ClassDB::bind_method("_set_renaming_buses", &EditorAudioBuses::_set_renaming_buses); ClassDB::bind_method("_update_buses", &EditorAudioBuses::_update_buses); ClassDB::bind_method("_update_bus", &EditorAudioBuses::_update_bus); ClassDB::bind_method("_update_sends", &EditorAudioBuses::_update_sends); diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h index 8a7f9b6456..9ff5afac66 100644 --- a/editor/editor_audio_buses.h +++ b/editor/editor_audio_buses.h @@ -172,6 +172,9 @@ class EditorAudioBuses : public VBoxContainer { Timer *save_timer = nullptr; String edited_path; + bool renaming_buses = false; + void _set_renaming_buses(bool p_renaming); + void _add_bus(); void _update_buses(); void _update_bus(int p_index); -- cgit v1.2.3 From 0112862e70819f700fd86104a136795fcbe1c80e Mon Sep 17 00:00:00 2001 From: RedworkDE <10944644+RedworkDE@users.noreply.github.com> Date: Tue, 28 Feb 2023 22:08:19 +0100 Subject: C#: Fix crash when errors occur before language initialization. (cherry picked from commit c0ebc281360c7df1acae4b0510d8310573491acc) --- modules/mono/csharp_script.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 9159f308a2..aad8ab9a57 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -581,7 +581,7 @@ Vector CSharpLanguage::debug_get_current_stack_info() _recursion_flag_ = false; }; - if (!gdmono->is_runtime_initialized()) { + if (!gdmono || !gdmono->is_runtime_initialized()) { return Vector(); } @@ -671,6 +671,7 @@ void CSharpLanguage::reload_tool_script(const Ref