Title: [277172] trunk/Source
Revision
277172
Author
commit-qu...@webkit.org
Date
2021-05-07 07:55:50 -0700 (Fri, 07 May 2021)

Log Message

[GTK4] Rewrite GTK gesture support to work for both 3.x and 4.x.
https://bugs.webkit.org/show_bug.cgi?id=212324

Patch by Carlos Garnacho <carl...@gnome.org> on 2021-05-07
Reviewed by Carlos Garcia Campos.

Source/WebCore:

* platform/gtk/GtkVersioning.h:
(gtk_event_controller_get_current_event_state):
(gtk_event_controller_get_current_event_time): New GTK4 portability
helper methods.

Source/WebKit:

Rewrite the touch gesture handling to avoid GdkEvent as an exchange
token, and not rely on the web view being able to hold and re-route
these at whim. This makes touch and touchpad gestures work on GTK3
and GTK4 in similar ways, and so that both work.

For this, touch event propagation got some substantial changes, it
used to work by first delivering the touch events to the web page,
and manually feeding the returned+unhandled ones to gesture controllers.
Now event delivery is delegated on GTK, and happens right away on
gesture controllers, it is the WebkitWebViewBase which chooses to make
them effective after the web page (maybe) handled the events. Gestures
are reset whenever the web page is considered to be handling touch
events.

Also fix some buglets accumulated along the way, web view zoom conflicted
with in-page zoom handling, and ViewGestureController page switching
conflicted with press-drag-release emulation on the web page. These now
work better and closer to GtkScrolledWindow behavior.

No new tests, the GTK touch tests that should catch this were disabled
in the past and need fixing. This patch will require manual testing.

* PlatformGTK.cmake: Drop GTK4 conditionals around ViewGestureController
* SourcesGTK.txt: Drop GestureController.cpp. Build ViewGestureController
code files unconditionally.
* UIProcess/API/gtk/PageClientImpl.cpp:
(WebKit::PageClientImpl::doneWithTouchEvent): Delegate handling on
WebKitWebViewBase.
(WebKit::PageClientImpl::wheelEventWasNotHandledByWebCore): Use platform
independent struct to forward scroll to ViewGestureController.
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseSnapshot): Involve ViewGestureController in rendering.
(webkitWebViewBaseButtonPressEvent):
(webkitWebViewBaseButtonReleaseEvent):
(webkitWebViewBaseButtonPressed):
(webkitWebViewBaseButtonReleased):
(webkitWebViewBaseMotionNotifyEvent): Ignore pointer-emulated events from
touchscreens.
(webkitWebViewBaseHandleWheelEvent):
(webkitWebViewBaseScroll):  Use platform independent struct
to forward scroll to ViewGestureController.
(appendTouchEvent):
(touchPointStateForEvents):
(webkitWebViewBaseGetTouchPointsForEvent):
(webkitWebViewBaseTouchEvent):
Generalized to work on both GTK3 and GTK4.
(webkitWebViewBaseZoomBegin):
(webkitWebViewBaseZoomChanged):
(webkitWebViewBaseTouchLongPress):
(webkitWebViewBaseTouchPress):
(webkitWebViewBaseTouchRelease):
(webkitWebViewBaseTouchDragBegin):
(webkitWebViewBaseTouchDragUpdate):
(webkitWebViewBaseTouchDragEnd):
(webkitWebViewBaseTouchDragCancel):
(webkitWebViewBaseTouchSwipe): Newly added touch gesture implementation
callbacks. Not delegated anymore on GestureController.
(webkitWebViewBaseConstructed): Create touch gestures in the base view
widget, let them handle events automatically instead of relying on
manual event feeding via gtk_event_controller_handle_event(). Also add
a GtkEventControllerLegacy to handle forwarding of raw touch events to
the web page in GTK4.
(webkitWebViewBaseSetEnableBackForwardNavigationGesture):
(webkitWebViewBaseViewGestureController):
(webkitWebViewBaseBeginBackSwipeForTesting):
(webkitWebViewBaseCompleteBackSwipeForTesting):
(webkitWebViewBaseWillSwapWebProcess):
(webkitWebViewBaseDidExitWebProcess):
(webkitWebViewBaseDidRelaunchWebProcess):
(webkitWebViewBaseDidStartProvisionalLoadForMainFrame):
(webkitWebViewBaseDidFirstVisuallyNonEmptyLayoutForMainFrame):
(webkitWebViewBaseDidFinishNavigation):
(webkitWebViewBaseDidFailNavigation):
(webkitWebViewBaseDidSameDocumentNavigationForMainFrame):
(webkitWebViewBaseDidRestoreScrollPosition): Remove conditionals around
ViewGestureController for GTK4.
(webkitWebViewBasePageGrabbedTouch): New method to tag touch events
altogether as handled by the web page, thus resetting any ongoing view-level
gesture handling. This inversion is necessary as gesture controllers are now
always fed input events parallel to web page touch event handling.
(webkitWebViewBaseGestureController): Deleted.
(webkit_web_view_base_class_init):
(webkitWebViewBaseEvent): Removed widget_class->event vfunc. Touchpad gesture
event forwarding to event controllers is delegated on GTK.
* UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
* UIProcess/ViewGestureController.h:
* UIProcess/gtk/GestureController.cpp: Removed. Gestures are implemented in
the base view.
* UIProcess/gtk/GestureController.h: Removed.
* UIProcess/gtk/ViewGestureControllerGtk.cpp:
(WebKit::isEventStop):
(WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanStartSwipe):
(WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanEndSwipe):
(WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanInfluenceSwipe):
(WebKit::isTouchEvent):
(WebKit::createScrollEvent):
(WebKit::ViewGestureController::PendingSwipeTracker::scrollEventGetScrollingDeltas):
(WebKit::ViewGestureController::handleScrollWheelEvent):
(WebKit::ViewGestureController::SwipeProgressTracker::handleEvent):
(WebKit::ViewGestureController::beginSwipeGesture):
(WebKit::ViewGestureController::beginSimulatedSwipeInDirectionForTesting):
(WebKit::ViewGestureController::completeSimulatedSwipeInDirectionForTesting): Declare
PlatformGtkScrollData, and use it as "platform scroll event" for both GTK3 and GTK4.
(WebKit::ViewGestureController::snapshot): New GTK4 specific method to render
the page switching gesture action.

Modified Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277171 => 277172)


--- trunk/Source/WebCore/ChangeLog	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebCore/ChangeLog	2021-05-07 14:55:50 UTC (rev 277172)
@@ -1,3 +1,15 @@
+2021-05-07  Carlos Garnacho  <carl...@gnome.org>
+
+        [GTK4] Rewrite GTK gesture support to work for both 3.x and 4.x.
+        https://bugs.webkit.org/show_bug.cgi?id=212324
+
+        Reviewed by Carlos Garcia Campos.
+
+        * platform/gtk/GtkVersioning.h:
+        (gtk_event_controller_get_current_event_state):
+        (gtk_event_controller_get_current_event_time): New GTK4 portability
+        helper methods.
+
 2021-05-07  Youenn Fablet  <you...@apple.com>
 
         Add WebRTC logging control in GPUProcess

Modified: trunk/Source/WebCore/platform/gtk/GtkVersioning.h (277171 => 277172)


--- trunk/Source/WebCore/platform/gtk/GtkVersioning.h	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebCore/platform/gtk/GtkVersioning.h	2021-05-07 14:55:50 UTC (rev 277172)
@@ -276,4 +276,18 @@
     return gtk_scrolled_window_new(nullptr, nullptr);
 }
 
+static inline GdkModifierType
+gtk_event_controller_get_current_event_state(GtkEventController*)
+{
+    GdkModifierType modifiers;
+    gtk_get_current_event_state(&modifiers);
+    return modifiers;
+}
+
+static inline uint32_t
+gtk_event_controller_get_current_event_time(GtkEventController*)
+{
+    return gtk_get_current_event_time();
+}
+
 #endif // USE(GTK4)

Modified: trunk/Source/WebKit/ChangeLog (277171 => 277172)


