Skip to content

Switch to using animation request for scroll inertia dispatch#18997

Merged
maxkatz6 merged 2 commits into
masterfrom
scroll_inertia_dispatch
Jun 14, 2025
Merged

Switch to using animation request for scroll inertia dispatch#18997
maxkatz6 merged 2 commits into
masterfrom
scroll_inertia_dispatch

Conversation

@emmauss

@emmauss emmauss commented Jun 4, 2025

Copy link
Copy Markdown
Contributor

What does the pull request do?

This PR dispatches scroll inertia events on animation tick. This provides much smoother inertia scrolling on high framerate devices.

What is the current behavior?

Scroll inertia was dispatched on 16ms interval, limiting it to 60fps. Devices with higher framerate or variable framerate will have choppy scroll animations when inertia is started.

What is the updated/expected behavior with this PR?

How was the solution implemented (if it's not obvious)?

Checklist

Breaking changes

Obsoletions / Deprecations

Fixed issues

@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0056932-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

return true;
}, TimeSpan.FromMilliseconds(16), DispatcherPriority.Background);

MediaContext.Instance.RequestAnimationFrame(StartInertia);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use TopLevel.RequestAnimationFrame method, as it's a stable API. MediaContext is internal.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that animation frames will be toplevel-scoped at some point too, the plan is to not trigger callbacks if toplevel isn't visible or is being throttled by the system compositor.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, TopLevel is in the Controls project, and not the Base project.


var speed = _inertia * Math.Pow(InertialResistance, (_lastTime - _inertiaStartTime).TotalSeconds);
var distance = speed * elapsedSinceLastTick.TotalSeconds;
_inertiaDispatchOperation = Dispatcher.UIThread.InvokeAsync(() =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment here, that we actually want InvokeAsync only to raise events with Input priority?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC from the discussion, priority change was the only reason.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

return true;
}, TimeSpan.FromMilliseconds(16), DispatcherPriority.Background);

MediaContext.Instance.RequestAnimationFrame(StartInertia);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think StartInertial should be called directly from PointerReleased. There is no reason to delay that.

return;
}

var elapsedSinceLastTick = timeSpan - _lastTime;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of those calculations should live in Input priority callback. The only job of animation frame callbacks is to throttle inertia events. OnAnimationRequested should just post a callback via dispatcher.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@emmauss emmauss force-pushed the scroll_inertia_dispatch branch from 6ac2653 to a60f7a9 Compare June 4, 2025 12:12
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.0.999-cibuild0056938-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@maxkatz6 maxkatz6 added this pull request to the merge queue Jun 14, 2025
@maxkatz6 maxkatz6 removed this pull request from the merge queue due to a manual request Jun 14, 2025
@maxkatz6 maxkatz6 merged commit 1341357 into master Jun 14, 2025
12 checks passed
@maxkatz6 maxkatz6 deleted the scroll_inertia_dispatch branch June 14, 2025 01:58
BrycensRanch pushed a commit to BrycensRanch/FreeBSD-Avalonia that referenced this pull request Dec 13, 2025
…iaUI#18997)

* switch to using animation request for scroll inertia dispatch

* run inertia calcs in dispatcher operation
maxbrousseau pushed a commit to Devolutions/Avalonia that referenced this pull request Mar 18, 2026
…iaUI#18997)

* switch to using animation request for scroll inertia dispatch

* run inertia calcs in dispatcher operation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants