fix: detach platform input when presentation source closes - #21782
Merged
MrJul merged 4 commits intoJul 21, 2026
Conversation
Closed top levels retain the presentation source as the platform input callback. A late platform input event can therefore target an already disposed visual tree.\n\nThe regression test requires top-level closure to clear ITopLevelImpl.Input.
Win32 can deliver WM_CAPTURECHANGED while destroying a popup that owns mouse capture. The platform then calls the input handler retained by the disposed presentation source, which logs a warning and can route input into a detached visual tree.\n\nClear the platform input callback at the start of presentation source disposal, alongside the existing scaling event unsubscription.
NathanDrake2406
marked this pull request as ready for review
July 15, 2026 08:03
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
MrJul
added a commit
that referenced
this pull request
Jul 29, 2026
* test: cover platform input detachment on close Closed top levels retain the presentation source as the platform input callback. A late platform input event can therefore target an already disposed visual tree.\n\nThe regression test requires top-level closure to clear ITopLevelImpl.Input. * fix: detach platform input when presentation source closes Win32 can deliver WM_CAPTURECHANGED while destroying a popup that owns mouse capture. The platform then calls the input handler retained by the disposed presentation source, which logs a warning and can route input into a detached visual tree.\n\nClear the platform input callback at the start of presentation source disposal, alongside the existing scaling event unsubscription. --------- Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does the pull request do?
Detaches the platform input callback when a presentation source closes. This prevents late native input, including Win32
WM_CAPTURECHANGED, from reaching an already disposed popup or window.What is the current behavior?
The Win32 handling added by #19685 forwards
WM_CAPTURECHANGEDthroughITopLevelImpl.Input. When a menu item closes a native popup while that popup owns mouse capture, Win32 can destroy the popup and then send the capture-loss message.PresentationSource.Disposeclears itsPlatformImplreference but leavesITopLevelImpl.Inputassigned toPresentationSource.HandleInput. The late message therefore enters the disposed presentation source, logsPlatformImpl is null, couldn't handle input, and can route later input work toward a detached visual tree.What is the updated/expected behavior with this PR?
Closing a top level clears
ITopLevelImpl.Inputbefore layout and renderer teardown, so the native implementation cannot dispatch input after close handling starts.Validation:
Closing_Should_Detach_Platform_Input_Handler, which fails before the fix because the closed top level retains the callback.Avalonia.Controls.UnitTestsexecutable: 3,643 passed, 1 existing test skipped, 0 failed.How was the solution implemented (if it's not obvious)?
PresentationSourceassigns and owns the platform input callback. Disposal now clears it alongsideScalingChangedbefore layout and renderer teardown.The change does not alter pointer capture, popup close ordering, or public API. The regression test verifies the framework/platform ownership boundary using the mock top-level implementation. Native Win32 UI automation was not run because the development host is macOS.
Checklist
Breaking changes
None.
Obsoletions / Deprecations
None.
Fixed issues
Fixes #19892