--- trunk/Source/WebKit/ChangeLog	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/ChangeLog	2021-05-07 14:55:50 UTC (rev 277172)
@@ -1,3 +1,116 @@
+2021-05-07  Carlos Garnacho  <carl...@gnome.org>
+
+        [GTK4] Rewrite GTK gesture support to work for both 3.x and 4.x.
+        https://bugs.webkit.org/show_bug.cgi?id=212324
+
+        Reviewed by Carlos Garcia Campos.
+
+        Rewrite the touch gesture handling to avoid GdkEvent as an exchange
+        token, and not rely on the web view being able to hold and re-route
+        these at whim. This makes touch and touchpad gestures work on GTK3
+        and GTK4 in similar ways, and so that both work.
+
+        For this, touch event propagation got some substantial changes, it
+        used to work by first delivering the touch events to the web page,
+        and manually feeding the returned+unhandled ones to gesture controllers.
+        Now event delivery is delegated on GTK, and happens right away on
+        gesture controllers, it is the WebkitWebViewBase which chooses to make
+        them effective after the web page (maybe) handled the events. Gestures
+        are reset whenever the web page is considered to be handling touch
+        events.
+
+        Also fix some buglets accumulated along the way, web view zoom conflicted
+        with in-page zoom handling, and ViewGestureController page switching
+        conflicted with press-drag-release emulation on the web page. These now
+        work better and closer to GtkScrolledWindow behavior.
+
+        No new tests, the GTK touch tests that should catch this were disabled
+        in the past and need fixing. This patch will require manual testing.
+
+        * PlatformGTK.cmake: Drop GTK4 conditionals around ViewGestureController
+        * SourcesGTK.txt: Drop GestureController.cpp. Build ViewGestureController
+        code files unconditionally.
+        * UIProcess/API/gtk/PageClientImpl.cpp:
+        (WebKit::PageClientImpl::doneWithTouchEvent): Delegate handling on
+        WebKitWebViewBase.
+        (WebKit::PageClientImpl::wheelEventWasNotHandledByWebCore): Use platform
+        independent struct to forward scroll to ViewGestureController.
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseSnapshot): Involve ViewGestureController in rendering.
+        (webkitWebViewBaseButtonPressEvent):
+        (webkitWebViewBaseButtonReleaseEvent):
+        (webkitWebViewBaseButtonPressed):
+        (webkitWebViewBaseButtonReleased):
+        (webkitWebViewBaseMotionNotifyEvent): Ignore pointer-emulated events from
+        touchscreens.
+        (webkitWebViewBaseHandleWheelEvent):
+        (webkitWebViewBaseScroll):  Use platform independent struct
+        to forward scroll to ViewGestureController.
+        (appendTouchEvent):
+        (touchPointStateForEvents):
+        (webkitWebViewBaseGetTouchPointsForEvent):
+        (webkitWebViewBaseTouchEvent):
+        Generalized to work on both GTK3 and GTK4.
+        (webkitWebViewBaseZoomBegin):
+        (webkitWebViewBaseZoomChanged):
+        (webkitWebViewBaseTouchLongPress):
+        (webkitWebViewBaseTouchPress):
+        (webkitWebViewBaseTouchRelease):
+        (webkitWebViewBaseTouchDragBegin):
+        (webkitWebViewBaseTouchDragUpdate):
+        (webkitWebViewBaseTouchDragEnd):
+        (webkitWebViewBaseTouchDragCancel):
+        (webkitWebViewBaseTouchSwipe): Newly added touch gesture implementation
+        callbacks. Not delegated anymore on GestureController.
+        (webkitWebViewBaseConstructed): Create touch gestures in the base view
+        widget, let them handle events automatically instead of relying on
+        manual event feeding via gtk_event_controller_handle_event(). Also add
+        a GtkEventControllerLegacy to handle forwarding of raw touch events to
+        the web page in GTK4.
+        (webkitWebViewBaseSetEnableBackForwardNavigationGesture):
+        (webkitWebViewBaseViewGestureController):
+        (webkitWebViewBaseBeginBackSwipeForTesting):
+        (webkitWebViewBaseCompleteBackSwipeForTesting):
+        (webkitWebViewBaseWillSwapWebProcess):
+        (webkitWebViewBaseDidExitWebProcess):
+        (webkitWebViewBaseDidRelaunchWebProcess):
+        (webkitWebViewBaseDidStartProvisionalLoadForMainFrame):
+        (webkitWebViewBaseDidFirstVisuallyNonEmptyLayoutForMainFrame):
+        (webkitWebViewBaseDidFinishNavigation):
+        (webkitWebViewBaseDidFailNavigation):
+        (webkitWebViewBaseDidSameDocumentNavigationForMainFrame):
+        (webkitWebViewBaseDidRestoreScrollPosition): Remove conditionals around
+        ViewGestureController for GTK4.
+        (webkitWebViewBasePageGrabbedTouch): New method to tag touch events
+        altogether as handled by the web page, thus resetting any ongoing view-level
+        gesture handling. This inversion is necessary as gesture controllers are now
+        always fed input events parallel to web page touch event handling.
+        (webkitWebViewBaseGestureController): Deleted.
+        (webkit_web_view_base_class_init):
+        (webkitWebViewBaseEvent): Removed widget_class->event vfunc. Touchpad gesture
+        event forwarding to event controllers is delegated on GTK.
+        * UIProcess/API/gtk/WebKitWebViewBasePrivate.h:
+        * UIProcess/ViewGestureController.h:
+        * UIProcess/gtk/GestureController.cpp: Removed. Gestures are implemented in
+        the base view.
+        * UIProcess/gtk/GestureController.h: Removed.
+        * UIProcess/gtk/ViewGestureControllerGtk.cpp:
+        (WebKit::isEventStop):
+        (WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanStartSwipe):
+        (WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanEndSwipe):
+        (WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanInfluenceSwipe):
+        (WebKit::isTouchEvent):
+        (WebKit::createScrollEvent):
+        (WebKit::ViewGestureController::PendingSwipeTracker::scrollEventGetScrollingDeltas):
+        (WebKit::ViewGestureController::handleScrollWheelEvent):
+        (WebKit::ViewGestureController::SwipeProgressTracker::handleEvent):
+        (WebKit::ViewGestureController::beginSwipeGesture):
+        (WebKit::ViewGestureController::beginSimulatedSwipeInDirectionForTesting):
+        (WebKit::ViewGestureController::completeSimulatedSwipeInDirectionForTesting): Declare
+        PlatformGtkScrollData, and use it as "platform scroll event" for both GTK3 and GTK4.
+        (WebKit::ViewGestureController::snapshot): New GTK4 specific method to render
+        the page switching gesture action.
+
 2021-05-07  Youenn Fablet  <you...@apple.com>
 
         Add WebRTC logging control in GPUProcess

Modified: trunk/Source/WebKit/PlatformGTK.cmake (277171 => 277172)


--- trunk/Source/WebKit/PlatformGTK.cmake	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/PlatformGTK.cmake	2021-05-07 14:55:50 UTC (rev 277172)
@@ -33,21 +33,12 @@
     "SourcesGTK.txt"
 )
 
-if (NOT USE_GTK4)
-    list(APPEND WebKit_SOURCES
-        UIProcess/ViewGestureController.cpp
+list(APPEND WebKit_MESSAGES_IN_FILES
+    UIProcess/ViewGestureController
 
-        UIProcess/gtk/ViewGestureControllerGtk.cpp
+    WebProcess/WebPage/ViewGestureGeometryCollector
+)
 
-        WebProcess/WebPage/ViewGestureGeometryCollector.cpp
-    )
-    list(APPEND WebKit_MESSAGES_IN_FILES
-        UIProcess/ViewGestureController
-
-        WebProcess/WebPage/ViewGestureGeometryCollector
-    )
-endif ()
-
 list(APPEND WebKit_DERIVED_SOURCES
     ${WebKit2Gtk_DERIVED_SOURCES_DIR}/InspectorGResourceBundle.c
     ${WebKit2Gtk_DERIVED_SOURCES_DIR}/WebKitDirectoryInputStreamData.cpp

Modified: trunk/Source/WebKit/SourcesGTK.txt (277171 => 277172)


--- trunk/Source/WebKit/SourcesGTK.txt	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/SourcesGTK.txt	2021-05-07 14:55:50 UTC (rev 277172)
@@ -105,6 +105,7 @@
 UIProcess/BackingStore.cpp
 UIProcess/DefaultUndoController.cpp
 UIProcess/LegacySessionStateCodingNone.cpp
+UIProcess/ViewGestureController.cpp
 UIProcess/ViewSnapshotStore.cpp
 UIProcess/WebGrammarDetail.cpp
 UIProcess/WebMemoryPressureHandler.cpp
@@ -252,7 +253,6 @@
 UIProcess/gtk/ClipboardGtk3.cpp @no-unify
 UIProcess/gtk/ClipboardGtk4.cpp @no-unify
 UIProcess/gtk/WebDateTimePickerGtk.cpp
-UIProcess/gtk/GestureController.cpp
 UIProcess/gtk/HardwareAccelerationManager.cpp
 UIProcess/gtk/KeyBindingTranslator.cpp
 UIProcess/gtk/PointerLockManager.cpp @no-unify
@@ -260,6 +260,7 @@
 UIProcess/gtk/PointerLockManagerX11.cpp @no-unify
 UIProcess/gtk/TextCheckerGtk.cpp @no-unify
 UIProcess/gtk/ViewSnapshotStoreGtk.cpp
+UIProcess/gtk/ViewGestureControllerGtk.cpp
 UIProcess/gtk/WaylandCompositor.cpp @no-unify
 UIProcess/gtk/WebColorPickerGtk.cpp
 UIProcess/gtk/WebContextMenuProxyGtk.cpp
@@ -415,6 +416,7 @@
 WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp
 
 WebProcess/WebPage/AcceleratedSurface.cpp
+WebProcess/WebPage/ViewGestureGeometryCollector.cpp
 
 WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp
 WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp

Modified: trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp (277171 => 277172)


--- trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp	2021-05-07 14:55:50 UTC (rev 277172)
@@ -412,65 +412,8 @@
 #if ENABLE(TOUCH_EVENTS)
 void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
 {
-#if !USE(GTK4)
-    const GdkEvent* touchEvent = event.nativeEvent();
-    if (!touchEvent)
-        return;
-
-    GestureController& gestureController = webkitWebViewBaseGestureController(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
-    if (wasEventHandled) {
-        gestureController.reset();
-        return;
-    }
-    wasEventHandled = gestureController.handleEvent(const_cast<GdkEvent*>(event.nativeEvent()));
-
     if (wasEventHandled)
-        return;
-
-    // Emulate pointer events if unhandled.
-    if (!touchEvent->touch.emulating_pointer)
-        return;
-
-    GUniquePtr<GdkEvent> pointerEvent;
-
-    if (touchEvent->type == GDK_TOUCH_UPDATE) {
-        pointerEvent.reset(gdk_event_new(GDK_MOTION_NOTIFY));
-        pointerEvent->motion.time = touchEvent->touch.time;
-        pointerEvent->motion.x = touchEvent->touch.x;
-        pointerEvent->motion.y = touchEvent->touch.y;
-        pointerEvent->motion.x_root = touchEvent->touch.x_root;
-        pointerEvent->motion.y_root = touchEvent->touch.y_root;
-        pointerEvent->motion.state = touchEvent->touch.state | GDK_BUTTON1_MASK;
-    } else {
-        switch (touchEvent->type) {
-        case GDK_TOUCH_CANCEL:
-            FALLTHROUGH;
-        case GDK_TOUCH_END:
-            pointerEvent.reset(gdk_event_new(GDK_BUTTON_RELEASE));
-            pointerEvent->button.state = touchEvent->touch.state | GDK_BUTTON1_MASK;
-            break;
-        case GDK_TOUCH_BEGIN:
-            pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS));
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-        }
-
-        pointerEvent->button.button = 1;
-        pointerEvent->button.time = touchEvent->touch.time;
-        pointerEvent->button.x = touchEvent->touch.x;
-        pointerEvent->button.y = touchEvent->touch.y;
-        pointerEvent->button.x_root = touchEvent->touch.x_root;
-        pointerEvent->button.y_root = touchEvent->touch.y_root;
-    }
-
-    gdk_event_set_device(pointerEvent.get(), gdk_event_get_device(touchEvent));
-    gdk_event_set_source_device(pointerEvent.get(), gdk_event_get_source_device(touchEvent));
-    pointerEvent->any.window = GDK_WINDOW(g_object_ref(touchEvent->any.window));
-    pointerEvent->any.send_event = TRUE;
-
-    gtk_widget_event(m_viewWidget, pointerEvent.get());
-#endif
+        webkitWebViewBasePageGrabbedTouch(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
 }
 #endif // ENABLE(TOUCH_EVENTS)
 
@@ -482,7 +425,12 @@
 #if !USE(GTK4)
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(WEBKIT_WEB_VIEW_BASE(m_viewWidget));
     if (controller && controller->isSwipeGestureEnabled()) {
-        controller->wheelEventWasNotHandledByWebCore(&event.nativeEvent()->scroll);
+        double deltaX;
+        gdk_event_get_scroll_deltas(event.nativeEvent(), &deltaX, nullptr);
+        bool isEnd = gdk_event_is_scroll_stop_event(event.nativeEvent()) ? true : false;
+        int32_t eventTime = static_cast<int32_t>(gdk_event_get_time(event.nativeEvent()));
+        PlatformGtkScrollData scrollData = { .delta = deltaX, .eventTime = eventTime, .isTouch = false, .isEnd = isEnd };
+        controller->wheelEventWasNotHandledByWebCore(&scrollData);
         return;
     }
 

Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp (277171 => 277172)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp	2021-05-07 14:55:50 UTC (rev 277172)
@@ -316,11 +316,9 @@
     std::unique_ptr<DropTarget> dropTarget;
 #endif
 
-#if !USE(GTK4)
-    std::unique_ptr<GestureController> gestureController;
+    GtkGesture* touchGestureGroup;
     std::unique_ptr<ViewGestureController> viewGestureController;
     bool isBackForwardNavigationGestureEnabled { false };
-#endif
 
 #if GTK_CHECK_VERSION(3, 24, 0)
     GtkWidget* emojiChooser;
@@ -328,6 +326,14 @@
     RunLoop::Timer<WebKitWebViewBasePrivate> releaseEmojiChooserTimer;
 #endif
 
+    // Touch gestures state
+    double initialZoomScale;
+    IntPoint initialZoomPoint;
+    FloatPoint dragOffset;
+    bool isLongPressed;
+    bool isBeingDragged;
+    bool pageGrabbedTouch;
+
     std::unique_ptr<PointerLockManager> pointerLockManager;
 };
 
