Skip to content

Commit d3cc1d4

Browse files
authored
Merge pull request #7412 from unoplatform/mergify/bp/release/beta/3.11/pr-7402
fix(calendar): Fix miscs scrolling issues (backport #7402)
2 parents 1eaf7c7 + 614fe55 commit d3cc1d4

File tree

3 files changed

+35
-14
lines changed

3 files changed

+35
-14
lines changed

src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement_EffectiveViewport.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,12 +1120,12 @@ public EVPTreeListener(FrameworkElement root, FrameworkElement leaf)
11201120
_root = root;
11211121
_leaf = leaf;
11221122

1123-
leaf.Loaded += ElementLoaded;
1123+
leaf.Loading += ElementLoading;
11241124
}
11251125

1126-
private void ElementLoaded(object sender, RoutedEventArgs e)
1126+
private void ElementLoading(object sender, object args)
11271127
{
1128-
_leaf.Loaded -= ElementLoaded;
1128+
_leaf.Loading -= ElementLoading;
11291129

11301130
Subscribe(sender);
11311131

@@ -1155,7 +1155,7 @@ public EVPListener Of<T>()
11551155

11561156
public void Dispose()
11571157
{
1158-
_leaf.Loaded -= ElementLoaded;
1158+
_leaf.Loading -= ElementLoading;
11591159
foreach (var listener in _listeners.Values)
11601160
{
11611161
listener.Dispose();

src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/ScrollContentPresenter.wasm.cs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -239,15 +239,6 @@ private void TryProcessScrollTo()
239239

240240
private void OnScroll(object sender, EventArgs args)
241241
{
242-
if (IsArrangeDirty && _pendingScrollTo.HasValue)
243-
{
244-
// When the native element of the SCP is becoming "valid" with a non 0 offset, it will raise a scroll event.
245-
// But if we have a manual scroll request pending, we need to mute it and wait for the next layout updated.
246-
return;
247-
}
248-
249-
_pendingScrollTo = default;
250-
251242
// We don't have any information from the DOM 'scroll' event about the intermediate vs. final state.
252243
// We could try to rely on the IsPointerPressed state to detect when the user is scrolling and use it.
253244
// This would however not include scrolling due to the inertia which should also be flagged as intermediate.
@@ -262,6 +253,21 @@ private void OnScroll(object sender, EventArgs args)
262253
var horizontalOffset = GetNativeHorizontalOffset();
263254
var verticalOffset = GetNativeVerticalOffset();
264255

256+
if (IsArrangeDirty
257+
&& _pendingScrollTo is { } pending
258+
&& (
259+
pending.horizontal is { } hOffset && Math.Abs(horizontalOffset - hOffset) > 1
260+
|| pending.vertical is { } vOffset && Math.Abs(verticalOffset - vOffset) > 1)
261+
)
262+
{
263+
// When the native element of the SCP is becoming "valid" with a non 0 offset, it will raise a scroll event.
264+
// But if we have a manual scroll request pending, we need to mute it and wait for the next layout updated.
265+
266+
return;
267+
}
268+
269+
_pendingScrollTo = default;
270+
265271
HorizontalOffset = horizontalOffset;
266272
VerticalOffset = verticalOffset;
267273

src/Uno.UI/UI/Xaml/FrameworkElement.EffectiveViewport.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ partial class FrameworkElement : IFrameworkElement_EffectiveViewport
3333
{
3434
private static readonly RoutedEventHandler ReconfigureViewportPropagationOnLoad = (snd, e) => ((_This)snd).ReconfigureViewportPropagation();
3535
private event TypedEventHandler<_This, EffectiveViewportChangedEventArgs>? _effectiveViewportChanged;
36+
private bool _hasNewHandler;
3637
private int _childrenInterestedInViewportUpdates;
3738
private IDisposable? _parentViewportUpdatesSubscription;
3839
private ViewportInfo _parentViewport = ViewportInfo.Empty; // WARNING: Stored in parent's coordinates space, use GetParentViewport()
@@ -45,6 +46,7 @@ public event TypedEventHandler<_This, EffectiveViewportChangedEventArgs> Effecti
4546
{
4647
add
4748
{
49+
_hasNewHandler = true;
4850
_effectiveViewportChanged += value;
4951
ReconfigureViewportPropagation(isInternal: true);
5052
}
@@ -74,6 +76,13 @@ private void ReconfigureViewportPropagation(bool isInternal = false, IFrameworkE
7476
{
7577
if (IsLoaded && IsEffectiveViewportEnabled)
7678
{
79+
#if CHECK_LAYOUTED
80+
if (IsLoaded)
81+
{
82+
_isLayouted = true;
83+
}
84+
#endif
85+
7786
if (_parentViewportUpdatesSubscription == null)
7887
{
7988
TRACE_EFFECTIVE_VIEWPORT("Enabling effective viewport propagation.");
@@ -314,8 +323,14 @@ private void PropagateEffectiveViewportChange(
314323
+ $"| reason: {caller} "
315324
+ $"| children: {_childrenInterestedInViewportUpdates}");
316325

317-
if (!isInternal && viewportUpdated) // We don't want to raise the event when we are only initializing the tree due to a new event handler
326+
if (viewportUpdated
327+
&& (
328+
!isInternal // We don't want to raise the event when we are only initializing the tree due to a new event handler somewhere in sub tree
329+
|| _hasNewHandler // but if we have a new local handler, we do need to raise the event!
330+
))
318331
{
332+
_hasNewHandler = false;
333+
319334
// Note: The event only notify about the parentViewport (expressed in local coordinate space!),
320335
// the "local effective viewport" is used only by our children.
321336
_effectiveViewportChanged?.Invoke(this, new EffectiveViewportChangedEventArgs(parentViewport.Effective));

0 commit comments

Comments
 (0)