-
Notifications
You must be signed in to change notification settings - Fork 669
DYN-9823: This Visual is not connected to a PresentationSource. #16958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1593,33 +1593,51 @@ private void CachedValueChanged() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private Point PointToLocal(double x, double y, UIElement target) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private static bool TryPointToLocal(double x, double y, UIElement target, out Point result) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Point positionFromScreen = target.PointToScreen(new Point(x, y)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PresentationSource source = PresentationSource.FromVisual(target); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(positionFromScreen); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return targetPoints; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result = default; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Point positionFromScreen = target.PointToScreen(new Point(x, y)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PresentationSource source = PresentationSource.FromVisual(target); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result = source.CompositionTarget.TransformFromDevice.Transform(positionFromScreen); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| catch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // DYN-9823: PointToScreen can throw when the visual is not connected to a PresentationSource | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // (e.g. during layout, tab switch, or node deletion). Popup placement is non-critical, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // so just return false for any exception and let the caller handle it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So the side effect will be that we position the window in a weird position ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah the autocomplete popup could end up in a weird position if the user stops moving the node around just in time where the exception happens. It should then continue following the node if the node is moved again. So its like a single frame thing in very weird cases. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1599
to
+1612
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try | |
| { | |
| Point positionFromScreen = target.PointToScreen(new Point(x, y)); | |
| PresentationSource source = PresentationSource.FromVisual(target); | |
| result = source.CompositionTarget.TransformFromDevice.Transform(positionFromScreen); | |
| return true; | |
| } | |
| catch | |
| { | |
| // DYN-9823: PointToScreen can throw when the visual is not connected to a PresentationSource | |
| // (e.g. during layout, tab switch, or node deletion). Popup placement is non-critical, | |
| // so just return false for any exception and let the caller handle it. | |
| return false; | |
| } | |
| if (target == null) | |
| { | |
| return false; | |
| } | |
| Point positionFromScreen; | |
| try | |
| { | |
| positionFromScreen = target.PointToScreen(new Point(x, y)); | |
| } | |
| catch (InvalidOperationException) | |
| { | |
| // DYN-9823: PointToScreen can throw when the visual is not connected to a PresentationSource | |
| // (e.g. during layout, tab switch, or node deletion). Popup placement is non-critical, | |
| // so just return false for this expected exception and let the caller handle it. | |
| return false; | |
| } | |
| PresentationSource source = PresentationSource.FromVisual(target); | |
| if (source?.CompositionTarget == null) | |
| { | |
| return false; | |
| } | |
| result = source.CompositionTarget.TransformFromDevice.Transform(positionFromScreen); | |
| return true; |
Copilot
AI
Mar 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If either TryPointToLocal call fails here, the window position is left unchanged (or stays at the default for a newly created window), but the autocomplete window may still be shown by the caller. That can result in the popup appearing in an arbitrary/stale location. Consider a fallback behavior when placement can't be computed (e.g., hide/close the window for that tick, or place it relative to the owner/workspace until a valid target is available).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to do some extra checks here to avoid an exception ?
for source, source.RootVisual, source.CompositionTarget