@@ -746,11 +752,23 @@
     if (!drawingArea)
         return;
 
+    auto* pageSnapshot = gtk_snapshot_new();
     if (!webViewBase->priv->isBlank) {
         ASSERT(drawingArea->isInAcceleratedCompositingMode());
-        webViewBase->priv->acceleratedBackingStore->snapshot(snapshot);
+        webViewBase->priv->acceleratedBackingStore->snapshot(pageSnapshot);
     }
 
+    if (auto* pageRenderNode = gtk_snapshot_free_to_node(pageSnapshot)) {
+        bool showingNavigationSnapshot = webViewBase->priv->pageProxy->isShowingNavigationGestureSnapshot();
+        auto* controller = webkitWebViewBaseViewGestureController(webViewBase);
+        if (showingNavigationSnapshot && controller)
+            controller->snapshot(snapshot, pageRenderNode);
+        else
+            gtk_snapshot_append_node(snapshot, pageRenderNode);
+
+        gsk_render_node_unref(pageRenderNode);
+    }
+
     if (webViewBase->priv->inspectorView)
         gtk_widget_snapshot_child(widget, webViewBase->priv->inspectorView, snapshot);
 
@@ -1157,6 +1175,9 @@
     if (priv->dialog)
         return GDK_EVENT_STOP;
 
+    if (gdk_device_get_source(gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event))) == GDK_SOURCE_TOUCHSCREEN)
+        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->button_press_event(widget, event);
+
     webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
 
     return GDK_EVENT_STOP;
@@ -1169,6 +1190,8 @@
 
     if (priv->dialog)
         return GDK_EVENT_STOP;
+    if (gdk_device_get_source(gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event))) == GDK_SOURCE_TOUCHSCREEN)
+        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->button_release_event(widget, event);
 
     webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
 
@@ -1179,6 +1202,8 @@
 #if USE(GTK4)
 static void webkitWebViewBaseButtonPressed(WebKitWebViewBase* webViewBase, int clickCount, double x, double y, GtkGesture* gesture)
 {
+    if (gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)))
+        return;
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
     if (priv->dialog)
         return;
@@ -1202,6 +1227,8 @@
 
 static void webkitWebViewBaseButtonReleased(WebKitWebViewBase* webViewBase, int clickCount, double x, double y, GtkGesture* gesture)
 {
+    if (gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)))
+        return;
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
     if (priv->dialog)
         return;
@@ -1234,8 +1261,15 @@
 static void webkitWebViewBaseHandleWheelEvent(WebKitWebViewBase* webViewBase, GdkEvent* event, Optional<WebWheelEvent::Phase> phase = WTF::nullopt, Optional<WebWheelEvent::Phase> momentum = WTF::nullopt)
 {
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
-    if (controller && controller->isSwipeGestureEnabled() && controller->handleScrollWheelEvent(reinterpret_cast<GdkEventScroll*>(event)))
-        return;
+    if (controller && controller->isSwipeGestureEnabled()) {
+        double deltaX;
+        gdk_event_get_scroll_deltas(event, &deltaX, nullptr);
+        bool isEnd = gdk_event_is_scroll_stop_event(event) ? true : false;
+        int32_t eventTime = static_cast<int32_t>(gdk_event_get_time(event));
+        PlatformGtkScrollData scrollData = { .delta = deltaX, .eventTime = eventTime, .isTouch = false, .isEnd = isEnd };
+        if (controller->handleScrollWheelEvent(&scrollData))
+            return;
+    }
 
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
     ASSERT(!priv->dialog);
@@ -1283,14 +1317,23 @@
 #endif
 
 #if USE(GTK4)
-static gboolean webkitWebViewBaseScroll(WebKitWebViewBase* webViewBase, double deltaX, double deltaY, GtkEventController* controller)
+static gboolean webkitWebViewBaseScroll(WebKitWebViewBase* webViewBase, double deltaX, double deltaY, GtkEventController* eventController)
 {
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
     if (priv->dialog)
         return GDK_EVENT_PROPAGATE;
 
-    auto* event = gtk_event_controller_get_current_event(controller);
+    auto* event = gtk_event_controller_get_current_event(eventController);
 
+    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
+    if (controller && controller->isSwipeGestureEnabled()) {
+        bool isEnd = gdk_scroll_event_is_stop(event) ? true : false;
+        int32_t eventTime = static_cast<int32_t>(gtk_event_controller_get_current_event_time(eventController));
+        PlatformGtkScrollData scrollData = { .delta = deltaX, .eventTime = eventTime, .isTouch = false, .isEnd = isEnd };
+        if (controller->handleScrollWheelEvent(&scrollData))
+            return GDK_EVENT_STOP;
+    }
+
     if (shouldInvertDirectionForScrollEvent(priv->mouseIsOverScrollbar, gdk_event_get_modifier_state(event) & GDK_SHIFT_MASK))
         std::swap(deltaX, deltaY);
 
@@ -1330,6 +1373,9 @@
         return widgetClass->motion_notify_event ? widgetClass->motion_notify_event(widget, event) : GDK_EVENT_PROPAGATE;
     }
 
+    if (gdk_device_get_source(gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event))) == GDK_SOURCE_TOUCHSCREEN)
+        return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->motion_notify_event(widget, event);
+
     if (priv->pointerLockManager) {
         double x, y;
         gdk_event_get_root_coords(reinterpret_cast<GdkEvent*>(event), &x, &y);
@@ -1453,11 +1499,16 @@
 }
 #endif
 
-#if ENABLE(TOUCH_EVENTS) && !USE(GTK4)
-static void appendTouchEvent(Vector<WebPlatformTouchPoint>& touchPoints, const GdkEvent* event, WebPlatformTouchPoint::TouchPointState state)
+#if ENABLE(TOUCH_EVENTS)
+static void appendTouchEvent(GtkWidget* webViewBase, Vector<WebPlatformTouchPoint>& touchPoints, GdkEvent* event, WebPlatformTouchPoint::TouchPointState state)
 {
     gdouble x, y;
     gdk_event_get_coords(event, &x, &y);
+#if USE(GTK4)
+    // Events in GTK4 are given in native surface coordinates
+    gtk_widget_translate_coordinates(GTK_WIDGET(gtk_widget_get_native(webViewBase)),
+        webViewBase, x, y, &x, &y);
+#endif
 
     gdouble xRoot, yRoot;
     gdk_event_get_root_coords(event, &xRoot, &yRoot);
@@ -1466,12 +1517,12 @@
     touchPoints.uncheckedAppend(WebPlatformTouchPoint(identifier, state, IntPoint(xRoot, yRoot), IntPoint(x, y)));
 }
 
-static inline WebPlatformTouchPoint::TouchPointState touchPointStateForEvents(const GdkEvent* current, const GdkEvent* event)
+static inline WebPlatformTouchPoint::TouchPointState touchPointStateForEvents(GdkEvent* current, GdkEvent* event)
 {
     if (gdk_event_get_event_sequence(current) != gdk_event_get_event_sequence(event))
         return WebPlatformTouchPoint::TouchStationary;
 
-    switch (current->type) {
+    switch (gdk_event_get_event_type(event)) {
     case GDK_TOUCH_UPDATE:
         return WebPlatformTouchPoint::TouchMoved;
     case GDK_TOUCH_BEGIN:
@@ -1492,15 +1543,20 @@
     bool touchEnd = (type == GDK_TOUCH_END) || (type == GDK_TOUCH_CANCEL);
     touchPoints.reserveInitialCapacity(touchEnd ? priv->touchEvents.size() + 1 : priv->touchEvents.size());
 
+    GtkWidget* widget = GTK_WIDGET(webViewBase);
     for (const auto& it : priv->touchEvents)
-        appendTouchEvent(touchPoints, it.value.get(), touchPointStateForEvents(it.value.get(), event));
+        appendTouchEvent(widget, touchPoints, it.value.get(), touchPointStateForEvents(it.value.get(), event));
 
     // Touch was already removed from the TouchEventsMap, add it here.
     if (touchEnd)
-        appendTouchEvent(touchPoints, event, WebPlatformTouchPoint::TouchReleased);
+        appendTouchEvent(widget, touchPoints, event, WebPlatformTouchPoint::TouchReleased);
 }
 
+#if USE(GTK4)
+static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEvent* event)
+#else
 static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEventTouch* event)
