From 5682cc7b8116d98435a22bc85091859f6545d54e Mon Sep 17 00:00:00 2001 From: aaronp64 Date: Fri, 12 Jul 2024 16:57:33 -0400 Subject: [PATCH] Avoid FlowContainer crash with TextureRect using EXPAND_FIT_* expand modes When a FlowContainer had a TextureRect child using any of the EXPAND_FIT_* expand modes, it could crash when changing the FlowContainer's minimum size, or that of its children. This was due to the TextureRect resizing in FlowContainer::_resort, updating its minimum size, and triggering another _resort. If the TextureRect's minimum size changed in a way that caused any of the FlowContainer's children to be put on a different line, it could repeatedly cause _resort to be called again, moving the children back and forth between the old and new lines. This change is for FlowContainer::_resort to give a warning for TextureRects with EXPAND_FIT_* expand modes when multiple lines are used, and just keep the TextureRect size the same in that case. This is similar to the check added to AspectRatioContainer in godotengine#73396, but attempting to still support it in FlowContainer when possible. In the case where the TextureRect is forced to stay the same size, there may be some overlap between the FlowContainer's children, but should no longer crash. --- scene/gui/flow_container.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/scene/gui/flow_container.cpp b/scene/gui/flow_container.cpp index f77d66fe98c..6810de12eb9 100644 --- a/scene/gui/flow_container.cpp +++ b/scene/gui/flow_container.cpp @@ -30,6 +30,7 @@ #include "flow_container.h" +#include "scene/gui/texture_rect.h" #include "scene/theme/theme_db.h" struct _LineData { @@ -203,7 +204,23 @@ void FlowContainer::_resort() { } } - if (vertical) { /* VERTICAL */ + bool is_unsupported_texture_rect = false; + if (lines_data.size() > 1) { + TextureRect *trect = Object::cast_to(child); + if (trect) { + TextureRect::ExpandMode mode = trect->get_expand_mode(); + if (mode == TextureRect::EXPAND_FIT_WIDTH || mode == TextureRect::EXPAND_FIT_WIDTH_PROPORTIONAL || + mode == TextureRect::EXPAND_FIT_HEIGHT || mode == TextureRect::EXPAND_FIT_HEIGHT_PROPORTIONAL) { + is_unsupported_texture_rect = true; + } + } + } + + if (is_unsupported_texture_rect) { + // Temporary fix for editor crash. Changing size of TextureRect with EXPAND_FIT_* ExpandModes can lead to infinite loop if child items are moved between lines. + WARN_PRINT_ONCE("TextureRects with Fit Expand Modes are currently not supported inside FlowContainers with multiple lines"); + child_size = child->get_size(); + } else if (vertical) { /* VERTICAL */ if (child->get_h_size_flags().has_flag(SIZE_FILL) || child->get_h_size_flags().has_flag(SIZE_SHRINK_CENTER) || child->get_h_size_flags().has_flag(SIZE_SHRINK_END)) { child_size.width = line_data.min_line_height; }