From 90755045f5404dd7d38048c90ed3d718b09dcef9 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 15 Jan 2025 03:31:54 +0100 Subject: [PATCH] Windows multitouch tweaks * Fix special case of first single touch. While another touch is active, any new touch must not get the ID of the (ignored) first touch. * reset "last-touch" coordinate on touch-begin. Previously it was possible that the first motion event was ignored. NB: This does not fix missing events when the first touch coincides with any other finger (gesture?). --- libs/tk/ydk/win32/gdkevents-win32.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/libs/tk/ydk/win32/gdkevents-win32.c b/libs/tk/ydk/win32/gdkevents-win32.c index 440695c468..efe384ab2b 100644 --- a/libs/tk/ydk/win32/gdkevents-win32.c +++ b/libs/tk/ydk/win32/gdkevents-win32.c @@ -249,7 +249,8 @@ touch_idx_lookup (DWORD id) static int touch_idx_map (DWORD id) { - GList* g = g_list_find (touch_mapper, GUINT_TO_POINTER(G_MAXUINT)); + /* when there is an active touch, skip index 0 (mouse) */ + GList* g = touch_mapper ? g_list_find (touch_mapper->next, GUINT_TO_POINTER(G_MAXUINT)): NULL; if (!g) { touch_mapper = g_list_append (touch_mapper, GUINT_TO_POINTER(id)); } else { @@ -267,6 +268,20 @@ touch_idx_unmap (DWORD id) } int rv = g_list_position (touch_mapper, g); g->data = GUINT_TO_POINTER(G_MAXULONG); + + /* last touch clears the list */ + gboolean empty = TRUE; + for (g = touch_mapper; g && empty; g = g->next) { + if (g->data != GUINT_TO_POINTER(G_MAXULONG)) { + empty = FALSE; + break; + } + } + if (empty) { + g_list_free (touch_mapper); + touch_mapper = NULL; + } + return rv; } @@ -2118,8 +2133,13 @@ handle_wm_pointer (GdkEventType type, GdkWindow* window, MSG* msg) return FALSE; } - last_touch_x[touch_sequence] = (int)point.x; - last_touch_y[touch_sequence] = (int)point.y; + if (type == GDK_TOUCH_BEGIN) { + last_touch_x[touch_sequence] = -1; + last_touch_y[touch_sequence] = -1; + } else { + last_touch_x[touch_sequence] = (int)point.x; + last_touch_y[touch_sequence] = (int)point.y; + } /* first single touch is already handled by Windows as mouse event */ if (touch_sequence == 0) {