+#endif
 {
     WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
@@ -1514,6 +1570,8 @@
     GdkEventType type = gdk_event_get_event_type(touchEvent);
     switch (type) {
     case GDK_TOUCH_BEGIN: {
+        if (priv->touchEvents.isEmpty())
+            priv->pageGrabbedTouch = false;
         ASSERT(!priv->touchEvents.contains(sequence));
         GUniquePtr<GdkEvent> event(gdk_event_copy(touchEvent));
         priv->touchEvents.add(sequence, WTFMove(event));
@@ -1532,7 +1590,10 @@
         priv->touchEvents.remove(sequence);
         break;
     default:
-        break;
+#if !USE(GTK4)
+        ASSERT_NOT_REACHED();
+#endif
+        return GDK_EVENT_PROPAGATE;
     }
 
     Vector<WebPlatformTouchPoint> touchPoints;
@@ -1539,142 +1600,16 @@
     webkitWebViewBaseGetTouchPointsForEvent(webViewBase, touchEvent, touchPoints);
     priv->pageProxy->handleTouchEvent(NativeWebTouchEvent(reinterpret_cast<GdkEvent*>(event), WTFMove(touchPoints)));
 
-    return GDK_EVENT_STOP;
+#if USE(GTK4)
+    return GDK_EVENT_PROPAGATE;
+#else
+    return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->touch_event(widget, event);
+#endif
 }
 #endif // ENABLE(TOUCH_EVENTS)
 
-#if !USE(GTK4)
-class TouchGestureController final : public GestureControllerClient {
-    WTF_MAKE_FAST_ALLOCATED;
-
-public:
-    explicit TouchGestureController(WebKitWebViewBase* webViewBase)
-        : m_webView(webViewBase)
-    {
-    }
-
-private:
-    static GUniquePtr<GdkEvent> createScrollEvent(GdkEventTouch* event, const FloatPoint& point, const FloatPoint& delta, bool isStop = false)
-    {
-        GUniquePtr<GdkEvent> scrollEvent(gdk_event_new(GDK_SCROLL));
-        scrollEvent->scroll.time = event->time;
-        scrollEvent->scroll.x = point.x();
-        scrollEvent->scroll.y = point.y();
-        scrollEvent->scroll.x_root = event->x_root;
-        scrollEvent->scroll.y_root = event->y_root;
-        scrollEvent->scroll.direction = GDK_SCROLL_SMOOTH;
-        scrollEvent->scroll.delta_x = delta.x();
-        scrollEvent->scroll.delta_y = delta.y();
-        scrollEvent->scroll.state = event->state;
-        scrollEvent->scroll.is_stop = isStop;
-        scrollEvent->scroll.window = event->window ? GDK_WINDOW(g_object_ref(event->window)) : nullptr;
-        auto* touchEvent = reinterpret_cast<GdkEvent*>(event);
-        gdk_event_set_screen(scrollEvent.get(), gdk_event_get_screen(touchEvent));
-        gdk_event_set_device(scrollEvent.get(), gdk_event_get_device(touchEvent));
-        gdk_event_set_source_device(scrollEvent.get(), gdk_event_get_source_device(touchEvent));
-        return scrollEvent;
-    }
-
-    void simulateMouseClick(GdkEventTouch* event, unsigned button)
-    {
-        GUniquePtr<GdkEvent> pointerEvent(gdk_event_new(GDK_MOTION_NOTIFY));
-        pointerEvent->motion.time = event->time;
-        pointerEvent->motion.x = event->x;
-        pointerEvent->motion.y = event->y;
-        pointerEvent->motion.x_root = event->x_root;
-        pointerEvent->motion.y_root = event->y_root;
-        pointerEvent->motion.state = event->state;
-        pointerEvent->motion.window = event->window ? GDK_WINDOW(g_object_ref(event->window)) : nullptr;
-        auto* touchEvent = reinterpret_cast<GdkEvent*>(event);
-        gdk_event_set_screen(pointerEvent.get(), gdk_event_get_screen(touchEvent));
-        gdk_event_set_device(pointerEvent.get(), gdk_event_get_device(touchEvent));
-        gdk_event_set_source_device(pointerEvent.get(), gdk_event_get_source_device(touchEvent));
-        webkitWebViewBaseHandleMouseEvent(m_webView, pointerEvent.get());
-
-        pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS));
-        pointerEvent->button.button = button;
-        pointerEvent->button.time = event->time;
-        pointerEvent->button.x = event->x;
-        pointerEvent->button.y = event->y;
-        pointerEvent->button.x_root = event->x_root;
-        pointerEvent->button.y_root = event->y_root;
-        pointerEvent->button.window = event->window ? GDK_WINDOW(g_object_ref(event->window)) : nullptr;
-        gdk_event_set_screen(pointerEvent.get(), gdk_event_get_screen(touchEvent));
-        gdk_event_set_device(pointerEvent.get(), gdk_event_get_device(touchEvent));
-        gdk_event_set_source_device(pointerEvent.get(), gdk_event_get_source_device(touchEvent));
-        webkitWebViewBaseHandleMouseEvent(m_webView, pointerEvent.get());
-
-        pointerEvent->type = GDK_BUTTON_RELEASE;
-        webkitWebViewBaseHandleMouseEvent(m_webView, pointerEvent.get());
-    }
-
-    void tap(GdkEventTouch* event) final
-    {
-        simulateMouseClick(event, GDK_BUTTON_PRIMARY);
-    }
-
-    void startDrag(GdkEventTouch* event, const FloatPoint& startPoint) final
-    {
-        GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, startPoint, { });
-        webkitWebViewBaseHandleWheelEvent(m_webView, scrollEvent.get(), WebWheelEvent::Phase::PhaseBegan);
-    }
-
-    void drag(GdkEventTouch* event, const FloatPoint& point, const FloatPoint& delta) final
-    {
-        GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, point, delta);
-        webkitWebViewBaseHandleWheelEvent(m_webView, scrollEvent.get(), WebWheelEvent::Phase::PhaseChanged);
-    }
-
-    void cancelDrag() final
-    {
-        if (auto* controller = webkitWebViewBaseViewGestureController(m_webView))
-            controller->cancelSwipe();
-    }
-
-    void swipe(GdkEventTouch* event, const FloatPoint& velocity) final
-    {
-        double x, y;
-        gdk_event_get_coords(reinterpret_cast<GdkEvent*>(event), &x, &y);
-        GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, FloatPoint::narrowPrecision(x, y), velocity, true);
-        webkitWebViewBaseHandleWheelEvent(m_webView, scrollEvent.get(), WebWheelEvent::Phase::PhaseNone, WebWheelEvent::Phase::PhaseBegan);
-    }
-
-    void startZoom(const IntPoint& center, double& initialScale, IntPoint& initialPoint) final
-    {
-        auto* page = m_webView->priv->pageProxy.get();
-        ASSERT(page);
-        initialScale = page->pageScaleFactor();
-        page->getCenterForZoomGesture(center, initialPoint);
-    }
-
-    void zoom(double scale, const IntPoint& origin) final
-    {
-        auto* page = m_webView->priv->pageProxy.get();
-        ASSERT(page);
-
-        page->scalePage(scale, origin);
-    }
-
-    void longPress(GdkEventTouch* event) final
-    {
-        simulateMouseClick(event, GDK_BUTTON_SECONDARY);
-    }
-
-    WebKitWebViewBase* m_webView;
-};
-
-GestureController& webkitWebViewBaseGestureController(WebKitWebViewBase* webViewBase)
-{
-    WebKitWebViewBasePrivate* priv = webViewBase->priv;
-    if (!priv->gestureController)
-        priv->gestureController = makeUnique<GestureController>(GTK_WIDGET(webViewBase), makeUnique<TouchGestureController>(webViewBase));
-    return *priv->gestureController;
-}
-#endif
-
 void webkitWebViewBaseSetEnableBackForwardNavigationGesture(WebKitWebViewBase* webViewBase, bool enabled)
 {
-#if !USE(GTK4)
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
     priv->isBackForwardNavigationGestureEnabled = enabled;
 
@@ -1682,22 +1617,17 @@
         controller->setSwipeGestureEnabled(enabled);
 
     priv->pageProxy->setShouldRecordNavigationSnapshots(enabled);
-#endif
 }
 
-#if !USE(GTK4)
 ViewGestureController* webkitWebViewBaseViewGestureController(WebKitWebViewBase* webViewBase)
 {
     return webViewBase->priv->viewGestureController.get();
 }
-#endif
 
 bool webkitWebViewBaseBeginBackSwipeForTesting(WebKitWebViewBase* webViewBase)
 {
-#if !USE(GTK4)
     if (auto* gestureController = webkitWebViewBaseViewGestureController(webViewBase))
         return gestureController->beginSimulatedSwipeInDirectionForTesting(ViewGestureController::SwipeDirection::Back);
-#endif
 
     return FALSE;
 }
@@ -1704,10 +1634,8 @@
 
 bool webkitWebViewBaseCompleteBackSwipeForTesting(WebKitWebViewBase* webViewBase)
 {
-#if !USE(GTK4)
     if (auto* gestureController = webkitWebViewBaseViewGestureController(webViewBase))
         return gestureController->completeSimulatedSwipeInDirectionForTesting(ViewGestureController::SwipeDirection::Back);
-#endif
 
     return FALSE;
 }
@@ -1736,13 +1664,6 @@
 }
 
 #if !USE(GTK4)
-static gboolean webkitWebViewBaseEvent(GtkWidget* widget, GdkEvent* event)
-{
-    if (gdk_event_get_event_type(event) == GDK_TOUCHPAD_PINCH)
-        webkitWebViewBaseGestureController(WEBKIT_WEB_VIEW_BASE(widget)).handleEvent(event);
-    return GDK_EVENT_PROPAGATE;
-}
-
 static AtkObject* webkitWebViewBaseGetAccessible(GtkWidget* widget)
 {
     WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
@@ -1924,6 +1845,158 @@
     return GTK_WIDGET_CLASS(webkit_web_view_base_parent_class)->focus(widget, direction);
 }
 
