WPF tocuh in Window with StylusPlugIn may throw InvalidOperationException
- .NET Core Version: 6.0.121.56705
- Windows version: win10 21H2
- Does the bug reproduce also in WPF for .NET Framework 4.8?: No
Problem description:
After https://github.com/dotnet/wpf/pull/2891 the Stylus Input thread will call the GetAndCacheTransformToDeviceMatrix to get the Matrix to calculate.
https://github.com/dotnet/wpf/blob/ab8e3f026bc4319aae72e0b3b0383acbc500aeef/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusLogic.cs#L417-L435
After we changed the moniter DPI and then we touch the application immediately, the GetAndCacheTransformToDeviceMatrix will call hwndSource.CompositionTarget.TransformToDevice and then throw the System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
https://github.com/dotnet/wpf/blob/ab8e3f026bc4319aae72e0b3b0383acbc500aeef/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusLogic.cs#L427
Because we can not find the new DpiScale in _transformToDeviceMatrices
Actual behavior:
Application: Application.exe
CoreCLR Version: 6.0.121.56705
.NET Version: 6.0.1
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
at System.Windows.Threading.Dispatcher.ThrowVerifyAccess()
at System.Windows.Threading.Dispatcher.VerifyAccess()
at System.Windows.Threading.DispatcherObject.VerifyAccess()
at System.Windows.Media.CompositionTarget.VerifyAPIReadOnly()
at System.Windows.Interop.HwndTarget.get_TransformToDevice()
at System.Windows.Input.StylusLogic.GetAndCacheTransformToDeviceMatrix(PresentationSource source)
at System.Windows.Input.StylusWisp.WispLogic.GetTabletToViewTransform(PresentationSource source, TabletDevice tabletDevice)
at System.Windows.Input.PenContexts.InvokeStylusPluginCollection(RawStylusInputReport inputReport)
at System.Windows.Input.StylusWisp.WispLogic.InvokeStylusPluginCollection(RawStylusInputReport inputReport)
at System.Windows.Input.StylusWisp.WispLogic.ProcessInputReport(RawStylusInputReport inputReport)
at System.Windows.Input.StylusWisp.WispLogic.ProcessInput(RawStylusActions actions, PenContext penContext, Int32 tabletDeviceId, Int32 stylusDeviceId, Int32[] data, Int32 timestamp, PresentationSource inputSource)
at System.Windows.Input.PenContexts.ProcessInput(RawStylusActions actions, PenContext penContext, Int32 tabletDeviceId, Int32 stylusPointerId, Int32[] data, Int32 timestamp)
at System.Windows.Input.PenContexts.OnPenDown(PenContext penContext, Int32 tabletDeviceId, Int32 stylusPointerId, Int32[] data, Int32 timestamp)
at System.Windows.Input.PenContext.FirePenDown(Int32 stylusPointerId, Int32[] data, Int32 timestamp)
at System.Windows.Input.PenThreadWorker.FireEvent(PenContext penContext, Int32 evt, Int32 stylusPointerId, Int32 cPackets, Int32 cbPacket, IntPtr pPackets)
at System.Windows.Input.PenThreadWorker.ThreadProc()
at System.Threading.Thread.StartHelper.Callback(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Thread.StartCallback()
Expected behavior:
Work well.
Minimal repro:
- Create the application and attache the StylusPlugIn to main window
- Run the application in the device with touch screen.
- Touch the main window and then change the moniter DPI and then touch the application immediately
Repeat step 3 many times, and we will find the exception.
Reference: https://github.com/dotnet/wpf/issues/6415
cc @rladuca
Why we cache the Matrix to _transformToDeviceMatrices ? Why not calculate the Matrix with hwndSource.CompositionTarget.CurrentDpiScale ?
The TransformToDevice property is calculate with CurrentDpiScale.
https://github.com/dotnet/wpf/blob/ab8e3f026bc4319aae72e0b3b0383acbc500aeef/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/InterOp/HwndTarget.cs#L2334-L2343