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

Fix for Android double tap not triggering correctly #46100 and #46101 #54225

Closed
wants to merge 3 commits into from

Conversation

Ongnissim
Copy link

onDoubleTap gets called for touch events, so event.getButtonState() returns
nothing. Instead, event.getPointerCount returns the number of fingers currently on the
screen, so doubleTap now returns the appropriate "button" for one to
three fingers.

This fixes the issues with FileDialog on Android as well.

There is still a button release event being sent after the double_click is triggered, and I believe this is happening due to a bit of code called ensure_touch_mouse_raised() in input.cpp that's called by the SceneTree when focus is changed.

It doesn't seem to break anything, so I didn't mess with it.

@Ongnissim Ongnissim requested a review from a team as a code owner October 25, 2021 12:19
@akien-mga
Copy link
Member

Thanks for contributing!

There are some issues with the commits in this PR which would need to be solved by rebasing, namely:

@akien-mga akien-mga added this to the 4.0 milestone Oct 25, 2021
@akien-mga akien-mga added cherrypick:3.4 cherrypick:3.x Considered for cherry-picking into a future 3.x release labels Oct 25, 2021
@thebestnom
Copy link
Contributor

Godot on android does support mouse buttons, and this is how we get which button was pressed

@thebestnom
Copy link
Contributor

You should check event source before doing this 😅

@aaronfranke
Copy link
Member

@Ongnissim You can't just revert. You have to rebase. See the article that Akien linked for more information.

@Ongnissim
Copy link
Author

I had an issue with Github authorization. I'm new to this whole process, so please forgive me. Should be clean and ready to go now!

Godot on android does support mouse buttons, and this is how we get which button was pressed

Yes! But in this case, in the GestureHandler was trying to parse a screen touch event as a mouse button event, which lead to a double click happening on mouse button 0, which was off.

At least that's what it appears to have been doing. My tests show that it's now working as intended, and mouse input on Android is unaffected by this change. I definitely tested that before I put up a pull request. I really really don't want to break anything, haha!

@thebestnom
Copy link
Contributor

Mouse click should be affected by it for right click or middle click as you put a constant there 😅

@Ongnissim
Copy link
Author

This only affects touch screen input, it's only triggered when a double tap is done on screen, since this is in the gesture input event handler. Traditional mouse input is unaffected.

This then sends the correct button mask to the double click parser.

The original, being a screen touch event, came out to 0, which becomes mouse button none. With this, the double tap is parser correctly as either 1, 2, or 3 for a double tap that is mapped to the intended button (left, right, middle) by the code that already exists within the Android event handler.

I hope this makes sense

@thebestnom
Copy link
Contributor

Traditional mouse input is unaffected.

I have tested it once on traditional mouse and it does catch that, can you test your claim 😅?

…and godotengine#46101.

Changes the buttonMask for doubleTap input on android to recognize both Mouse and Screen Touch inputs.
@Ongnissim
Copy link
Author

Ongnissim commented Oct 26, 2021

Alright, I've spent a bit more time on this. When I'd first tested it, I'll admit, I only tested single-clicks under the assumption that the gesture handler couldn't possibly affect non-gesture inputs. (I was wrong :P). So:

If we run both getPointerCount and getButtonState through, with a boolean check on whether the input was a mouse, then it behaves as it should to my testing. I'm updating my commit now.

I cannot get the right mouse button to register a double click, and I can't figure out why only that button isn't registering. The LMB and MMB both double click as expected.

The code in Master as-is also misses double-clicks from RMB, at least in my testing. But I've only tested on a Samsung Galaxy Tab S7, and my research shows that Android has had varying behaviors in the past on how RMB is mapped, but my attempts to find out why have been fruitless so far.

@Ongnissim
Copy link
Author

There's another potential issue I see here: double-taps will register as mouse double-clicks even if emulate_touch_as_mouse is off, which means this probably isn't the absolute best way to fix this, or that it's just a quick patch for a deeper underlying bug.

This does solve the problems for my needs, but there is clearly something else going on.

@@ -74,7 +74,7 @@ public boolean onDoubleTap(MotionEvent event) {
//Log.i("GodotGesture", "onDoubleTap");
final int x = Math.round(event.getX());
final int y = Math.round(event.getY());
final int buttonMask = event.getButtonState();
final int buttonMask = event.getButtonState() + (event.getToolType(event.getActionIndex()) != MotionEvent.TOOL_TYPE_MOUSE ? 1 : 0) * event.getPointerCount();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ongnissim Is double tap triggered with multiple fingers? I tested double tapping with 2 and 3 fingers and the event didn't trigger.
If it's not supported, then we can simplify this logic.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it is supported, but in the event that it would be supported, this returns a button mask of 0,1,2,3... for the number of fingers. I did this so that touch input would have parity with mouse input. I never got a response so I stopped working on it.

Are you saying that onDoubleTap doesn't trigger at all on double tapping with multiple fingers? I also couldn't get this to trigger how I expected, and would like to know how to make this work.

This is my first PR ever, so I won't be offended if this isn't the correct way to implement this, and just want the bug fixed :).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to clone this again and test to see if getPointerIndex() does what I anticipated.
The idea is that you'd be able to have one finger down, double-tap a second finger, and this would register as a right-mouse double-click. Three for MMB.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is that you'd be able to have one finger down, double-tap a second finger, and this would register as a right-mouse double-click. Three for MMB.

@Ongnissim I tested that, and yes onDoubleTap doesn't trigger in this scenario.

This is my first PR ever, so I won't be offended if this isn't the correct way to implement this, and just want the bug fixed :).

The approach is pretty close and can be improved by incorporating some of the logic in #59760.

I think the proper approach here would be to pass the tooltype value alongside the button mask.
In the native code in AndroidInputHandler::process_double_tap, when the tooltype is MotionEvent.TOOL_TYPE_FINGER, then disregard the button mask and use the logic in #59760.
Otherwise, use the current logic that takes into account the button mask.

@madmiraal @thebestnom Thoughts?

Copy link
Contributor

@madmiraal madmiraal Jun 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to properly fix #46100 and #46101 (beyond #59760) would require separating out the mouse double-clicks from the double-taps. So that the start of the second tap is not also detected as the start of a second single click.
Note: The main challenge is ensuring the release of the second click releases the double tap too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that the start of the second tap is not also detected as the start of a second single click.

@madmiraal That's part of a larger issue that also affects other gestures besides double-taps. Our current input logic sends both the raw input events (down, move, up) and the processed input events (detected gestures) to the native layer, so in scenarios where a gesture is detected, we end double-counting.

We need to update the logic so that we only sends raw input events when a gesture is not detected; it's part of a larger fix I'll be looking at unless one of you is up to the task :)

For this issue, we can scope the fix to re-enabling finger double-taps using the proposal I highlighted above since at the moment they're disabled because of the button mask value.
On top of fixing finger double-taps, this will allow to leverage the current logic which provide information regarding the source of the event when it's not a finger.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem isn't just with the Android platform. It was thinking through this issue that led me to create godotengine/godot-proposals#4340

@m4gr3d
Copy link
Contributor

m4gr3d commented Sep 6, 2022

Superseded by #65434

@m4gr3d m4gr3d closed this Sep 6, 2022
@akien-mga akien-mga added archived and removed cherrypick:3.x Considered for cherry-picking into a future 3.x release labels Sep 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants