[GTK] Navigation gesture improvements
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Oct 2019 10:03:38 +0000 (10:03 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Oct 2019 10:03:38 +0000 (10:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202645

Patch by Alexander Mikhaylenko <alexm@gnome.org> on 2019-10-08
Reviewed by Carlos Garcia Campos.

Measure velocity threshold in pixels per second rather than distance (range [0-1])
per second. The value is the same as it was on touchpads, since a fixed distance is
used, but is now consistent on touchscreens, regardless of the webview width.

Add a threshold for cancelling gesture when the page is more than halfway
through, so that it's symmetric with the first half.

Align the moving page to pixel grid on hidpi devices correctly. Just
rounding the position doesn't work correctly, since the cairo context is
pre-scaled. Multiplying by scale factor, rounding and then dividing by
scale factor fixes this.

* UIProcess/ViewGestureController.h:
* UIProcess/gtk/ViewGestureControllerGtk.cpp:
(WebKit::ViewGestureController::SwipeProgressTracker::reset):
(WebKit::ViewGestureController::SwipeProgressTracker::handleEvent):
(WebKit::ViewGestureController::SwipeProgressTracker::shouldCancel):
(WebKit::ViewGestureController::draw):

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

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/ViewGestureController.h
Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp

index 669c599..ea5581e 100644 (file)
@@ -1,3 +1,29 @@
+2019-10-08  Alexander Mikhaylenko  <alexm@gnome.org>
+
+        [GTK] Navigation gesture improvements
+        https://bugs.webkit.org/show_bug.cgi?id=202645
+
+        Reviewed by Carlos Garcia Campos.
+
+        Measure velocity threshold in pixels per second rather than distance (range [0-1])
+        per second. The value is the same as it was on touchpads, since a fixed distance is
+        used, but is now consistent on touchscreens, regardless of the webview width.
+
+        Add a threshold for cancelling gesture when the page is more than halfway
+        through, so that it's symmetric with the first half.
+
+        Align the moving page to pixel grid on hidpi devices correctly. Just
+        rounding the position doesn't work correctly, since the cairo context is
+        pre-scaled. Multiplying by scale factor, rounding and then dividing by
+        scale factor fixes this.
+
+        * UIProcess/ViewGestureController.h:
+        * UIProcess/gtk/ViewGestureControllerGtk.cpp:
+        (WebKit::ViewGestureController::SwipeProgressTracker::reset):
+        (WebKit::ViewGestureController::SwipeProgressTracker::handleEvent):
+        (WebKit::ViewGestureController::SwipeProgressTracker::shouldCancel):
+        (WebKit::ViewGestureController::draw):
+
 2019-10-08  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         Unreviewed. Remove unused WebKitSoupRequestGeneric after r250597
index 1bb012f..0c8493a 100644 (file)
@@ -399,6 +399,7 @@ private:
 
         Seconds m_prevTime;
         double m_velocity { 0 };
+        double m_distance { 0 };
 
         Seconds m_startTime;
         Seconds m_endTime;
index 79b63f8..4a4d1fe 100644 (file)
@@ -45,7 +45,7 @@ static const double swipeTouchpadBaseWidth = 400;
 static const double swipeAnimationDurationMultiplier = 3;
 
 static const double swipeCancelArea = 0.5;
-static const double swipeCancelVelocityThreshold = 0.001;
+static const double swipeCancelVelocityThreshold = 0.4;
 
 static bool isEventStop(GdkEventScroll* event)
 {
@@ -141,6 +141,7 @@ void ViewGestureController::SwipeProgressTracker::reset()
     m_endTime = 0_ms;
     m_prevTime = 0_ms;
     m_velocity = 0;
+    m_distance = 0;
     m_cancelled = false;
 }
 
@@ -178,10 +179,13 @@ bool ViewGestureController::SwipeProgressTracker::handleEvent(GdkEventScroll* ev
     gdk_event_get_scroll_deltas(reinterpret_cast<GdkEvent*>(event), &eventDeltaX, nullptr);
 
     double deltaX = -eventDeltaX;
-    if (isTouchEvent(event))
-        deltaX *= (double) Scrollbar::pixelsPerLineStep() / m_webPageProxy.viewSize().width();
-    else
-        deltaX *= gtkScrollDeltaMultiplier / swipeTouchpadBaseWidth;
+    if (isTouchEvent(event)) {
+        m_distance = m_webPageProxy.viewSize().width();
+        deltaX *= static_cast<double>(Scrollbar::pixelsPerLineStep()) / m_distance;
+    } else {
+        m_distance = swipeTouchpadBaseWidth;
+        deltaX *= gtkScrollDeltaMultiplier / m_distance;
+    }
 
     Seconds time = Seconds::fromMilliseconds(eventTime);
     if (time != m_prevTime)
@@ -203,14 +207,12 @@ bool ViewGestureController::SwipeProgressTracker::handleEvent(GdkEventScroll* ev
 bool ViewGestureController::SwipeProgressTracker::shouldCancel()
 {
     bool swipingLeft = m_viewGestureController.isPhysicallySwipingLeft(m_direction);
+    double relativeVelocity = m_velocity * (swipingLeft ? 1 : -1);
 
-    if (swipingLeft && m_velocity < 0)
-        return true;
-
-    if (!swipingLeft && m_velocity > 0)
-        return true;
+    if (abs(m_progress) > swipeCancelArea)
+        return (relativeVelocity * m_distance < -swipeCancelVelocityThreshold);
 
-    return (abs(m_progress) < swipeCancelArea && abs(m_velocity) < swipeCancelVelocityThreshold);
+    return (relativeVelocity * m_distance < swipeCancelVelocityThreshold);
 }
 
 void ViewGestureController::SwipeProgressTracker::startAnimation()
@@ -404,8 +406,9 @@ void ViewGestureController::draw(cairo_t* cr, cairo_pattern_t* pageGroup)
     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);
+    double swipingLayerOffset = (swipingLeft ? 0 : width) + floor(width * progress * scale) / scale;
 
     double dimmingProgress = swipingLeft ? 1 - progress : -progress;
     if (isRTL)