+static void webkitWebViewBaseZoomBegin(WebKitWebViewBase* webViewBase, GdkEventSequence* sequence, GtkGesture* gesture)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    priv->initialZoomScale = priv->pageProxy->pageScaleFactor();
+
+    double x, y;
+    gtk_gesture_get_bounding_box_center(gesture, &x, &y);
+    priv->pageProxy->getCenterForZoomGesture(IntPoint(x, y), priv->initialZoomPoint);
+}
+
+static void webkitWebViewBaseZoomChanged(WebKitWebViewBase* webViewBase, gdouble scale, GtkGesture* gesture)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (priv->pageGrabbedTouch)
+        return;
+
+    gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);
+
+    auto pageScale = clampTo<double>(priv->initialZoomScale * scale, 1, 3);
+
+    FloatPoint scaledZoomCenter(priv->initialZoomPoint);
+    scaledZoomCenter.scale(pageScale);
+
+    double x, y;
+    gtk_gesture_get_bounding_box_center(gesture, &x, &y);
+    FloatPoint viewPoint = FloatPoint(x, y);
+
+    priv->pageProxy->scalePage(pageScale, WebCore::roundedIntPoint(FloatPoint(scaledZoomCenter - viewPoint)));
+}
+
+static void webkitWebViewBaseTouchLongPress(WebKitWebViewBase* webViewBase, gdouble x, gdouble y, GtkGesture*)
+{
+    webViewBase->priv->isLongPressed = true;
+}
+
+static void webkitWebViewBaseTouchPress(WebKitWebViewBase* webViewBase, int nPress, double x, double y, GtkGesture*)
+{
+    webViewBase->priv->isLongPressed = false;
+}
+
+static void webkitWebViewBaseTouchRelease(WebKitWebViewBase* webViewBase, int nPress, double x, double y, GtkGesture* gesture)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (priv->pageGrabbedTouch)
+        return;
+    if (priv->isBeingDragged)
+        return;
+
+    unsigned button;
+    unsigned buttons;
+    if (priv->isLongPressed) {
+        button = GDK_BUTTON_SECONDARY;
+        buttons = GDK_BUTTON3_MASK;
+    } else {
+        button = GDK_BUTTON_PRIMARY;
+        buttons = GDK_BUTTON1_MASK;
+    }
+
+    unsigned modifiers = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture));
+    webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Motion, 0, 0, x, y, modifiers, nPress, touchPointerEventType());
+    webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Press, button, 0, x, y, modifiers, nPress, touchPointerEventType());
+    webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Release, button, buttons, x, y, modifiers, nPress, touchPointerEventType());
+}
+
+static void webkitWebViewBaseTouchDragBegin(WebKitWebViewBase* webViewBase, gdouble startX, gdouble startY, GtkGesture*)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    priv->dragOffset.set(0, 0);
+    priv->isBeingDragged = false;
+}
+
+static void webkitWebViewBaseTouchDragUpdate(WebKitWebViewBase* webViewBase, double offsetX, double offsetY, GtkGesture* gesture)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (priv->pageGrabbedTouch)
+        return;
+
+    double x, y;
+    gtk_gesture_drag_get_start_point(GTK_GESTURE_DRAG(gesture), &x, &y);
+
+    unsigned modifiers = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture));
+    if (!priv->isBeingDragged) {
+        if (!gtk_drag_check_threshold(GTK_WIDGET(webViewBase), 0, 0, static_cast<int>(offsetX), static_cast<int>(offsetY)))
+            return;
+        priv->isBeingDragged = true;
+        gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);
+
+        if (priv->isLongPressed) {
+            // Drag after long press forwards emulated mouse events (for e.g. text selection)
+            webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Motion, 0, 0, x, y, modifiers, 1, touchPointerEventType());
+            webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Press, GDK_BUTTON_PRIMARY, 0, x, y, modifiers, 0, touchPointerEventType());
+        } else
+            webkitWebViewBaseSynthesizeWheelEvent(webViewBase, 0, 0, x, y, WheelEventPhase::Began, WheelEventPhase::NoPhase);
+    }
+
+    if (priv->isLongPressed)
+        webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Motion, GDK_BUTTON_PRIMARY, GDK_BUTTON1_MASK, x + offsetX, y + offsetY, modifiers, 0, touchPointerEventType());
+    else {
+        double deltaX = (priv->dragOffset.x() - offsetX) / Scrollbar::pixelsPerLineStep();
+        double deltaY = (priv->dragOffset.y() - offsetY) / Scrollbar::pixelsPerLineStep();
+        priv->dragOffset.set(offsetX, offsetY);
+
+        ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
+        if (controller && controller->isSwipeGestureEnabled()) {
+            int32_t eventTime = static_cast<int32_t>(gtk_event_controller_get_current_event_time(GTK_EVENT_CONTROLLER(gesture)));
+            PlatformGtkScrollData scrollData = { .delta = deltaX, .eventTime = eventTime, .isTouch = true, .isEnd = false };
+            if (controller->handleScrollWheelEvent(&scrollData))
+                return;
+        }
+
+        webkitWebViewBaseSynthesizeWheelEvent(webViewBase, -deltaX, -deltaY, x, y, WheelEventPhase::Changed, WheelEventPhase::NoPhase);
+    }
+}
+
+static void webkitWebViewBaseTouchDragEnd(WebKitWebViewBase* webViewBase, gdouble offsetX, gdouble offsetY, GtkGesture* gesture)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (priv->pageGrabbedTouch)
+        return;
+
+    if (priv->isLongPressed) {
+        double x, y;
+        gtk_gesture_drag_get_start_point(GTK_GESTURE_DRAG(gesture), &x, &y);
+        unsigned modifiers = gtk_event_controller_get_current_event_state(GTK_EVENT_CONTROLLER(gesture));
+        webkitWebViewBaseSynthesizeMouseEvent(webViewBase, MouseEventType::Release, GDK_BUTTON_PRIMARY, GDK_BUTTON1_MASK, x + offsetX, y + offsetY, modifiers, 0, touchPointerEventType());
+    } else {
+        ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
+        if (controller && controller->isSwipeGestureEnabled()) {
+            int32_t eventTime = static_cast<int32_t>(gtk_event_controller_get_current_event_time(GTK_EVENT_CONTROLLER(gesture)));
+            PlatformGtkScrollData scrollData = { .delta = 0, .eventTime = eventTime, .isTouch = false, .isEnd = true };
+            controller->handleScrollWheelEvent(&scrollData);
+        }
+    }
+}
+
+static void webkitWebViewBaseTouchDragCancel(WebKitWebViewBase* webViewBase, GdkEventSequence*, GtkGesture*)
+{
+    if (auto* controller = webkitWebViewBaseViewGestureController(webViewBase))
+        controller->cancelSwipe();
+}
+
+static void webkitWebViewBaseTouchSwipe(WebKitWebViewBase* webViewBase, gdouble velocityX, gdouble velocityY, GtkGesture* gesture)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    if (priv->pageGrabbedTouch || !priv->isBeingDragged || priv->isLongPressed)
+        return;
+
+    double x, y;
+    if (gtk_gesture_get_point(gesture, gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture)), &x, &y))
+        webkitWebViewBaseSynthesizeWheelEvent(webViewBase, -velocityX, -velocityY, x, y, WheelEventPhase::NoPhase, WheelEventPhase::Began);
+}
+
 static void webkitWebViewBaseConstructed(GObject* object)
 {
     G_OBJECT_CLASS(webkit_web_view_base_parent_class)->constructed(object);
@@ -1961,12 +2034,77 @@
     g_signal_connect_object(controller, "key-released", G_CALLBACK(webkitWebViewBaseKeyReleased), viewWidget, G_CONNECT_SWAPPED);
     gtk_widget_add_controller(viewWidget, controller);
 
+    controller = gtk_event_controller_legacy_new();
+    gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER(controller), GTK_PHASE_TARGET);
+    g_signal_connect_object(controller, "event", G_CALLBACK(webkitWebViewBaseTouchEvent), viewWidget, G_CONNECT_SWAPPED);
+    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(controller));
+
     auto* gesture = gtk_gesture_click_new();
     gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(gesture), 0);
+    gtk_gesture_single_set_exclusive(GTK_GESTURE_SINGLE(gesture), TRUE);
     g_signal_connect_object(gesture, "pressed", G_CALLBACK(webkitWebViewBaseButtonPressed), viewWidget, G_CONNECT_SWAPPED);
     g_signal_connect_object(gesture, "released", G_CALLBACK(webkitWebViewBaseButtonReleased), viewWidget, G_CONNECT_SWAPPED);
     gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
 #endif
+
+    // Touch gestures
+#if USE(GTK4)
+    priv->touchGestureGroup = gtk_gesture_zoom_new();
+    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(priv->touchGestureGroup));
+#else
+    priv->touchGestureGroup = gtk_gesture_zoom_new(viewWidget);
+    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-zoom-gesture", priv->touchGestureGroup, g_object_unref);
+#endif
+    g_signal_connect_object(priv->touchGestureGroup, "begin", G_CALLBACK(webkitWebViewBaseZoomBegin), viewWidget, G_CONNECT_SWAPPED);
+    g_signal_connect_object(priv->touchGestureGroup, "scale-changed", G_CALLBACK(webkitWebViewBaseZoomChanged), viewWidget, G_CONNECT_SWAPPED);
+
+#if USE(GTK4)
+    gesture = gtk_gesture_long_press_new();
+    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
+#else
+    auto* 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);
+    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(gesture), TRUE);
+    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
+    gesture = gtk_gesture_drag_new(viewWidget);
+    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-drag-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, "drag-begin", G_CALLBACK(webkitWebViewBaseTouchDragBegin), viewWidget, G_CONNECT_SWAPPED);
+    g_signal_connect_object(gesture, "drag-update", G_CALLBACK(webkitWebViewBaseTouchDragUpdate), viewWidget, G_CONNECT_SWAPPED);
+    g_signal_connect_object(gesture, "drag-end", G_CALLBACK(webkitWebViewBaseTouchDragEnd), viewWidget, G_CONNECT_SWAPPED);
+    g_signal_connect_object(gesture, "cancel", G_CALLBACK(webkitWebViewBaseTouchDragCancel), viewWidget, G_CONNECT_SWAPPED);
+
+#if USE(GTK4)
+    gesture = gtk_gesture_swipe_new();
+    gtk_widget_add_controller(viewWidget, GTK_EVENT_CONTROLLER(gesture));
+#else
+    gesture = gtk_gesture_swipe_new(viewWidget);
+    g_object_set_data_full(G_OBJECT(viewWidget), "wk-view-swipe-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, "swipe", G_CALLBACK(webkitWebViewBaseTouchSwipe), viewWidget, G_CONNECT_SWAPPED);
 }
 
 static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebViewBaseClass)
@@ -2009,7 +2147,6 @@
 #endif
     widgetClass->query_tooltip = webkitWebViewBaseQueryTooltip;
 #if !USE(GTK4)
-    widgetClass->event = webkitWebViewBaseEvent;
     widgetClass->get_accessible = webkitWebViewBaseGetAccessible;
 #endif
 #if USE(GTK4)
@@ -2298,18 +2435,14 @@
 
 void webkitWebViewBaseWillSwapWebProcess(WebKitWebViewBase* webkitWebViewBase)
 {
-#if !USE(GTK4)
     WebKitWebViewBasePrivate* priv = webkitWebViewBase->priv;
     if (priv->viewGestureController)
         priv->viewGestureController->disconnectFromProcess();
-#endif
 }
 
 void webkitWebViewBaseDidExitWebProcess(WebKitWebViewBase* webkitWebViewBase)
 {
-#if !USE(GTK4)
     webkitWebViewBase->priv->viewGestureController = nullptr;
-#endif
 }
 
 void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase* webkitWebViewBase)
@@ -2322,7 +2455,6 @@
         auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(priv->pageProxy->drawingArea());
         priv->acceleratedBackingStore->update(drawingArea->layerTreeContext());
     }
-#if !USE(GTK4)
     if (priv->viewGestureController)
         priv->viewGestureController->connectToProcess();
     else {
@@ -2329,7 +2461,6 @@
         priv->viewGestureController = makeUnique<WebKit::ViewGestureController>(*priv->pageProxy);
         priv->viewGestureController->setSwipeGestureEnabled(priv->isBackForwardNavigationGestureEnabled);
     }
-#endif
 }
 
 void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase)
