unoplatform / uno

Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
https://platform.uno
Apache License 2.0
8.78k stars 706 forks source link

`Tapped` event not fired on `ListViewItem` in GTK/Skia on Linux OpenGL #14001

Open HakanL opened 11 months ago

HakanL commented 11 months ago

Current behavior

I have an application where I have a ListViewItem without a parent ListView (which I don't know if that's the cause of the issue or not). The reason is that I'm using the keyboard focus to navigate to it, and it provides a good container for that purpose. It works fine in Linux FB and GTK/Skia on Windows. The issue is that the Tapped event on the ListViewItem is never fired. If I repeatably tap the control then I sometimes get this error:

fail: Microsoft.UI.Input.GestureRecognizer[0]
      Microsoft.UI.Xaml.Controls.ListViewItem Inconsistent state, we already have a pending gesture for a pointer that is going down. Abort the previous gesture.

But my event handler is never fired. On Windows is works fine (but the error above is occasionally popping up). Note that I use a touchscreen only on the Linux/Raspberry Pi device, I don't have a mouse connected.

I can tap on other things just fine, for example if I add a Tapped event on the child Grid then it's fired.

Expected behavior

Tapped events should be fired when the control is tapped on the touch screen.

How to reproduce it (as minimally and precisely as possible)

https://github.com/HakanL/Uno-Tapped-Issue

Relevant code: https://github.com/HakanL/Uno-Tapped-Issue/blob/main/UnoApp5/MainPage.xaml#L16-L25

Workaround

Maybe I can use a different container, but this has worked fine for everything else, and I don't see why it wouldn't work.

Works on UWP/WinUI

None

Environment

Uno.WinUI / Uno.WinUI.WebAssembly / Uno.WinUI.Skia

NuGet package version(s)

    <PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
    <PackageVersion Include="SkiaSharp.Skottie" Version="2.88.6" />
    <PackageVersion Include="SkiaSharp.Views.Uno.WinUI" Version="2.88.6" />
    <PackageVersion Include="Uno.Core.Extensions.Logging.Singleton" Version="4.0.1" />
    <PackageVersion Include="Uno.Material.WinUI" Version="3.0.40" />
    <PackageVersion Include="Uno.Dsp.Tasks" Version="1.1.0" />
    <PackageVersion Include="Uno.Resizetizer" Version="1.1.3" />
    <PackageVersion Include="Uno.UI.Adapter.Microsoft.Extensions.Logging" Version="4.10.26" />
    <PackageVersion Include="Uno.UniversalImageLoader" Version="1.9.36" />
    <PackageVersion Include="Uno.WinUI" Version="4.10.26" />
    <PackageVersion Include="Uno.WinUI.Lottie" Version="4.10.26" />
    <PackageVersion Include="Uno.WinUI.RemoteControl" Version="4.10.26" />
    <PackageVersion Include="Uno.WinUI.Skia.Gtk" Version="4.10.26" />

Affected platforms

Skia (GTK on Linux/macOS/Windows)

IDE

Visual Studio 2022

IDE version

No response

Relevant plugins

No response

Anything else we need to know?

No response

dr1rrb commented 10 months ago

Hey @HakanL, thanks for the report.

The ListView and ListViewItem are very complex controls, mainly due to UI recycling. Noticeably we do have some specifies in layouting algorithm to support that and some parts of the layouting are delegated to the ListView. I would suspect that using a ListViewItem out of a ListView would let it with some internal properties not set properly, driving the hit-test algorithm to not be able to properly dispatch events to it.

For instance I would suspect that:

  1. Moving your ListViewItem before the TextBlock (i.e. first child of the Stackpanel / located at 0,0 in the parent container) could fix your issue
  2. Any element within the ListViewItem (as it's currently in your sample) won't be able to raise Tapped event and coordinates of all pointers events are offseted (if they are raised)

Are you using the ListViewItem only for keyboard navigation? If so I would suspect that @MartinZikmund could provide other solutions?

HakanL commented 10 months ago

@dr1rrb Thanks for your insight. Yes, I'm primarily using the ListViewItem for keyboard navigation (and I have some code in my application that handles external rotary encoder navigation, which is currently looking for the ListViewItem, but that could be changed to a different control). It sounds like I should probably just find a different container to show the keyboard navigation, I used the ListViewItem because prior to using ItemsRepeater I had a ListView and it worked well (but had other focus issue with the ListView control itself).

dr1rrb commented 10 months ago

Yes I think it would be easier to use another container, you can create you own container that inherits directly from ContentControl. Though, my recommendation would be that you look for a custom attached property instead of a specific control type, so you would be able to use any type of container (you can even set this attached property in an implicit Style)

HakanL commented 10 months ago

Yeah I think you're right, I used the ListViewItem initially just because it did exactly what I wanted out of the box (when used in a ListView).

HakanL commented 10 months ago

I changed my application to use a ContentControl instead of orphan ListViewItem. I've managed to get my visual focus rectangle to work, but I'm still having the issue reported here where some of the tap event aren't triggered. Short of using a button, what control should I use to reliably catch tap events? I've also tried a Grid with the Tapped event, and it's the same issue. FWIW I'm on Uno5 now.

ramezgerges commented 9 months ago

@HakanL I tested your repro on Windows and couldn't reproduce, and now I'm testing on Manjaro with OpenGL and it's still not reproducing. The bug sounds weird to begin with, as ListViewItem is pretty much just a SelectorItem, which in turn is mostly a ContentControl which a bunch of logic for IsSelected, visual states and a bit of pointer logic that shouldn't affect tapping too much.

I suspect there's something very specific to your setup that may be breaking our pointers.

HakanL commented 9 months ago

@ramezgerges This is on a Raspberry Pi with a touchscreen, I haven't tried to repro on Windows (I don't have a touchscreen on my Windows machine). I feel like I had something similar on Framebuffer, even on regular buttons, but that improved when I moved to X11 and GTK, now it's just an issue with tapping non-buttons.