Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Attempt to close WPF window containing Avalonia control causes InvalidOperationException

Open jl0pd opened this issue 1 year ago • 3 comments

Describe the bug

Whenever I try to close window from Avalonia control, exception is thrown. Problem is that IInputRoot doesn't have visual parent and therefore cannot convert point. Adding check for _inputRoot.VisualParent is { } seems to do the trick and window closes normally, but I'm not sure if this is good way to fix issue

https://github.com/AvaloniaUI/Avalonia/blob/97a18c8d675cb81e8bb1936f9570b30a5e101eba/src/Avalonia.Base/Input/PointerOverPreProcessor.cs#L31-L33

To Reproduce Steps to reproduce the behavior:

  1. Create WPF application
  2. Add reference to Avalonia.Win32.Interoperability
  3. Create WPF window with Avalonia content
  4. Open window with Show
  5. Close window from Avalonia content by button click

Repository with example: https://github.com/jl0pd/AvaWindowFail

Expected behavior

Window closed normally

Actual behavior

Application throws following exception

InvalidOperationException: Visual is not connected to a PresentationSource
   at System.Windows.Media.Visual.PointFromScreen(Point point)
   at Avalonia.Win32.Interop.Wpf.WpfTopLevelImpl.Avalonia.Platform.ITopLevelImpl.PointToClient(PixelPoint point)
   at Avalonia.Controls.TopLevel.Avalonia.Rendering.IRenderRoot.PointToClient(PixelPoint p)
   at Avalonia.VisualExtensions.PointToClient(IVisual visual, PixelPoint point)
   at Avalonia.Input.PointerOverPreProcessor.OnNext(RawInputEventArgs value)
   at System.Reactive.Subjects.Subject`1.OnNext(T value)
   at Avalonia.Input.InputManager.ProcessInput(RawInputEventArgs e)
   at Avalonia.Controls.TopLevel.HandleInput(RawInputEventArgs e)
   at Avalonia.Win32.Interop.Wpf.WpfTopLevelImpl.MouseEvent(RawPointerEventType type, MouseEventArgs e)
   at Avalonia.Win32.Interop.Wpf.WpfTopLevelImpl.OnMouseLeave(MouseEventArgs e)
   at System.Windows.UIElement.OnMouseLeaveThunk(Object sender, MouseEventArgs e)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.ReverseInheritProperty.FirePropertyChangeInAncestry(DependencyObject element, Boolean oldValue, DeferredElementTreeState treeState, Action`2 originChangedAction)
   at System.Windows.ReverseInheritProperty.OnOriginValueChanged(DependencyObject oldOrigin, DependencyObject newOrigin, IList`1 otherOrigins, DeferredElementTreeState& oldTreeState, Action`2 originChangedAction)
   at System.Windows.Input.MouseDevice.ChangeMouseOver(IInputElement mouseOver, Int32 timestamp)
   at System.Windows.Input.MouseDevice.PreNotifyInput(Object sender, NotifyInputEventArgs e)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.MouseDevice.Synchronize()
   at System.Windows.Input.MouseDevice.ChangeMouseCapture(IInputElement mouseCapture, IMouseInputProvider providerCapture, CaptureMode captureMode, Int32 timestamp)
   at System.Windows.Input.MouseDevice.PreNotifyInput(Object sender, NotifyInputEventArgs e)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)

Desktop (please complete the following information):

  • OS: Windows 10 21h2
  • Version 0.10.18, 11.0.0-preview1

jl0pd avatar Aug 23 '22 10:08 jl0pd

Adding check for _inputRoot.VisualParent is { } seems to do the trick and window closes normally

Won't it break normal avalonia application, as "input root" is already a root without any parent?

maxkatz6 avatar Aug 23 '22 11:08 maxkatz6

Version 0.10.18, 11.0.0-preview1

Is it really reproducible on 0.10.18 ?

maxkatz6 avatar Aug 23 '22 11:08 maxkatz6

Is it really reproducible on 0.10.18 ?

I've first tried on 0.10.18, then tried on 11.0.0-preview1 to see if it was fixed

jl0pd avatar Aug 23 '22 11:08 jl0pd