@@ -2364,56 +2495,44 @@
 
 void webkitWebViewBaseDidStartProvisionalLoadForMainFrame(WebKitWebViewBase* webkitWebViewBase)
 {
-#if !USE(GTK4)
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
     if (controller && controller->isSwipeGestureEnabled())
         controller->didStartProvisionalLoadForMainFrame();
-#endif
 }
 
 void webkitWebViewBaseDidFirstVisuallyNonEmptyLayoutForMainFrame(WebKitWebViewBase* webkitWebViewBase)
 {
-#if !USE(GTK4)
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
     if (controller && controller->isSwipeGestureEnabled())
         controller->didFirstVisuallyNonEmptyLayoutForMainFrame();
-#endif
 }
 
 void webkitWebViewBaseDidFinishNavigation(WebKitWebViewBase* webkitWebViewBase, API::Navigation* navigation)
 {
-#if !USE(GTK4)
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
     if (controller && controller->isSwipeGestureEnabled())
         controller->didFinishNavigation(navigation);
-#endif
 }
 
 void webkitWebViewBaseDidFailNavigation(WebKitWebViewBase* webkitWebViewBase, API::Navigation* navigation)
 {
-#if !USE(GTK4)
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
     if (controller && controller->isSwipeGestureEnabled())
         controller->didFailNavigation(navigation);
-#endif
 }
 
 void webkitWebViewBaseDidSameDocumentNavigationForMainFrame(WebKitWebViewBase* webkitWebViewBase, SameDocumentNavigationType type)
 {
-#if !USE(GTK4)
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
     if (controller && controller->isSwipeGestureEnabled())
         controller->didSameDocumentNavigationForMainFrame(type);
-#endif
 }
 
 void webkitWebViewBaseDidRestoreScrollPosition(WebKitWebViewBase* webkitWebViewBase)
 {
-#if !USE(GTK4)
     ViewGestureController* controller = webkitWebViewBaseViewGestureController(webkitWebViewBase);
     if (controller && controller->isSwipeGestureEnabled())
         webkitWebViewBase->priv->viewGestureController->didRestoreScrollPosition();
-#endif
 }
 
 #if GTK_CHECK_VERSION(3, 24, 0)
@@ -2792,3 +2911,10 @@
     priv->isBlank = makeBlank;
     gtk_widget_queue_draw(GTK_WIDGET(webViewBase));
 }
+
+void webkitWebViewBasePageGrabbedTouch(WebKitWebViewBase* webViewBase)
+{
+    WebKitWebViewBasePrivate* priv = webViewBase->priv;
+    priv->pageGrabbedTouch = true;
+    gtk_gesture_set_state(priv->touchGestureGroup, GTK_EVENT_SEQUENCE_DENIED);
+}

Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h (277171 => 277172)


--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h	2021-05-07 14:55:50 UTC (rev 277172)
@@ -28,7 +28,6 @@
 #pragma once
 
 #include "APIPageConfiguration.h"
-#include "GestureController.h"
 #include "InputMethodState.h"
 #include "SameDocumentNavigationType.h"
 #include "ShareableBitmap.h"
@@ -88,15 +87,9 @@
 void webkitWebViewBaseDidPerformDragControllerAction(WebKitWebViewBase*);
 #endif
 
-#if !USE(GTK4)
-WebKit::GestureController& webkitWebViewBaseGestureController(WebKitWebViewBase*);
-#endif
-
 RefPtr<WebKit::ViewSnapshot> webkitWebViewBaseTakeViewSnapshot(WebKitWebViewBase*, Optional<WebCore::IntRect>&&);
 void webkitWebViewBaseSetEnableBackForwardNavigationGesture(WebKitWebViewBase*, bool enabled);
-#if !USE(GTK4)
 WebKit::ViewGestureController* webkitWebViewBaseViewGestureController(WebKitWebViewBase*);
-#endif
 
 bool webkitWebViewBaseBeginBackSwipeForTesting(WebKitWebViewBase*);
 bool webkitWebViewBaseCompleteBackSwipeForTesting(WebKitWebViewBase*);
@@ -122,3 +115,4 @@
 void webkitWebViewBaseSynthesizeCompositionKeyPress(WebKitWebViewBase*, const String& text, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<WebKit::EditingRange>&&);
 
 void webkitWebViewBaseMakeBlank(WebKitWebViewBase*, bool);
+void webkitWebViewBasePageGrabbedTouch(WebKitWebViewBase* webkitWebViewBase);

Modified: trunk/Source/WebKit/UIProcess/ViewGestureController.h (277171 => 277172)


--- trunk/Source/WebKit/UIProcess/ViewGestureController.h	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/UIProcess/ViewGestureController.h	2021-05-07 14:55:50 UTC (rev 277172)
@@ -74,8 +74,13 @@
 #if PLATFORM(MAC)
 typedef NSEvent* PlatformScrollEvent;
 #elif PLATFORM(GTK)
-typedef struct _GdkEventScroll GdkEventScroll;
-typedef GdkEventScroll* PlatformScrollEvent;
+typedef struct {
+    double delta;
+    int32_t eventTime;
+    bool isTouch;
+    bool isEnd;
+} PlatformGtkScrollData;
+typedef PlatformGtkScrollData* PlatformScrollEvent;
 #endif
 
 namespace WebKit {
@@ -173,8 +178,12 @@
 
 #if PLATFORM(GTK)
     void cancelSwipe();
+#if USE(GTK4)
+    void snapshot(GtkSnapshot*, GskRenderNode*);
+#else
     void draw(cairo_t*, cairo_pattern_t*);
 #endif
+#endif
 
     // Testing
     bool beginSimulatedSwipeInDirectionForTesting(SwipeDirection);

Deleted: trunk/Source/WebKit/UIProcess/gtk/GestureController.cpp (277171 => 277172)


--- trunk/Source/WebKit/UIProcess/gtk/GestureController.cpp	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/UIProcess/gtk/GestureController.cpp	2021-05-07 14:55:50 UTC (rev 277172)
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2014 Igalia S.L.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "GestureController.h"
-
-#if !USE(GTK4)
-
-#include <WebCore/Scrollbar.h>
-#include <gtk/gtk.h>
-
-namespace WebKit {
-using namespace WebCore;
-
-static const double maximumZoom = 3.0;
-
-GestureController::GestureController(GtkWidget* widget, std::unique_ptr<GestureControllerClient>&& client)
-    : m_client(WTFMove(client))
-    , m_dragGesture(widget, *m_client)
-    , m_swipeGesture(widget, *m_client)
-    , m_zoomGesture(widget, *m_client)
-    , m_longpressGesture(widget, *m_client)
-{
-}
-
-bool GestureController::handleEvent(GdkEvent* event)
-{
-    bool wasProcessingGestures = isProcessingGestures();
-    bool touchEnd;
-    m_dragGesture.handleEvent(event);
-    m_swipeGesture.handleEvent(event);
-    m_zoomGesture.handleEvent(event);
-    m_longpressGesture.handleEvent(event);
-    touchEnd = (gdk_event_get_event_type(event) == GDK_TOUCH_END) || (gdk_event_get_event_type(event) == GDK_TOUCH_CANCEL);
-    return touchEnd ? wasProcessingGestures : isProcessingGestures();
-}
-
-bool GestureController::isProcessingGestures() const
-{
-    return m_dragGesture.isActive() || m_swipeGesture.isActive() || m_zoomGesture.isActive() || m_longpressGesture.isActive();
-}
-
-GestureController::Gesture::Gesture(GtkGesture* gesture, GestureControllerClient& client)
-    : m_gesture(adoptGRef(gesture))
-    , m_client(client)
-{
-    gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER(m_gesture.get()), GTK_PHASE_NONE);
-}
-
-void GestureController::Gesture::reset()
-{
-    gtk_event_controller_reset(GTK_EVENT_CONTROLLER(m_gesture.get()));
-}
-
-bool GestureController::Gesture::isActive() const
-{
-    return gtk_gesture_is_active(m_gesture.get());
-}
-
-void GestureController::Gesture::handleEvent(GdkEvent* event)
-{
-    gtk_event_controller_handle_event(GTK_EVENT_CONTROLLER(m_gesture.get()), event);
-}
-
-void GestureController::DragGesture::startDrag(GdkEvent* event)
-{
-    ASSERT(!m_inDrag);
-    m_client.startDrag(reinterpret_cast<GdkEventTouch*>(event), m_start);
-}
-
-void GestureController::DragGesture::handleDrag(GdkEvent* event, double x, double y)
-{
-    ASSERT(m_inDrag);
-    m_client.drag(reinterpret_cast<GdkEventTouch*>(event), m_start,
-        FloatPoint::narrowPrecision((m_offset.x() - x) / Scrollbar::pixelsPerLineStep(), (m_offset.y() - y) / Scrollbar::pixelsPerLineStep()));
-}
-
-void GestureController::DragGesture::cancelDrag()
-{
-    ASSERT(m_inDrag);
-    m_client.cancelDrag();
-}
-
-void GestureController::DragGesture::handleTap(GdkEvent* event)
-{
-    ASSERT(!m_inDrag);
-    m_client.tap(reinterpret_cast<GdkEventTouch*>(event));
-}
-
-void GestureController::DragGesture::begin(DragGesture* dragGesture, double x, double y, GtkGesture* gesture)
-{
-    GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
-    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
-    dragGesture->m_inDrag = false;
-    dragGesture->m_start.set(x, y);
-    dragGesture->m_offset.set(0, 0);
-
-    GtkWidget* widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture));
-    unsigned delay;
-    g_object_get(gtk_widget_get_settings(widget), "gtk-long-press-time", &delay, nullptr);
-    dragGesture->m_longPressTimeout.startOneShot(1_ms * delay);
-    dragGesture->startDrag(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)));
-}
-
-void GestureController::DragGesture::update(DragGesture* dragGesture, double x, double y, GtkGesture* gesture)
-{
-    GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
-    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
-
-    GtkWidget* widget = gtk_event_controller_get_widget(GTK_EVENT_CONTROLLER(gesture));
-    if (!dragGesture->m_inDrag && gtk_drag_check_threshold(widget, dragGesture->m_start.x(), dragGesture->m_start.y(), dragGesture->m_start.x() + x, dragGesture->m_start.y() + y)) {
-        dragGesture->m_inDrag = true;
-        dragGesture->m_longPressTimeout.stop();
-    }
-
-    if (dragGesture->m_inDrag)
-        dragGesture->handleDrag(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)), x, y);
-    dragGesture->m_offset.set(x, y);
-}
-
-void GestureController::DragGesture::end(DragGesture* dragGesture, GdkEventSequence* sequence, GtkGesture* gesture)
-{
-    dragGesture->m_longPressTimeout.stop();
-    if (!gtk_gesture_handles_sequence(gesture, sequence)) {
-        gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_DENIED);
-        return;
-    }
-    if (!dragGesture->m_inDrag) {
-        dragGesture->handleTap(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)));
-        gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_DENIED);
-    }
-}
-
-void GestureController::DragGesture::cancel(DragGesture* dragGesture, GdkEventSequence* sequence, GtkGesture* gesture)
-{
-    dragGesture->m_longPressTimeout.stop();
-    dragGesture->cancelDrag();
-}
-
-void GestureController::DragGesture::longPressFired()
-{
-    m_inDrag = true;
-}
-
-GestureController::DragGesture::DragGesture(GtkWidget* widget, GestureControllerClient& client)
-    : Gesture(gtk_gesture_drag_new(widget), client)
-    , m_longPressTimeout(RunLoop::main(), this, &GestureController::DragGesture::longPressFired)
-{
-    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(m_gesture.get()), TRUE);
-    g_signal_connect_swapped(m_gesture.get(), "drag-begin", G_CALLBACK(begin), this);
-    g_signal_connect_swapped(m_gesture.get(), "drag-update", G_CALLBACK(update), this);
-    g_signal_connect_swapped(m_gesture.get(), "end", G_CALLBACK(end), this);
-    g_signal_connect_swapped(m_gesture.get(), "cancel", G_CALLBACK(cancel), this);
-}
-
-void GestureController::SwipeGesture::startMomentumScroll(GdkEvent* event, double velocityX, double velocityY)
-{
-    m_client.swipe(reinterpret_cast<GdkEventTouch*>(event), FloatPoint::narrowPrecision(velocityX, velocityY));
-}
-
-void GestureController::SwipeGesture::swipe(SwipeGesture* swipeGesture, double velocityX, double velocityY, GtkGesture* gesture)
-{
-    GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
-    if (!gtk_gesture_handles_sequence(gesture, sequence))
-        return;
-
-    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
-
-    swipeGesture->startMomentumScroll(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)), velocityX, velocityY);
-}
-
-GestureController::SwipeGesture::SwipeGesture(GtkWidget* widget, GestureControllerClient& client)
-    : Gesture(gtk_gesture_swipe_new(widget), client)
-{
-    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(m_gesture.get()), TRUE);
-    g_signal_connect_swapped(m_gesture.get(), "swipe", G_CALLBACK(swipe), this);
-}
-
-void GestureController::ZoomGesture::begin(ZoomGesture* zoomGesture, GdkEventSequence*, GtkGesture* gesture)
-{
-    gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);
-    zoomGesture->startZoom();
-}
-
-IntPoint GestureController::ZoomGesture::center() const
-{
-    double x, y;
-    gtk_gesture_get_bounding_box_center(m_gesture.get(), &x, &y);
-    return IntPoint(x, y);
-}
-
-void GestureController::ZoomGesture::startZoom()
-{
-    m_client.startZoom(center(), m_initialScale, m_initialPoint);
-}
-
-void GestureController::ZoomGesture::handleZoom()
-{
-    FloatPoint scaledZoomCenter(m_initialPoint);
-    scaledZoomCenter.scale(m_scale);
-
-    m_client.zoom(m_scale, WebCore::roundedIntPoint(FloatPoint(scaledZoomCenter - m_viewPoint)));
-}
-
-void GestureController::ZoomGesture::scaleChanged(ZoomGesture* zoomGesture, double scale, GtkGesture*)
-{
-    zoomGesture->m_scale = zoomGesture->m_initialScale * scale;
-    if (zoomGesture->m_scale < 1.0)
-        zoomGesture->m_scale = 1.0;
-    if (zoomGesture->m_scale > maximumZoom)
-        zoomGesture->m_scale = maximumZoom;
-
-    zoomGesture->m_viewPoint = zoomGesture->center();
-
-    if (zoomGesture->m_idle.isActive())
-        return;
-
-    zoomGesture->m_idle.startOneShot(0_s);
-}
-
-GestureController::ZoomGesture::ZoomGesture(GtkWidget* widget, GestureControllerClient& client)
-    : Gesture(gtk_gesture_zoom_new(widget), client)
-    , m_idle(RunLoop::main(), this, &GestureController::ZoomGesture::handleZoom)
-{
-    g_signal_connect_swapped(m_gesture.get(), "begin", G_CALLBACK(begin), this);
-    g_signal_connect_swapped(m_gesture.get(), "scale-changed", G_CALLBACK(scaleChanged), this);
-}
-
-void GestureController::LongPressGesture::longPressed(GdkEvent* event)
-{
-    m_client.longPress(reinterpret_cast<GdkEventTouch*>(event));
-}
-
-void GestureController::LongPressGesture::pressed(LongPressGesture* longpressGesture, double x, double y, GtkGesture* gesture)
-{
-    GdkEventSequence* sequence = gtk_gesture_single_get_current_sequence(GTK_GESTURE_SINGLE(gesture));
-    if (!gtk_gesture_handles_sequence(gesture, sequence))
-        return;
-
-    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
-
-    longpressGesture->longPressed(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)));
-}
-
-GestureController::LongPressGesture::LongPressGesture(GtkWidget* widget, GestureControllerClient& client)
-    : Gesture(gtk_gesture_long_press_new(widget), client)
-{
-    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(m_gesture.get()), TRUE);
-    g_signal_connect_swapped(m_gesture.get(), "pressed", G_CALLBACK(pressed), this);
-}
-
-} // namespace WebKit
-
-#endif

