StylusPlugIn OnStylusDown/Move/Up invoked on UI thread and called out of order
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
### Description
• StylusPlugIn.OnStylusDown / OnStylusUp are sometimes invoked out of order: I see OnStylusUp called on the UI thread, then later OnStylusDown called on the Stylus (pen/touch) thread.
• The incoming message is a touch (StylusDeviceId != 0, e.g. 123), so it should not be handled as a mouse message on the UI thread.
### Reproduction Steps
How to reproduce (minimal)
1. Create a class inheriting StylusPlugIn and override OnStylusDown, OnStylusMove, OnStylusUp.
2. Add Thread.Sleep calls inside these methods to simulate expensive work.
3. Rapid multi-finger taps on a touch screen. And set the DPI to 300%
4. Observe that OnStylusUp (UI thread) can be called before OnStylusDown (stylus thread) for the same StylusDeviceId.
I put a minimal repro/demo on GitHub: https://github.com/lindexi/lindexi_gd/tree/107caecee7f847355d23744bf6fc7b970d5e8c69/WPFDemo/LoqairjaniferNudalcefinay
### Expected behavior
Events for a given touch/stylus input should be delivered in order and handled on the correct thread for that input type (touch/pen events on the stylus/pen input thread or otherwise consistently marshalled), not processed as mouse/UI-thread messages if StylusDeviceId indicates a touch/pen device.
### Actual behavior
OnStylusUp invoked on the UI thread (before OnStylusDown), then OnStylusDown invoked later on the stylus thread. This produces incorrect ordering and state corruption in StylusPlugIn implementations.
### Regression?
_No response_
### Known Workarounds
_No response_
### Impact
_No response_
### Configuration
_No response_
### Other information
In WispLogic.cs there is a comment: "We are on the pen thread, just call directly." This is misleading/wrong in context — that line is inside VerifyStylusPlugInCollectionTarget.
https://github.com/dotnet/wpf/blob/348310ee9e945f9d70187e19e15132a1977983ce/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Wisp/WispLogic.cs#L2741
VerifyStylusPlugInCollectionTarget is only called from `WispLogic.PreNotifyInput`, and `PreNotifyInput` is wired to InputManager.PreNotifyInput: `_inputManager.Value.PreNotifyInput += new NotifyInputEventHandler(PreNotifyInput);` . `InputManager.PreNotifyInput` is raised on the UI thread, so the code path does not guarantee we are on the Stylus Input thread.
Because `targetPIC.FireRawStylusInput` in `VerifyStylusPlugInCollectionTarget` assumes "Stylus Input thread", StylusPlugIn callbacks can be invoked on the UI thread incorrectly.
Contributor guide
Assessment
This issue has not been assessed yet.