diff --git a/tests/YGRelayoutTest.cpp b/tests/YGRelayoutTest.cpp index 01ae5c4177..54d48510f6 100644 --- a/tests/YGRelayoutTest.cpp +++ b/tests/YGRelayoutTest.cpp @@ -49,3 +49,33 @@ TEST(YogaTest, recalculate_resolvedDimonsion_onchange) { YGNodeFreeRecursive(root); } + + +YGSize _measureRecalc(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode) { + return YGSize { 0, 0}; +} + +TEST(YogaTest, recalculate_on_layout_values_change) { + const YGConfigRef config = YGConfigNew(); + YGConfigSetExperimentalFeatureEnabled(config, YGExperimentalFeatureWebFlexBasis, true); + YGConfigSetPointScaleFactor(config, 3.f); + const YGNodeRef root = YGNodeNewWithConfig(config); + YGNodeStyleSetFlexDirection(root, YGFlexDirectionRow); + YGNodeStyleSetAlignItems(root, YGAlignFlexStart); + YGNodeStyleSetAlignContent(root, YGAlignFlexStart); + const YGNodeRef child = YGNodeNewWithConfig(config); + YGNodeStyleSetMinHeightPercent(child, 40.f); + YGNodeStyleSetMaxHeightPercent(child, 60.f); + YGNodeStyleSetHeight(child, 10.f); + YGNodeStyleSetWidth(child, 50.0f); + YGNodeSetMeasureFunc(child, _measureRecalc); + YGNodeInsertChild(root, child, 0); + + YGNodeCalculateLayout(root, 50.0f, YGUndefined, YGDirectionLTR); + ASSERT_FLOAT_EQ(10, YGNodeLayoutGetHeight(child)); + + YGNodeCalculateLayout(root, 50.0f, 30.0f, YGDirectionLTR); + ASSERT_FLOAT_EQ(12, YGNodeLayoutGetHeight(child)); + + YGNodeFreeRecursive(root); +} diff --git a/yoga/YGLayout.h b/yoga/YGLayout.h index ce61204019..c97a17559a 100644 --- a/yoga/YGLayout.h +++ b/yoga/YGLayout.h @@ -39,6 +39,9 @@ struct YGLayout { uint32_t generationCount = 0; YGDirection lastOwnerDirection = YGDirectionInherit; + bool lastOwnerHadUndefinedHeight = false; + bool lastOwnerHadUndefinedWidth = false; + uint32_t nextCachedMeasurementsIndex = 0; std::array cachedMeasurements = {}; diff --git a/yoga/Yoga.cpp b/yoga/Yoga.cpp index dc04b72fb7..27cc7e1278 100644 --- a/yoga/Yoga.cpp +++ b/yoga/Yoga.cpp @@ -3867,9 +3867,14 @@ bool YGLayoutNodeInternal( depth++; + bool ownerHasUndefinedHeight = YGFloatIsUndefined(ownerHeight); + bool ownerHasUndefinedWidth = YGFloatIsUndefined(ownerWidth); + const bool needToVisitNode = (node->isDirty() && layout->generationCount != generationCount) || - layout->lastOwnerDirection != ownerDirection; + layout->lastOwnerDirection != ownerDirection || + layout->lastOwnerHadUndefinedHeight != ownerHasUndefinedHeight|| + layout->lastOwnerHadUndefinedWidth != ownerHasUndefinedWidth; if (needToVisitNode) { // Invalidate the cached results. @@ -4051,6 +4056,8 @@ bool YGLayoutNodeInternal( } layout->lastOwnerDirection = ownerDirection; + layout->lastOwnerHadUndefinedHeight = ownerHasUndefinedHeight; + layout->lastOwnerHadUndefinedWidth = ownerHasUndefinedWidth; if (cachedResults == nullptr) { if (layout->nextCachedMeasurementsIndex + 1 >