Deleted: trunk/Source/WebKit/UIProcess/gtk/GestureController.h (277171 => 277172)


--- trunk/Source/WebKit/UIProcess/gtk/GestureController.h	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/UIProcess/gtk/GestureController.h	2021-05-07 14:55:50 UTC (rev 277172)
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2014 Igalia S.L.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#if !USE(GTK4)
-
-#include <WebCore/FloatPoint.h>
-#include <wtf/Noncopyable.h>
-#include <wtf/RunLoop.h>
-#include <wtf/glib/GRefPtr.h>
-
-typedef union _GdkEvent GdkEvent;
-typedef struct _GdkEventTouch GdkEventTouch;
-typedef struct _GdkEventSequence GdkEventSequence;
-typedef struct _GtkGesture GtkGesture;
-
-
-namespace WebKit {
-
-class GestureControllerClient {
-public:
-    virtual ~GestureControllerClient() = default;
-
-    virtual void tap(GdkEventTouch*) = 0;
-
-    virtual void startDrag(GdkEventTouch*, const WebCore::FloatPoint&) = 0;
-    virtual void drag(GdkEventTouch*, const WebCore::FloatPoint&, const WebCore::FloatPoint&) = 0;
-    virtual void cancelDrag() = 0;
-
-    virtual void swipe(GdkEventTouch*, const WebCore::FloatPoint&) = 0;
-
-    virtual void startZoom(const WebCore::IntPoint& center, double& initialScale, WebCore::IntPoint& initialPoint) = 0;
-    virtual void zoom(double scale, const WebCore::IntPoint& origin) = 0;
-
-    virtual void longPress(GdkEventTouch*) = 0;
-};
-
-class GestureController {
-    WTF_MAKE_NONCOPYABLE(GestureController);
-    WTF_MAKE_FAST_ALLOCATED;
-
-public:
-    GestureController(GtkWidget*, std::unique_ptr<GestureControllerClient>&&);
-
-    bool isProcessingGestures() const;
-    bool handleEvent(GdkEvent*);
-
-    void reset()
-    {
-        m_dragGesture.reset();
-        m_swipeGesture.reset();
-        m_zoomGesture.reset();
-        m_longpressGesture.reset();
-    }
-
-private:
-    class Gesture {
-    public:
-        void reset();
-        bool isActive() const;
-        void handleEvent(GdkEvent*);
-
-    protected:
-        Gesture(GtkGesture*, GestureControllerClient&);
-
-        GRefPtr<GtkGesture> m_gesture;
-        GestureControllerClient& m_client;
-    };
-
-    class DragGesture final : public Gesture {
-    public:
-        DragGesture(GtkWidget*, GestureControllerClient&);
-
-    private:
-        // Notify that a drag started, allowing to stop kinetic deceleration.
-        void startDrag(GdkEvent*);
-        void handleDrag(GdkEvent*, double x, double y);
-        void cancelDrag();
-        void handleTap(GdkEvent*);
-        void longPressFired();
-
-        static void begin(DragGesture*, double x, double y, GtkGesture*);
-        static void update(DragGesture*, double x, double y, GtkGesture*);
-        static void end(DragGesture*, GdkEventSequence*, GtkGesture*);
-        static void cancel(DragGesture*, GdkEventSequence*, GtkGesture*);
-
-        WebCore::FloatPoint m_start;
-        WebCore::FloatPoint m_offset;
-        RunLoop::Timer<DragGesture> m_longPressTimeout;
-        GRefPtr<GtkGesture> m_longPress;
-        bool m_inDrag { false };
-    };
-
-    class SwipeGesture final : public Gesture {
-    public:
-        SwipeGesture(GtkWidget*, GestureControllerClient&);
-
-    private:
-        void startMomentumScroll(GdkEvent*, double velocityX, double velocityY);
-
-        static void swipe(SwipeGesture*, double velocityX, double velocityY, GtkGesture*);
-    };
-
-    class ZoomGesture final : public Gesture {
-    public:
-        ZoomGesture(GtkWidget*, GestureControllerClient&);
-
-    private:
-        WebCore::IntPoint center() const;
-        void startZoom();
-        void handleZoom();
-
-        static void begin(ZoomGesture*, GdkEventSequence*, GtkGesture*);
-        static void scaleChanged(ZoomGesture*, double scale, GtkGesture*);
-
-        double m_initialScale { 0 };
-        double m_scale { 0 };
-        WebCore::IntPoint m_initialPoint;
-        WebCore::IntPoint m_viewPoint;
-        RunLoop::Timer<ZoomGesture> m_idle;
-    };
-
-    class LongPressGesture final : public Gesture {
-    public:
-        LongPressGesture(GtkWidget*, GestureControllerClient&);
-
-    private:
-        void longPressed(GdkEvent*);
-
-        static void pressed(LongPressGesture*, double x, double y, GtkGesture*);
-    };
-
-    std::unique_ptr<GestureControllerClient> m_client;
-    DragGesture m_dragGesture;
-    SwipeGesture m_swipeGesture;
-    ZoomGesture m_zoomGesture;
-    LongPressGesture m_longpressGesture;
-};
-
-} // namespace WebKit
-
-#endif

Modified: trunk/Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp (277171 => 277172)


--- trunk/Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp	2021-05-07 12:31:26 UTC (rev 277171)
+++ trunk/Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp	2021-05-07 14:55:50 UTC (rev 277172)
@@ -48,9 +48,9 @@
 static const double swipeCancelArea = 0.5;
 static const double swipeCancelVelocityThreshold = 0.4;
 
