Skip to content

StylusPlugIn OnStylusDown/Move/Up invoked on UI thread and called out of order #11103

@lindexi

Description

@lindexi

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.

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions