Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Touches from dialog window get "stuck" in main window #450

Open
vsfeedback opened this issue Mar 19, 2019 · 11 comments
Open

Touches from dialog window get "stuck" in main window #450

vsfeedback opened this issue Mar 19, 2019 · 11 comments
Labels
Bug Product bug (most likely)
Milestone

Comments

@vsfeedback
Copy link

I asked this question already in the other forums but still haven't been able to get a solution for it or even have somebody looking at it, so I'll try it again here (this is copy paste from other post here):


We are having quite a problem with our WPF app on touch devices. Sometimes after closing a modal window (opened with ShowDialog()) the buttons on our main window respond correctly to triggers on AreAnyTouchesOver, but they never fire a Click event or command when tapped. After quite some trail and error we believe we have found the issue causing this. The following scenario makes the issue appear.

Open a modal window and then make the UI thread busy for a while.
On the modal window there's a button that closes the window.
Now tap the close button and then any locations in the modal window (the close button or even some other place) WHILE the UI thread is still busy.
When the UI thread has done it's work it will see the click on the close button and close the window. All touches that came after the first tap on close appear now on the main window. However ONLY the (Preview)TouchDown events are raised in the main window and NO (Preview)TouchUp is ever occurring. This makes the main window think there are still fingers over itself while in reality they are not, and as a result when you tap a button this is seen as "1 more finger" instead of just a single finger tapping the screen.

https://1drv.ms/u/s!AhqurxiexJWri5EleIA1-J6XZ0aKvA

This sample app is a minimal repro. After the dialog closes you can see that the PreviewTouchDown handler of the main window is fired the same number of times you tapped the dialog after you pressed close for the first time. The PreviewTouchUp handler is never fired. You can see that every time the PreviewTouchDown handler is fired a TouchDevice is added to the TouchesOver collection.

For some reason after a "random" amount of interactions with the app the number of devices decreases and from the moment all "ghost fingers" are gone the buttons work as expected again.

We did not yet find a solution to resolve this issue.

We tried looping over PeekMessage (from User32.dll) to remove all touches in the queue but both WM_TOUCH and WM_GESTURE don't appear in there, even after calling RegisterTouchWindow. PeekMessage works fine for mouse though but we don't have mouse problems.

We also tried putting an in-between-window between the main window and our modal dialog. This works in the sense that we see the rogue touches coming to the in-between-window, and after we close it the main window will have 0 TouchesOver. But still this does not resolve the issue. We even tried using reflection in the in-between-window to call ReportUp and Deactivate on every TouchDevice in TouchesOver of the in-between-window. And we can see that it has an effect because they are 1 by 1 removed from TouchesOver. But even then after the in-between-window closes and with 0 TouchesOver on any window our main window does not correctly handle touch.

I did find something very suspicious in the .NET source code: https://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Input/TouchDevice.cs,720


So... if anyone has a robust solution this would be very welcome. If not we have to revert to set IsChecked, raise Click event, run Commands, etc all manually in global TouchUp handlers for all buttons.

Regards,
Stan

This issue has been moved from https://developercommunity.visualstudio.com/content/problem/496835/touches-from-dialog-window-get-stuck-in-main-windo.html
VSTS ticketId: 822709

These are the original issue comments:
(no comments)
These are the original issue solutions:
(no solutions)

@stevenbrix
Copy link
Contributor

@Stannieman does this only repro on .NET Core or are you seeing this on .NET Fx?

@stevenbrix stevenbrix added the Bug Product bug (most likely) label Mar 20, 2019
@Stannieman
Copy link

At least on full framework it happens. I haven't tried with Core, I'll have a look today evening or tomorrow.

@Stannieman
Copy link

@stevenbrix I just tried on .NET Core 3 with same code and the issue is reproducible there also.

@stevenbrix stevenbrix added this to the Future milestone Mar 21, 2019
@Jogge
Copy link

