Skip to content

Avoid exceptions when getting a position from a PointerEventArgs#21301

Merged
MrJul merged 1 commit into
AvaloniaUI:masterfrom
Enscape:fixes/PointerEventArgs-GetPosition-nothrow
May 4, 2026
Merged

Avoid exceptions when getting a position from a PointerEventArgs#21301
MrJul merged 1 commit into
AvaloniaUI:masterfrom
Enscape:fixes/PointerEventArgs-GetPosition-nothrow

Conversation

@TomEdwardsEnscape

@TomEdwardsEnscape TomEdwardsEnscape commented May 2, 2026

Copy link
Copy Markdown
Contributor

#21294 identifies a case in which PointerEventArgs.GetPosition can throw. The bug report blames ItemSelectionEventTriggers.IsPointerEventWithinBounds, which is where the exception was observed. But the problem is more general than that.

What is the current behaviour?

Inspecting the code of GetPosition, it's clear that the intent is to return (0,0) if a position can't be calculated. However, it will in fact throw if _rootVisual.VisualRoot is null when the method is called.

What is the updated/expected behavior with this PR?

  • GetPosition is no longer dependent on the value of _rootVisual.VisualRoot, and so no longer throws if it's null.
  • There are now tests for cross-root position requests.
  • The exceptions thrown by VisualExtensions.PointToClient and PointToScreen are now documented.

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

I refactored PointerEventArgs.GetPosition to use the new IPresentationSource.PointToClient and PointToScreen methods when transforming a point between two presentation sources. We can bypass the VisualExtensions equivalents because we already know that the position is in the coordinate space of the presentation source which raised the event.

This refactoring allows us to store rootVisual.PresentationSource in the constructor instead of rootVisual itself. This protects us from the property changing later. The only Visual involved is now the one passed to GetPosition.

IPresentationSource.PointToClient and PointToScreen now return null if they failed to transform the point, so that callers can respond appropriately.

Breaking changes

None.

Obsoletions / Deprecations

None.

Fixed issues

Fixes #21294

Return null when an IPresentationSource can't convert from/to screen coordinates
Document exceptions in VisualExtensions PointToClient and PointToScreen
Add tests for cross-root pointer event positions
@avaloniaui-bot

Copy link
Copy Markdown

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

@MrJul MrJul added bug backport-candidate-12.0.x Consider this PR for backporting to 12.0 branch labels May 4, 2026

@MrJul MrJul left a comment

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.

The changes make sense.
LGTM!

@MrJul MrJul added this pull request to the merge queue May 4, 2026
Merged via the queue into AvaloniaUI:master with commit 1365b64 May 4, 2026
12 checks passed
@TomEdwardsEnscape TomEdwardsEnscape deleted the fixes/PointerEventArgs-GetPosition-nothrow branch May 4, 2026 13:37
MrJul pushed a commit to MrJul/Avalonia that referenced this pull request May 28, 2026
…niaUI#21301)

Return null when an IPresentationSource can't convert from/to screen coordinates
Document exceptions in VisualExtensions PointToClient and PointToScreen
Add tests for cross-root pointer event positions
@MrJul MrJul added backported-12.0.x and removed backport-candidate-12.0.x Consider this PR for backporting to 12.0 branch labels May 28, 2026
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.

PointToScreen on null PlatformImpl causes exception

3 participants