Description

When a RetainerBox contains a child that for some reason has a desired size of zero, its OnPaint() method can incorrectly return LayerId 0. Afterwards, widgets further down the hierarchy can base their painting on that LayerId, leading to an incorrect draw z-order. This has been observed when the RetainerBox and other widgets were placed inside an Overlay widget.

The incorrect LayerId is returned by OnPaint() on the conditional branch "if (PaintResult == EPaintRetainedContentResult::TextureSizeZero)", which is true for example when the RetainerBox has a zero-sized child. In that case, the function returns GetCachedMaxLayerId(), but that value might not have had a chance to be set before that.

It seems that GetCachedMaxLayerId() is more appropriate when the RetainerBox actually draws its retained contents. Since in this case there is nothing to draw, an initial suggestion would be to instead return the same LayerId that was passed into the function by the parent.

Notes:

  • This repros on UE 5.1+ up to the latest mainline source version. Does not repro on 4.27.
  • In early versions, when the render texture had a zero dimension, OnPaint() returned the passed-in LayerId. CL 14075271 added an "InvalidSize" detection which rendered the widget as unretained (not ideal for zero-size, but worked - this is the state in 4.27). CL 14482220 separated the concept of InvalidSize into TextureSizeZero and TextureSizeTooBig. In the case of TextureSizeZero, it started returning GetCachedMaxLayerId() to avoid any rendering, but maybe returning LayerId would have been better.

 

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-352267 in the post.

0
Login to Vote

Unresolved
CreatedNov 4, 2025
UpdatedDec 8, 2025
View Jira Issue