From 4cb2b0c71b392b1f375eeec42e85dc3d2e948e1b Mon Sep 17 00:00:00 2001 From: artin Date: Wed, 4 Feb 2026 02:02:06 +0800 Subject: [PATCH] fix(ohos): process only the changed touch point in touch events The previous implementation processed all touch points in the array for every touch event, which could cause duplicate or incorrect events since the array contains the current state of all fingers. Now we correctly identify and process only the finger that triggered the current event (touchEvent.id), improving touch event accuracy on OpenHarmony platforms. --- src/core/ohos/SDL_ohos.c | 62 ++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/src/core/ohos/SDL_ohos.c b/src/core/ohos/SDL_ohos.c index 5c8ab566ab4ca..890863250d8dd 100644 --- a/src/core/ohos/SDL_ohos.c +++ b/src/core/ohos/SDL_ohos.c @@ -662,36 +662,48 @@ static void onNativeTouch(OH_NativeXComponent *component, void *window) OH_NativeXComponent_GetTouchEvent(component, window, &touchEvent); OH_NativeXComponent_GetTouchPointToolType(component, 0, &toolType); + // Only process the finger that triggered this event (touchEvent.id). + // The touchPoints array contains current state of all fingers, not just the changed one. + int targetIndex = -1; for (int i = 0; i < touchEvent.numPoints; i++) { - SDL_OHOSTouchEvent e; - e.timestamp = touchEvent.timeStamp; - // skip assertions - e.deviceId = touchEvent.deviceId + 1; - e.fingerId = touchEvent.touchPoints[i].id + 1; - e.area = touchEvent.touchPoints[i].size; - e.x = touchEvent.touchPoints[i].x / (float)wid; - e.y = touchEvent.touchPoints[i].y / (float)hei; - e.p = touchEvent.touchPoints[i].force; - - switch (touchEvent.touchPoints[i].type) { - case OH_NATIVEXCOMPONENT_DOWN: - e.type = SDL_EVENT_FINGER_DOWN; - break; - case OH_NATIVEXCOMPONENT_MOVE: - e.type = SDL_EVENT_FINGER_MOTION; - break; - case OH_NATIVEXCOMPONENT_UP: - e.type = SDL_EVENT_FINGER_UP; - break; - case OH_NATIVEXCOMPONENT_CANCEL: - case OH_NATIVEXCOMPONENT_UNKNOWN: - e.type = SDL_EVENT_FINGER_CANCELED; + if (touchEvent.touchPoints[i].id == touchEvent.id) { + targetIndex = i; break; } - - OHOS_OnTouch(e); } + if (targetIndex < 0) { + OHOS_UnlockPage(); + return; + } + + SDL_OHOSTouchEvent e; + e.timestamp = touchEvent.timeStamp; + e.deviceId = touchEvent.deviceId + 1; + e.fingerId = touchEvent.touchPoints[targetIndex].id + 1; + e.area = touchEvent.touchPoints[targetIndex].size; + e.x = touchEvent.touchPoints[targetIndex].x / (float)wid; + e.y = touchEvent.touchPoints[targetIndex].y / (float)hei; + e.p = touchEvent.touchPoints[targetIndex].force; + + switch (touchEvent.touchPoints[targetIndex].type) { + case OH_NATIVEXCOMPONENT_DOWN: + e.type = SDL_EVENT_FINGER_DOWN; + break; + case OH_NATIVEXCOMPONENT_MOVE: + e.type = SDL_EVENT_FINGER_MOTION; + break; + case OH_NATIVEXCOMPONENT_UP: + e.type = SDL_EVENT_FINGER_UP; + break; + case OH_NATIVEXCOMPONENT_CANCEL: + case OH_NATIVEXCOMPONENT_UNKNOWN: + e.type = SDL_EVENT_FINGER_CANCELED; + break; + } + + OHOS_OnTouch(e); + OHOS_UnlockPage(); } // TODO mouse data