processing-android
processing-android copied to clipboard
Multitouch: releasing second touch does not trigger touches[] update
Holding down two fingers on the screen and releasing one without moving(!) the other will not update touches[]
. The array will still contain two objects (which are unchanged) until an update is triggered by releasing or moving the remaining finger. toucheEnded()
still gets called.
If I get the touch events manually by overwriting surfaceTouchEvent()
, everything works as expected, so the issue seems to be with Processing and not Android or my phone.
Test code:
void setup() {
}
void draw() {
background(255);
fill(0);
textSize(64);
textAlign(CENTER, CENTER);
text(touches.length, width/2, height/2);
}
How to reproduce:
Hold down two fingers (It should display a 2) release one while holding the other still. It still is a 2 (at least for me), even though it should be a 1.
Versions: Processing: 3.5.2 Android Mode: 4.0.4
@Garbaz Cannot reproduce, tested on two different phones. The number of touch pointers gets updated as expected as I release fingers. What phone/android version are you using?
Phone: Fairphone 2
Android Version: 7.1.2
Given that when overwriting surfaceTouchEvent()
everything works as expected, I'm surprised that this is inconsistent across phones. Unfortunately I don't have a different phone on hand to test myself.
Maybe it is a case of touch screen resolution, filtering or something like that resulting in ACTION_MOVE
events even when not moving the finger?
Btw, this is the code that works for me:
boolean surfaceTouchEvent(MotionEvent event) {
int pointerIndex = event.getActionIndex();
int maskedAction = event.getActionMasked();
int up_down = 0;
if (maskedAction == MotionEvent.ACTION_DOWN || maskedAction == MotionEvent.ACTION_POINTER_DOWN) {
up_down = 1;
} else if (maskedAction == MotionEvent.ACTION_UP || maskedAction == MotionEvent.ACTION_POINTER_UP || maskedAction == MotionEvent.ACTION_CANCEL) {
up_down = -1;
} else if (maskedAction == MotionEvent.ACTION_MOVE) {
// Not used in my case
}
float touchX = event.getX(pointerIndex);
float touchY = event.getY(pointerIndex);
}
OK, thanks for the code. I will leave this for a bugfix release after 4.1 is out
I have observed the same Error (multiple touches registered even after fingers left the screen) on my Xiaomi 12 Lite (Android 12, advertised with 240hz touch sampling rate, so theoretically much better touchscreen), but interestingly NOT on my Honor 9X Lite. I even managed to get 3 Touches registered after taking off my hand. It seems to occur when I only touch the screen for a very short time, same with releasing the second finger which I can reproduce much more easily. I have not made a simple testing sketch, but I observed it while making this: https://github.com/JonLit/shortCutPhone
I just tested with the testing sketch, and it's a bit harder to reproduce, but I can still easily manage to get it in ~1/30 attempts
I'm not sure if this is the same issue, but I added some print statements to display the 'touches' array after every "touch started" and "touch ended" event. The counter on the device's screen is correct, but the info displayed in the console isn't. This is what I see in the IDE console when I touch with two fingers, then release them one at a time, about a second apart.
touch started
0 767.0 1164.0
touch started
0 767.0 1164.0
1 598.0 1367.0
touch ended
0 759.0 1170.0
1 595.0 1367.0
touch ended
I'm testing this on a Samsung Tab Lite 6 running Android 12 (attached to my computer) under Processing v4.0.1. Here's the code I used to test:
void setup() {
fullScreen();
}
void draw() {
background(255);
fill(0);
textSize(64);
textAlign(CENTER, CENTER);
text(touches.length, width/2, height/2);
}
void touchStarted() {
println("touch started");
printTouches();
}
void touchEnded() {
println("touch ended");
printTouches();
}
void printTouches() {
for (int i = 0; i < touches.length; i++) {
println(touches[i].id,touches[i].x,touches[i].y);
}
}
It's tricky to reproduce, most of the time the pointers are updated immediately, tested on a couple of different devices. The closest I was to reproduce it was in a few instances when the pointer that corresponded to the finger that was releases stayed a bit longer, but eventually was removed.
@Garbaz @dfkettle Ok I think I found the reason for this issue: when a ACTION_POINTER_UP event was registered, the event would still return the pointers including the one being released. So it remained in the list of touches until another event is registered. This commit should take care of this: https://github.com/processing/processing-android/commit/208f5e3508a69dc3d9f7df017560dcb7281fefd1, I will release a new beta version of the mode shortly so you can test it more extensively.