[GTK] Support navigation gesture on touchscreens
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 May 2019 20:28:22 +0000 (20:28 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 May 2019 20:28:22 +0000 (20:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197690

Patch by Alexander Mikhaylenko <exalm7659@gmail.com> on 2019-05-08
Reviewed by Michael Catanzaro.

Touch events generate scroll events that are handled in webkitWebViewBaseHandleWheelEvent(),
bypassing webkitWebViewBaseScrollEvent(). Because of that, ViewGestureController never receives
them. Hence pass scroll events to ViewGestureController in webkitWebViewBaseHandleWheelEvent()
instead.

For touch events, gesture progress calculation has to take window width into account to make
the page perfectly follow finger, and deltas are additionally divided by Scrollbar::pixelsPerLineStep(),
so compensate for that.

For touchpad events, change delta multiplier to 10 to match GTK behavior, and introduce a 400px
base width so the swipe speed doesn't change from the previous behavior.

Because of the multiplier change, threshold for triggering the gesture with touchpad is now 4
times larger.

* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseHandleWheelEvent): Move ViewGestureController bits here.
(webkitWebViewBaseScrollEvent): Removed ViewGestureController bits.
* UIProcess/gtk/ViewGestureControllerGtk.cpp:
(WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanInfluenceSwipe):
Allow events from touchscreen devices.
(WebKit::isTouchEvent): Added.
(WebKit::ViewGestureController::PendingSwipeTracker::scrollEventGetScrollingDeltas):
Change delta multipliers.
(WebKit::ViewGestureController::SwipeProgressTracker::handleEvent):
Change delta multipliers, account for view width for touchscreen events.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245065 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp
Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp

index 94d1685..eb847aa 100644 (file)
@@ -1,3 +1,37 @@
+2019-05-08  Alexander Mikhaylenko  <exalm7659@gmail.com>
+
+        [GTK] Support navigation gesture on touchscreens
+        https://bugs.webkit.org/show_bug.cgi?id=197690
+
+        Reviewed by Michael Catanzaro.
+
+        Touch events generate scroll events that are handled in webkitWebViewBaseHandleWheelEvent(),
+        bypassing webkitWebViewBaseScrollEvent(). Because of that, ViewGestureController never receives
+        them. Hence pass scroll events to ViewGestureController in webkitWebViewBaseHandleWheelEvent()
+        instead.
+
+        For touch events, gesture progress calculation has to take window width into account to make
+        the page perfectly follow finger, and deltas are additionally divided by Scrollbar::pixelsPerLineStep(),
+        so compensate for that.
+
+        For touchpad events, change delta multiplier to 10 to match GTK behavior, and introduce a 400px
+        base width so the swipe speed doesn't change from the previous behavior.
+
+        Because of the multiplier change, threshold for triggering the gesture with touchpad is now 4
+        times larger.
+
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseHandleWheelEvent): Move ViewGestureController bits here.
+        (webkitWebViewBaseScrollEvent): Removed ViewGestureController bits.
+        * UIProcess/gtk/ViewGestureControllerGtk.cpp:
+        (WebKit::ViewGestureController::PendingSwipeTracker::scrollEventCanInfluenceSwipe):
+        Allow events from touchscreen devices.
+        (WebKit::isTouchEvent): Added.
+        (WebKit::ViewGestureController::PendingSwipeTracker::scrollEventGetScrollingDeltas):
+        Change delta multipliers.
+        (WebKit::ViewGestureController::SwipeProgressTracker::handleEvent):
+        Change delta multipliers, account for view width for touchscreen events.
+
 2019-05-08  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         [iOS] Add a quirk to synthesize mouse events when modifying the selection
index 1cf6e29..18b6097 100644 (file)
@@ -850,6 +850,10 @@ static gboolean webkitWebViewBaseButtonReleaseEvent(GtkWidget* widget, GdkEventB
 
 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;
+
     WebKitWebViewBasePrivate* priv = webViewBase->priv;
     ASSERT(!priv->dialog);
     if (phase)
@@ -890,10 +894,6 @@ static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll*
         }
     }
 
-    ViewGestureController* controller = webkitWebViewBaseViewGestureController(webViewBase);
-    if (controller && controller->isSwipeGestureEnabled() && controller->handleScrollWheelEvent(event))
-        return GDK_EVENT_STOP;
-
     webkitWebViewBaseHandleWheelEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
 
     return GDK_EVENT_STOP;
index 6584c34..4bae03a 100644 (file)
@@ -36,6 +36,10 @@ static const Seconds swipeMinAnimationDuration = 100_ms;
 static const Seconds swipeMaxAnimationDuration = 400_ms;
 static const double swipeAnimationBaseVelocity = 0.002;
 
+// GTK divides all scroll deltas by 10, compensate for that
+static const double gtkScrollDeltaMultiplier = 10;
+static const double swipeTouchpadBaseWidth = 400;
+
 // This is derivative of the easing function at t=0
 static const double swipeAnimationDurationMultiplier = 3;
 
@@ -82,13 +86,23 @@ bool ViewGestureController::PendingSwipeTracker::scrollEventCanInfluenceSwipe(Gd
 
     // FIXME: Should it maybe be allowed on mice/trackpoints as well? The GDK_SCROLL_SMOOTH
     // requirement already filters out most mice, and it works pretty well on a trackpoint
-    return event->direction == GDK_SCROLL_SMOOTH && source == GDK_SOURCE_TOUCHPAD;
+    return event->direction == GDK_SCROLL_SMOOTH && (source == GDK_SOURCE_TOUCHPAD || source == GDK_SOURCE_TOUCHSCREEN);
+}
+
+static bool isTouchEvent(GdkEventScroll* event)
+{
+    GdkDevice* device = gdk_event_get_source_device(reinterpret_cast<GdkEvent*>(event));
+    GdkInputSource source = gdk_device_get_source(device);
+
+    return source == GDK_SOURCE_TOUCHSCREEN;
 }
 
 FloatSize ViewGestureController::PendingSwipeTracker::scrollEventGetScrollingDeltas(GdkEventScroll* event)
 {
+    double multiplier = isTouchEvent(event) ? Scrollbar::pixelsPerLineStep() : gtkScrollDeltaMultiplier;
+
     // GdkEventScroll deltas are inverted compared to NSEvent, so invert them again
-    return -FloatSize(event->delta_x, event->delta_y) * Scrollbar::pixelsPerLineStep();
+    return -FloatSize(event->delta_x, event->delta_y) * multiplier;
 }
 
 bool ViewGestureController::handleScrollWheelEvent(GdkEventScroll* event)
@@ -169,7 +183,11 @@ bool ViewGestureController::SwipeProgressTracker::handleEvent(GdkEventScroll* ev
         return false;
     }
 
-    double deltaX = -event->delta_x / Scrollbar::pixelsPerLineStep();
+    double deltaX = -event->delta_x;
+    if (isTouchEvent(event))
+        deltaX *= (double) Scrollbar::pixelsPerLineStep() / m_webPageProxy.viewSize().width();
+    else
+        deltaX *= gtkScrollDeltaMultiplier / swipeTouchpadBaseWidth;
 
     Seconds time = Seconds::fromMilliseconds(event->time);
     if (time != m_prevTime)