-static bool isEventStop(GdkEventScroll* event)
+static bool isEventStop(PlatformGtkScrollData* event)
 {
-    return gdk_event_is_scroll_stop_event(reinterpret_cast<GdkEvent*>(event));
+    return event->isEnd;
 }
 
 void ViewGestureController::platformTeardown()
@@ -58,45 +58,34 @@
     cancelSwipe();
 }
 
-bool ViewGestureController::PendingSwipeTracker::scrollEventCanStartSwipe(GdkEventScroll*)
+bool ViewGestureController::PendingSwipeTracker::scrollEventCanStartSwipe(PlatformGtkScrollData*)
 {
     return true;
 }
 
-bool ViewGestureController::PendingSwipeTracker::scrollEventCanEndSwipe(GdkEventScroll* event)
+bool ViewGestureController::PendingSwipeTracker::scrollEventCanEndSwipe(PlatformGtkScrollData* event)
 {
     return isEventStop(event);
 }
 
-bool ViewGestureController::PendingSwipeTracker::scrollEventCanInfluenceSwipe(GdkEventScroll* event)
+bool ViewGestureController::PendingSwipeTracker::scrollEventCanInfluenceSwipe(PlatformGtkScrollData* event)
 {
-    GdkDevice* device = gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event));
-    GdkInputSource source = gdk_device_get_source(device);
-
-    bool isDeviceAllowed = source == GDK_SOURCE_TOUCHPAD || source == GDK_SOURCE_TOUCHSCREEN || m_viewGestureController.m_isSimulatedSwipe;
-
-    return gdk_event_get_scroll_deltas(reinterpret_cast<GdkEvent*>(event), nullptr, nullptr) && isDeviceAllowed;
+    return true;
 }
 
-static bool isTouchEvent(GdkEventScroll* event)
+static bool isTouchEvent(PlatformGtkScrollData* event)
 {
-    GdkDevice* device = gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event));
-    GdkInputSource source = gdk_device_get_source(device);
-
-    return source == GDK_SOURCE_TOUCHSCREEN;
+    return event->isTouch;
 }
 
-FloatSize ViewGestureController::PendingSwipeTracker::scrollEventGetScrollingDeltas(GdkEventScroll* event)
+FloatSize ViewGestureController::PendingSwipeTracker::scrollEventGetScrollingDeltas(PlatformGtkScrollData* event)
 {
     double multiplier = isTouchEvent(event) ? Scrollbar::pixelsPerLineStep() : gtkScrollDeltaMultiplier;
-    double xDelta, yDelta;
-    gdk_event_get_scroll_deltas(reinterpret_cast<GdkEvent*>(event), &xDelta, &yDelta);
-
-    // GdkEventScroll deltas are inverted compared to NSEvent, so invert them again
-    return -FloatSize(xDelta, yDelta) * multiplier;
+    // GTK deltas are inverted compared to NSEvent, so invert them again
+    return -FloatSize(event->delta, 0) * multiplier;
 }
 
-bool ViewGestureController::handleScrollWheelEvent(GdkEventScroll* event)
+bool ViewGestureController::handleScrollWheelEvent(PlatformGtkScrollData* event)
 {
     return m_swipeProgressTracker.handleEvent(event) || m_pendingSwipeTracker.handleEvent(event);
 }
@@ -146,7 +135,7 @@
     m_cancelled = false;
 }
 
-bool ViewGestureController::SwipeProgressTracker::handleEvent(GdkEventScroll* event)
+bool ViewGestureController::SwipeProgressTracker::handleEvent(PlatformGtkScrollData* event)
 {
     // Don't allow scrolling while the next page is loading
     if (m_state == State::Finishing)
@@ -175,9 +164,8 @@
         return false;
     }
 
-    uint32_t eventTime = gdk_event_get_time(reinterpret_cast<GdkEvent*>(event));
-    double eventDeltaX;
-    gdk_event_get_scroll_deltas(reinterpret_cast<GdkEvent*>(event), &eventDeltaX, nullptr);
+    uint32_t eventTime = event->eventTime;
+    double eventDeltaX = event->delta;
 
     double deltaX = -eventDeltaX;
     if (isTouchEvent(event)) {
@@ -281,6 +269,7 @@
     m_viewGestureController.endSwipeGesture(m_targetItem.get(), m_cancelled);
 }
 
+#if !USE(GTK4)
 GRefPtr<GtkStyleContext> ViewGestureController::createStyleContext(const char* name)
 {
     bool isRTL = m_webPageProxy.userInterfaceLayoutDirection() == WebCore::UserInterfaceLayoutDirection::RTL;
@@ -320,6 +309,7 @@
 
     return width;
 }
+#endif
 
 void ViewGestureController::beginSwipeGesture(WebBackForwardListItem* targetItem, SwipeDirection direction)
 {
@@ -346,6 +336,7 @@
         }
     }
 
+#if !USE(GTK4)
     if (!m_currentSwipeSnapshotPattern) {
         GdkRGBA color;
         auto* context = gtk_widget_get_style_context(m_webPageProxy.viewWidget());
@@ -382,6 +373,7 @@
     m_swipeOutlineSize = elementWidth(context.get());
     if (m_swipeOutlineSize)
         m_swipeOutlinePattern = createElementPattern(context.get(), m_swipeOutlineSize, size.height(), scale);
+#endif
 }
 
 void ViewGestureController::handleSwipeGesture(WebBackForwardListItem*, double, SwipeDirection)
@@ -399,6 +391,49 @@
     }
 }
 
+#if USE(GTK4)
+void ViewGestureController::snapshot(GtkSnapshot* snapshot, GskRenderNode* pageRenderNode)
+{
+    bool swipingLeft = isPhysicallySwipingLeft(m_swipeProgressTracker.direction());
+    bool swipingBack = m_swipeProgressTracker.direction() == SwipeDirection::Back;
+    bool isRTL = m_webPageProxy.userInterfaceLayoutDirection() == WebCore::UserInterfaceLayoutDirection::RTL;
+    float progress = m_swipeProgressTracker.progress();
+
+    auto size = m_webPageProxy.drawingArea()->size();
+    int width = size.width();
+    int height = size.height();
+    double scale = m_webPageProxy.deviceScaleFactor();
+
+    double swipingLayerOffset = (swipingLeft ? 0 : width) + floor(width * progress * scale) / scale;
+
+    double dimmingProgress = swipingLeft ? 1 - progress : -progress;
+    if (isRTL) {
+        dimmingProgress = 1 - dimmingProgress;
+        swipingLayerOffset = -(width - swipingLayerOffset);
+    }
+
+    gtk_snapshot_save(snapshot);
+
+    graphene_point_t translation = { static_cast<float>(swipingLayerOffset), 0 };
+    if (!swipingBack) {
+        gtk_snapshot_append_node(snapshot, pageRenderNode);
+        gtk_snapshot_translate(snapshot, &translation);
+    }
+
+    graphene_rect_t rect = { 0, 0, (float)width, (float)height };
+    auto* cr = gtk_snapshot_append_cairo(snapshot, &rect);
+    cairo_set_source(cr, m_currentSwipeSnapshotPattern.get());
+    cairo_rectangle(cr, 0, 0, width, height);
+    cairo_fill(cr);
+
+    if (swipingBack) {
+        gtk_snapshot_translate(snapshot, &translation);
+        gtk_snapshot_append_node(snapshot, pageRenderNode);
+    }
+
+    gtk_snapshot_restore(snapshot);
+}
+#else
 void ViewGestureController::draw(cairo_t* cr, cairo_pattern_t* pageGroup)
 {
     bool swipingLeft = isPhysicallySwipingLeft(m_swipeProgressTracker.direction());
@@ -489,6 +524,7 @@
 
     cairo_restore(cr);
 }
+#endif
 
 void ViewGestureController::removeSwipeSnapshot()
 {
@@ -518,37 +554,6 @@
     m_swipeProgressTracker.reset();
 }
 
-static GUniquePtr<GdkEvent> createScrollEvent(GtkWidget* widget, double xDelta, double yDelta)
-{
-    GdkWindow* window = gtk_widget_get_window(widget);
-
-    int x, y;
-    gdk_window_get_root_origin(window, &x, &y);
-
-    int width = gdk_window_get_width(window);
-    int height = gdk_window_get_height(window);
-
-    GUniquePtr<GdkEvent> event(gdk_event_new(GDK_SCROLL));
-    event->scroll.time = GDK_CURRENT_TIME;
-    event->scroll.x = width / 2;
-    event->scroll.y = height / 2;
-    event->scroll.x_root = x + width / 2;
-    event->scroll.y_root = y + height / 2;
-    event->scroll.direction = GDK_SCROLL_SMOOTH;
-    event->scroll.delta_x = xDelta;
-    event->scroll.delta_y = yDelta;
-    event->scroll.state = 0;
-    event->scroll.is_stop = !xDelta && !yDelta;
-    event->scroll.window = GDK_WINDOW(g_object_ref(window));
-    gdk_event_set_screen(event.get(), gdk_window_get_screen(window));
-
-    GdkDevice* pointer = gdk_seat_get_pointer(gdk_display_get_default_seat(gdk_window_get_display(window)));
-    gdk_event_set_device(event.get(), pointer);
-    gdk_event_set_source_device(event.get(), pointer);
-
-    return event;
-}
-
 bool ViewGestureController::beginSimulatedSwipeInDirectionForTesting(SwipeDirection direction)
 {
     if (!canSwipeInDirection(direction))
@@ -561,8 +566,8 @@
     if (isPhysicallySwipingLeft(direction))
         delta = -delta;
 
-    GUniquePtr<GdkEvent> event = createScrollEvent(m_webPageProxy.viewWidget(), delta, 0);
-    gtk_widget_event(m_webPageProxy.viewWidget(), event.get());
+    PlatformGtkScrollData scrollData = { .delta = delta, .eventTime = GDK_CURRENT_TIME, .isTouch = false, .isEnd = false };
+    handleScrollWheelEvent(&scrollData);
 
     return true;
 }
@@ -569,9 +574,8 @@
 
 bool ViewGestureController::completeSimulatedSwipeInDirectionForTesting(SwipeDirection)
 {
-    GUniquePtr<GdkEvent> event = createScrollEvent(m_webPageProxy.viewWidget(), 0, 0);
-    gtk_widget_event(m_webPageProxy.viewWidget(), event.get());
-
+    PlatformGtkScrollData scrollData = { .delta = 0, .eventTime = GDK_CURRENT_TIME, .isTouch = false, .isEnd = true };
+    handleScrollWheelEvent(&scrollData);
     m_isSimulatedSwipe = false;
 
     return true;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to