[GTK3] Pinch zooming from a link activates it
https://bugs.webkit.org/show_bug.cgi?id=235639

Reviewed by Carlos Garcia Campos.

Turns out gestures behave differently between GTK3 and 4. On GTK4 it works
fine, but on GTK3 starting a pinch zoom triggers the multipress gesture
when one finger is down, and completes it when the second finger is down.

This results in a bogus click, with no way to prevent it as it happens
before any of the zoom callbacks are called. Since we can't know if there
will be a zoom afterwards or not, we can't do anything about it.

However, what we can do is reorder these gestures. In GTK3 the order the
gestures are processed in depends on which order they were created in.

At that point, there's a problem with the fact the gestures are grouped.
Grouping means that these 2 gestures are triggered at the same time. While
somehow the press gesture is still triggered without grouping with the
original order, they become properly decoupled in reverse order and
ungrouped.

At that point, we can safely cancel the press gesture when the zoom gesture
starts, and fix the issue.

This seems to still work fine for GTK4.

* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseZoomBegin):
(webkitWebViewBaseConstructed):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@288644 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index e18f47f..f9adf43 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,36 @@
+2022-01-26  Alexander Mikhaylenko  <alexm@gnome.org>
+
+        [GTK3] Pinch zooming from a link activates it
+        https://bugs.webkit.org/show_bug.cgi?id=235639
+
+        Reviewed by Carlos Garcia Campos.
+
+        Turns out gestures behave differently between GTK3 and 4. On GTK4 it works
+        fine, but on GTK3 starting a pinch zoom triggers the multipress gesture
+        when one finger is down, and completes it when the second finger is down.
+
+        This results in a bogus click, with no way to prevent it as it happens
+        before any of the zoom callbacks are called. Since we can't know if there
+        will be a zoom afterwards or not, we can't do anything about it.
+
+        However, what we can do is reorder these gestures. In GTK3 the order the
+        gestures are processed in depends on which order they were created in.
+
+        At that point, there's a problem with the fact the gestures are grouped.
+        Grouping means that these 2 gestures are triggered at the same time. While
+        somehow the press gesture is still triggered without grouping with the
+        original order, they become properly decoupled in reverse order and
+        ungrouped.
+
+        At that point, we can safely cancel the press gesture when the zoom gesture
+        starts, and fix the issue.
+
+        This seems to still work fine for GTK4.
+
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseZoomBegin):
+        (webkitWebViewBaseConstructed):
+
 2022-01-26  Michael Saboff  <msaboff@apple.com>
 
         Build failure - webkit daemons don't need symlink with system content path
diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
index b251c62..573d7fe 100644
--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
@@ -1842,6 +1842,9 @@
     auto* event = gtk_gesture_get_last_event(gesture, sequence);
 
     webkitWebViewBaseSynthesizeWheelEvent(webViewBase, event, 0, 0, x, y, WheelEventPhase::Began, WheelEventPhase::NoPhase, true);
+
+    GtkGesture* click = GTK_GESTURE(g_object_get_data(G_OBJECT(webViewBase), "wk-view-multi-press-gesture"));
+    gtk_gesture_set_state(click, GTK_EVENT_SEQUENCE_DENIED);
 }
 
 static void webkitWebViewBaseZoomChanged(WebKitWebViewBase* webViewBase, gdouble scale, GtkGesture* gesture)
@@ -2064,6 +2067,17 @@
     gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
 #endif
 
+#if USE(GTK4)
+    gesture = gtk_gesture_click_new();
+    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
+#else
+    auto* gesture = gtk_gesture_multi_press_new(viewWidget);
+    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-multi-press-gesture", gesture, g_object_unref);
+#endif
+    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(gesture), TRUE);
+    g_signal_connect_object(gesture, "pressed", G_CALLBACK(webkitWebViewBaseTouchPress), viewWidget, G_CONNECT_SWAPPED);
+    g_signal_connect_object(gesture, "released", G_CALLBACK(webkitWebViewBaseTouchRelease), viewWidget, G_CONNECT_SWAPPED);
+
     // Touch gestures
 #if USE(GTK4)
     priv->touchGestureGroup = gtk_gesture_zoom_new();
@@ -2080,7 +2094,7 @@
     gesture = gtk_gesture_long_press_new();
     gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
 #else
-    auto* gesture = gtk_gesture_long_press_new(viewWidget);
+    gesture = gtk_gesture_long_press_new(viewWidget);
     g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-long-press-gesture", gesture, g_object_unref);
 #endif
     gtk_gesture_group(gesture, priv->touchGestureGroup);
@@ -2088,18 +2102,6 @@
     g_signal_connect_object(gesture, "pressed", G_CALLBACK(webkitWebViewBaseTouchLongPress), viewWidget, G_CONNECT_SWAPPED);
 
 #if USE(GTK4)
-    gesture = gtk_gesture_click_new();
-    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
-#else
-    gesture = gtk_gesture_multi_press_new(viewWidget);
-    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-multi-press-gesture", gesture, g_object_unref);
-#endif
-    gtk_gesture_group(gesture, priv->touchGestureGroup);
-    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(gesture), TRUE);
-    g_signal_connect_object(gesture, "pressed", G_CALLBACK(webkitWebViewBaseTouchPress), viewWidget, G_CONNECT_SWAPPED);
-    g_signal_connect_object(gesture, "released", G_CALLBACK(webkitWebViewBaseTouchRelease), viewWidget, G_CONNECT_SWAPPED);
-
-#if USE(GTK4)
     gesture = gtk_gesture_drag_new();
     gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
 #else