-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect layout for custom MeasureFunction nodes caused by stale available width information #1784
Comments
A unit test here causing the failure might also be helpful, asserting what measure function sees. Off the top of my head though, I know:
|
We tried disabling canUseCachedMeasurement (always return false) and forcing flex basis to always be recomputed in computeFlexBasisForChild at the same time before reporting this issue here, unfortunately it was not sufficient to stop the repro. Perhaps a good unit test would be to make sure that computed innerWidth (the one passed to custom MeasureFunction) is consistent when an ancestor node is resized before and after the node below the ancestor is marked dirty. That could be the current issue - it is not sufficient to mark just the resized ancestor node dirty for all information to be available for correct recomputation of e.g. flexBasis of a descendant node, maybe an extra condition is that between that ancestor and descendant are multiple nodes with % width dimensions and fixed paddings |
Sometimes in our app when the panel is resize slowly from width 140 to width 180 the text with wrapping enabled gets MeasureFunction invoked with incorrect width (e.g. for panel width 140 it is called with 120 (correct), 160 is called with 140 (correct), 161 is called with 121 (incorrect). There are other elements inbetween, and it is inside a 35 percent width container, so I could imagine it is a difficult scenario to support for the algorithm.
It is fixed by setting
bool needToVisitNode
to true unconditionally (but obviously that destroys performance).It is also fixed by marking dirty all the descendant wrapping text elements of the resized panel (but it is annoying as it means iterating whole tree below them to find all the wrapping texts).
Finally we were able to fix it with what feels a bit more proper of a solution: we propagate
bool sizeChange
through the function calls starting atcalculateLayoutInternal
, it starts withfalse
, but if we meet any node along the recursion that has its style's dimensions changed, we set it to true, and from there on always visit nodes in that recursion chain. We update the layout's LastWidth and LastHeight in the same place LastOwnerDirection is currently getting updated.We have not noticed noticeable performance degradation, however we do not have many resizing scenarios (no animations yet). So we remain sceptical to that fix, and would love if someone from the team would take a look and evaluate it.
We are sorry for no minimal repro, we tried using the Yoga playground, however it does not allow usage of percentage dimensions, which we believe is crucial for the repro which involves a container X with percentage width dimension, and inside it are fixed width spacer followed by wrapping text, and the parent of X gets resized (and gets marked dirty), however it is not sufficient to cause Yoga without this new fix to update the wrapping text correctly every time (as mentioned, rare times the measure function is called with outdated available width, also known as inner width). We tried disabling caching for custom measure function node, always vising wrapping texts and other cheaper fixes, but none of them are sufficient.
The text was updated successfully, but these errors were encountered: