WindowsAppSDK icon indicating copy to clipboard operation
WindowsAppSDK copied to clipboard

Register InputPointerSource pointer event not work

Open EmmettTsai opened this issue 3 years ago • 2 comments

Describe the bug

I tried moving the "DirectX 11 and XAML App (Universal Windows - C++/CX)" template project to WinUI3 c++/winrt. I get InputPointerSource from SwapChainPanel::CreateCoreIndependentInputSource, and use the InputPointerSource to register the pressed/moved/released pointer event and DeviceKinds is Mouse|Touch|Pen. But use the mouse to rotate the cube not work.

But if I register pointer event from the control SwapChainPanel itself, can work fine.

I push my test project to https://github.com/EmmettTsai/SpinningCube

register pointer event code at here: https://github.com/EmmettTsai/SpinningCube/blob/71e8c6b982583fb7852b5f8662dc8569a047b874/SpinningCube/DirectXPage.cpp#L55

Steps to reproduce the bug

  1. Deploy with debug/x64
  2. Rotate the cube manually with the mouse not work.

Expected behavior

The cube can be rotated manually with the mouse.

Screenshots

SpinningCube

NuGet package version

1.1.2

Packaging type

Packaged (MSIX)

Windows version

Windows 10 version 21H2 (19044, November 2021 Update)

IDE

Visual Studio 2022

Additional context

No response

EmmettTsai avatar Jul 10 '22 15:07 EmmettTsai

Apparently, a dedicated DispatcherQueue thread is needed to pump the events. The documentation completely ignores this. Calling swapChainPanel.CreateCoreIndependentInputSource() on UI thread throws RPC_E_WRONG_THREAD error, while having it on a dedicated thread without dispatcher queue fails to deliver the events.

So your test code should change to:

m_dispatcherQueueController = DispatcherQueueController::CreateOnDedicatedThread();

// Register our SwapChainPanel to get independent input pointer events
m_dispatcherQueueController.DispatcherQueue().TryEnqueue([this] {
    // The CoreIndependentInputSource will raise pointer events for the specified device types on whichever thread it's created on.
    InputPointerSourceDeviceKinds deviceKind = (InputPointerSourceDeviceKinds)(
        Microsoft::UI::Input::InputPointerSourceDeviceKinds::Mouse |
        Microsoft::UI::Input::InputPointerSourceDeviceKinds::Touch |
        Microsoft::UI::Input::InputPointerSourceDeviceKinds::Pen);
    m_coreInput = swapChainPanel().CreateCoreIndependentInputSource(deviceKind);

    // Register for pointer events, which will be raised on the background thread.
    m_coreInput.PointerPressed({ this, &DirectXPage::SwapChainPanel_OnPointerPressed });
    m_coreInput.PointerMoved({ this, &DirectXPage::SwapChainPanel_OnPointerMoved });
    m_coreInput.PointerReleased({ this, &DirectXPage::SwapChainPanel_OnPointerReleased });
    });

Make sure to use the DispatcherQueueController in namespace Microsoft.UI.Dispatching, not the one in Windows.System.

vmilea avatar Jul 28 '22 05:07 vmilea

@vmilea Thanks for the explanation. It work fine.

EmmettTsai avatar Jul 30 '22 19:07 EmmettTsai