Skip to content

Commit

Permalink
Port fix for VSP floating-point hang from 4.8 (#4979)
Browse files Browse the repository at this point in the history
  • Loading branch information
SamBent authored Aug 17, 2021
1 parent 9fb0601 commit a12e85c
Showing 1 changed file with 30 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -931,16 +931,19 @@ private void OnAnchorOperation(bool isAnchorOperationPending)
// situations where the viewport size has changed)
if (!success)
{
double computedOffset, maxOffset;
if (isHorizontal)
{
success = DoubleUtil.GreaterThanOrClose(_scrollData._computedOffset.X,
_scrollData._extent.Width - _scrollData._viewport.Width);
computedOffset = _scrollData._computedOffset.X;
maxOffset = _scrollData._extent.Width - _scrollData._viewport.Width;
}
else
{
success = DoubleUtil.GreaterThanOrClose(_scrollData._computedOffset.Y,
_scrollData._extent.Height - _scrollData._viewport.Height);
computedOffset = _scrollData._computedOffset.Y;
maxOffset = _scrollData._extent.Height - _scrollData._viewport.Height;
}
success = LayoutDoubleUtil.LessThan(maxOffset, computedOffset) ||
LayoutDoubleUtil.AreClose(maxOffset, computedOffset);
}
}
}
Expand Down Expand Up @@ -973,21 +976,22 @@ private void OnAnchorOperation(bool isAnchorOperationPending)
else
{
bool remeasure = false;
double actualOffset, expectedOffset;
double actualOffset, expectedOffset, maxOffset;

if (isHorizontal)
{
_scrollData._computedOffset.X = prevFirstContainerOffset - prevFirstContainerOffsetFromViewport;

actualOffset = _scrollData._computedOffset.X + actualDistanceBetweenViewports;
expectedOffset = _scrollData._computedOffset.X + _scrollData._expectedDistanceBetweenViewports;
maxOffset = _scrollData._extent.Width - _scrollData._viewport.Width;

if (DoubleUtil.LessThan(expectedOffset, 0) || DoubleUtil.GreaterThan(expectedOffset, _scrollData._extent.Width - _scrollData._viewport.Width))
if (LayoutDoubleUtil.LessThan(expectedOffset, 0) || LayoutDoubleUtil.LessThan(maxOffset, expectedOffset))
{
// the condition can fail due to estimated sizes in subtrees that contribute
// to FindScrollOffset(_scrollData._firstContainerInViewport) but not to
// _scrollData._extent. If that happens, remeasure.
if (DoubleUtil.AreClose(actualOffset, 0) || DoubleUtil.AreClose(actualOffset, _scrollData._extent.Width - _scrollData._viewport.Width))
if (LayoutDoubleUtil.AreClose(actualOffset, 0) || LayoutDoubleUtil.AreClose(actualOffset, maxOffset))
{
_scrollData._computedOffset.X = actualOffset;
_scrollData._offset.X = actualOffset;
Expand All @@ -1010,13 +1014,14 @@ private void OnAnchorOperation(bool isAnchorOperationPending)

actualOffset = _scrollData._computedOffset.Y + actualDistanceBetweenViewports;
expectedOffset = _scrollData._computedOffset.Y + _scrollData._expectedDistanceBetweenViewports;
maxOffset = _scrollData._extent.Height - _scrollData._viewport.Height;

if (DoubleUtil.LessThan(expectedOffset, 0) || DoubleUtil.GreaterThan(expectedOffset, _scrollData._extent.Height - _scrollData._viewport.Height))
if (LayoutDoubleUtil.LessThan(expectedOffset, 0) || LayoutDoubleUtil.LessThan(maxOffset, expectedOffset))
{
// the condition can fail due to estimated sizes in subtrees that contribute
// to FindScrollOffset(_scrollData._firstContainerInViewport) but not to
// _scrollData._extent. If that happens, remeasure.
if (DoubleUtil.AreClose(actualOffset, 0) || DoubleUtil.AreClose(actualOffset, _scrollData._extent.Height - _scrollData._viewport.Height))
if (LayoutDoubleUtil.AreClose(actualOffset, 0) || LayoutDoubleUtil.AreClose(actualOffset, maxOffset))
{
_scrollData._computedOffset.Y = actualOffset;
_scrollData._offset.Y = actualOffset;
Expand Down Expand Up @@ -2824,11 +2829,11 @@ private Size MeasureOverrideImpl(Size constraint,
ref scrollGeneration);

if (ItemsChangedDuringMeasure)
{
// if the Items collection changed, our state is now invalid. Start over.
remeasure = true;
goto EscapeMeasure;
}
{
// if the Items collection changed, our state is now invalid. Start over.
remeasure = true;
goto EscapeMeasure;
}
}
}

Expand Down Expand Up @@ -2873,11 +2878,11 @@ private Size MeasureOverrideImpl(Size constraint,
ref scrollGeneration);

if (ItemsChangedDuringMeasure)
{
// if the Items collection changed, our state is now invalid. Start over.
remeasure = true;
goto EscapeMeasure;
}
{
// if the Items collection changed, our state is now invalid. Start over.
remeasure = true;
goto EscapeMeasure;
}
}
}

Expand Down Expand Up @@ -12321,6 +12326,12 @@ private void IdentifyTrace(ItemsControl ic, VirtualizingStackPanel vsp)
"ScrollUnit:", VirtualizingPanel.GetScrollUnit(ic),
"CacheLen:", VirtualizingPanel.GetCacheLength(ic), VirtualizingPanel.GetCacheLengthUnit(ic));

DpiScale dpiScale = vsp.GetDpi();
AddTrace(null, ScrollTraceOp.ID, _nullInfo,
"DPIScale:", dpiScale.DpiScaleX, dpiScale.DpiScaleY,
"UseLayoutRounding:", vsp.UseLayoutRounding,
"Rounding Quantum:", 1.0/dpiScale.DpiScaleY);

AddTrace(null, ScrollTraceOp.ID, _nullInfo,
"CanContentScroll:", ScrollViewer.GetCanContentScroll(ic),
"IsDeferredScrolling:", ScrollViewer.GetIsDeferredScrollingEnabled(ic),
Expand Down

0 comments on commit a12e85c

Please sign in to comment.