Jogge commented Mar 22, 2019

This issue seems to be related to #194

@Stannieman
Copy link

It looks related yet not exactly the same, see comment in that issue.

@cbaysinger
Copy link

I built your app and yes it does fail as expected. I introduced a timer to create a busy GUI thread after showing the dialog and it also closes the dialog. Touches during this busy period later appear in the parent TouchesOver.Count and they block the click event just as your example. So it appears that if the GUI thread is busy and multiple touches occur during that time and if the dialog closes before those touches are handled they will show up in the TouchesOver.Count and they prevent the click event. If you create another timer that allows the click events to be processed before closing the dialog the problem does not appear. Hardly a solution. I also found that if the parent window is not made the owner of the dialog then this problem does not occur.

I took a look at issue 194 and it does in fact fail to promote touch events to button clicks but I think it must have a different mechanism because the touch up events are all captured by the dialog, they are not moved to the parent window as in your case.

We are having similar problems thought I have not tested your method of showing the problem or at least a side effect of the problem.

Have you gotten any feedback from Core 3 team?

@cbaysinger
Copy link

I built your app and yes it does fail as expected. I introduced a timer to create a busy GUI thread after showing the dialog and it also closes the dialog. Touches during this busy period later appear in the parent TouchesOver.Count and they block the click event just as your example. So it appears that if the GUI thread is busy and multiple touches occur during that time and if the dialog closes before those touches are handled they will show up in the TouchesOver.Count and they prevent the click event. If you create another timer that allows the click events to be processed before closing the dialog the problem does not appear. Hardly a solution. I also found that if the parent window is not made the owner of the dialog then the problem does not occur. Again not a real solution but it may help to point at the cause.

We are having a similar problem and I will test your diagnostic to see if it is caused by the same mechanism. Thanks for your post.

Have you gotten any feedback from Core 3 team?

@cbaysinger
Copy link

Sorry about the previous double post.
Verified that this the source of a problem we have been seeing when a user does a rapid double touch when selecting an items from an items control that is hosted in a window that closes on the click event. On touching a button on the underlying window we are seeing the elevated TouchesOver.Count and no click event for various amounts of time before click events return.

@m-a-v
Copy link

m-a-v commented Aug 10, 2020

Any news concerning this issue?

@Stannieman
Copy link

Any news concerning this issue?

Not that I know of.
However I did hear somewhere that there was some activity in the WPF repo recently, which at least is more than the "no activity" from before.

@aquinn39
Copy link

aquinn39 commented Dec 3, 2023

If you're still having this issue and for anyone else who is having this issue, have you tried referencing Windows Forms and calling System.Windows.Forms.DoEvents() before calling Window.Close() on the modal window? Another thing to try is await Task.Delay(1) (try with higher numbers if need be) because it sounds like the window you're closing is being disposed before it gets to finish handling the touch event and the above two methods may give the window the chance it needs to finish handling the touch events. I have had similar issues to this (but that was with using an XAML host in a WPF window, which is a different thing, but the issue of the window closing before events had finished being handled existed there was something I encountered which sounds similar to this). Of course, this should be fixed in .Net but these may be some workarounds you could try for now.

Actually just thinking about this a bit more, another thing that could help might be calling Window.ReleaseAllTouchCaptures() on the modal (and maybe main as well) window.

One final thing actually that might work is this (code is in VB) is to define a method like this:
Private Async Function WPFDoEvents() As Task Await Application.Current.Dispatcher.InvokeAsync(AddressOf Dummy, System.Windows.Threading.DispatcherPriority.Render) End Function

And then await it before you call Close() on the model window. From my understanding, this should cause the UI to fully update, releasing all the touch captures, before the window closes.

Oh and it might even be worth trying these things before opening the model window as well, in case the touches are becoming trapped in the main window.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Product bug (most likely)
Projects
Status: Todo
Development

No branches or pull requests

7 participants