Changeset 227893 in webkit


Ignore:
Timestamp:
Jan 31, 2018 1:14:33 AM (6 years ago)
Author:
Carlos Garcia Campos
Message:

REGRESSION(r227544): [GTK] contextMenuEvent is NULL on CONTEXT_MENU call
https://bugs.webkit.org/show_bug.cgi?id=182224

Reviewed by Michael Catanzaro.

Move the gestures handling to WebKitWebViewBase. This patch adds GestureControllerClient class, created and
implemented by WebKitWebViewBase and used by GestureController instead of the WebPageProxy. This way we ensure
events are handled consistently.

  • UIProcess/API/gtk/PageClientImpl.cpp:

(WebKit::PageClientImpl::doneWithTouchEvent): Cast the GdkEvent since GestureController no longer works wirth
const GdkEvents.
(WebKit::PageClientImpl::zoom): Use webkit_web_view_set_zoom_level() in case of WebKitWebView or
WebPageProxy::setPageZoomFactor() otherwise.

  • UIProcess/API/gtk/PageClientImpl.h:
  • UIProcess/API/gtk/WebKitWebViewBase.cpp:

(ClickCounter::currentClickCountForGdkButtonEvent): Receive a GdkEvent to avoid casts.
(webkitWebViewBaseHandleMouseEvent): Helper function to handle mouse events.
(webkitWebViewBaseButtonPressEvent): Use webkitWebViewBaseHandleMouseEvent.
(webkitWebViewBaseButtonReleaseEvent): Ditto.
(webkitWebViewBaseHandleWheelEvent): Helper function to handle wheel events.
(webkitWebViewBaseScrollEvent): Use webkitWebViewBaseHandleWheelEvent.
(webkitWebViewBaseMotionNotifyEvent): Use webkitWebViewBaseHandleMouseEvent.
(webkitWebViewBaseCrossingNotifyEvent): Ditto.
(webkitWebViewBaseGestureController): Pass the widget and client to GestureController.

  • UIProcess/gtk/GestureController.cpp:

(WebKit::GestureController::GestureController): Receives a widget and client now.
(WebKit::GestureController::handleEvent): Remove the const.
(WebKit::GestureController::Gesture::Gesture): Initialize client.
(WebKit::GestureController::Gesture::handleEvent): Remove the const.
(WebKit::GestureController::DragGesture::startDrag): Use the client instead of WebPageProxy.
(WebKit::GestureController::DragGesture::handleDrag): Ditto.
(WebKit::GestureController::DragGesture::handleTap): Ditto.
(WebKit::GestureController::DragGesture::begin): Ignore the const returned by gtk_gesture_get_last_event().
(WebKit::GestureController::DragGesture::update): Ditto.
(WebKit::GestureController::DragGesture::end): Ditto.
(WebKit::GestureController::DragGesture::DragGesture): Receives a widget and client now.
(WebKit::GestureController::SwipeGesture::startMomentumScroll): Use the client instead of WebPageProxy.
(WebKit::GestureController::SwipeGesture::swipe): Ignore the const returned by gtk_gesture_get_last_event().
(WebKit::GestureController::SwipeGesture::SwipeGesture): Receives a widget and client now.
(WebKit::GestureController::ZoomGesture::begin): Start the zoom.
(WebKit::GestureController::ZoomGesture::startZoom): Use the client instead of WebPageProxy.
(WebKit::GestureController::ZoomGesture::handleZoom): Ditto.
(WebKit::GestureController::ZoomGesture::ZoomGesture): Receives a widget and client now.
(WebKit::GestureController::LongPressGesture::longPressed): Use the client instead of WebKitWebView.
(WebKit::GestureController::LongPressGesture::pressed): Ignore the const returned by gtk_gesture_get_last_event().
(WebKit::GestureController::LongPressGesture::LongPressGesture): Receives a widget and client now.
(WebKit::GestureController::Gesture::simulateMouseClick): Deleted.
(WebKit::createScrollEvent): Deleted.

  • UIProcess/gtk/GestureController.h:
Location:
trunk/Source/WebKit
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r227891 r227893  
     12018-01-31  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        REGRESSION(r227544): [GTK] contextMenuEvent is NULL on CONTEXT_MENU call
     4        https://bugs.webkit.org/show_bug.cgi?id=182224
     5
     6        Reviewed by Michael Catanzaro.
     7
     8        Move the gestures handling to WebKitWebViewBase. This patch adds GestureControllerClient class, created and
     9        implemented by WebKitWebViewBase and used by GestureController instead of the WebPageProxy. This way we ensure
     10        events are handled consistently.
     11
     12        * UIProcess/API/gtk/PageClientImpl.cpp:
     13        (WebKit::PageClientImpl::doneWithTouchEvent): Cast the GdkEvent since GestureController no longer works wirth
     14        const GdkEvents.
     15        (WebKit::PageClientImpl::zoom): Use webkit_web_view_set_zoom_level() in case of WebKitWebView or
     16        WebPageProxy::setPageZoomFactor() otherwise.
     17        * UIProcess/API/gtk/PageClientImpl.h:
     18        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
     19        (ClickCounter::currentClickCountForGdkButtonEvent): Receive a GdkEvent to avoid casts.
     20        (webkitWebViewBaseHandleMouseEvent): Helper function to handle mouse events.
     21        (webkitWebViewBaseButtonPressEvent): Use webkitWebViewBaseHandleMouseEvent.
     22        (webkitWebViewBaseButtonReleaseEvent): Ditto.
     23        (webkitWebViewBaseHandleWheelEvent): Helper function to handle wheel events.
     24        (webkitWebViewBaseScrollEvent): Use webkitWebViewBaseHandleWheelEvent.
     25        (webkitWebViewBaseMotionNotifyEvent): Use webkitWebViewBaseHandleMouseEvent.
     26        (webkitWebViewBaseCrossingNotifyEvent): Ditto.
     27        (webkitWebViewBaseGestureController): Pass the widget and client to GestureController.
     28        * UIProcess/gtk/GestureController.cpp:
     29        (WebKit::GestureController::GestureController): Receives a widget and client now.
     30        (WebKit::GestureController::handleEvent): Remove the const.
     31        (WebKit::GestureController::Gesture::Gesture): Initialize client.
     32        (WebKit::GestureController::Gesture::handleEvent): Remove the const.
     33        (WebKit::GestureController::DragGesture::startDrag): Use the client instead of WebPageProxy.
     34        (WebKit::GestureController::DragGesture::handleDrag): Ditto.
     35        (WebKit::GestureController::DragGesture::handleTap): Ditto.
     36        (WebKit::GestureController::DragGesture::begin): Ignore the const returned by gtk_gesture_get_last_event().
     37        (WebKit::GestureController::DragGesture::update): Ditto.
     38        (WebKit::GestureController::DragGesture::end): Ditto.
     39        (WebKit::GestureController::DragGesture::DragGesture): Receives a widget and client now.
     40        (WebKit::GestureController::SwipeGesture::startMomentumScroll): Use the client instead of WebPageProxy.
     41        (WebKit::GestureController::SwipeGesture::swipe): Ignore the const returned by gtk_gesture_get_last_event().
     42        (WebKit::GestureController::SwipeGesture::SwipeGesture): Receives a widget and client now.
     43        (WebKit::GestureController::ZoomGesture::begin): Start the zoom.
     44        (WebKit::GestureController::ZoomGesture::startZoom): Use the client instead of WebPageProxy.
     45        (WebKit::GestureController::ZoomGesture::handleZoom): Ditto.
     46        (WebKit::GestureController::ZoomGesture::ZoomGesture): Receives a widget and client now.
     47        (WebKit::GestureController::LongPressGesture::longPressed): Use the client instead of WebKitWebView.
     48        (WebKit::GestureController::LongPressGesture::pressed): Ignore the const returned by gtk_gesture_get_last_event().
     49        (WebKit::GestureController::LongPressGesture::LongPressGesture): Receives a widget and client now.
     50        (WebKit::GestureController::Gesture::simulateMouseClick): Deleted.
     51        (WebKit::createScrollEvent): Deleted.
     52        * UIProcess/gtk/GestureController.h:
     53
    1542018-01-31  Carlos Garcia Campos  <cgarcia@igalia.com>
    255
  • trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp

    r227544 r227893  
    352352        return;
    353353    }
    354     wasEventHandled = gestureController.handleEvent(event.nativeEvent());
     354    wasEventHandled = gestureController.handleEvent(const_cast<GdkEvent*>(event.nativeEvent()));
    355355#endif
    356356
     
    483483}
    484484
     485void PageClientImpl::zoom(double zoomLevel)
     486{
     487    if (WEBKIT_IS_WEB_VIEW(m_viewWidget)) {
     488        webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(m_viewWidget), zoomLevel);
     489        return;
     490    }
     491
     492    webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(m_viewWidget))->setPageZoomFactor(zoomLevel);
     493}
     494
    485495} // namespace WebKit
  • trunk/Source/WebKit/UIProcess/API/gtk/PageClientImpl.h

    r226323 r227893  
    5151
    5252    GtkWidget* viewWidget() { return m_viewWidget; }
     53
     54    void zoom(double);
    5355
    5456private:
  • trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp

    r227630 r227893  
    9696    }
    9797
    98     int currentClickCountForGdkButtonEvent(GdkEventButton* buttonEvent)
     98    int currentClickCountForGdkButtonEvent(GdkEvent* event)
    9999    {
    100         GdkEvent* event = reinterpret_cast<GdkEvent*>(buttonEvent);
    101100        int doubleClickDistance = 250;
    102101        int doubleClickTime = 5;
     
    119118
    120119        if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
    121             || ((std::abs(buttonEvent->x - previousClickPoint.x()) < doubleClickDistance)
    122                 && (std::abs(buttonEvent->y - previousClickPoint.y()) < doubleClickDistance)
     120            || ((std::abs(event->button.x - previousClickPoint.x()) < doubleClickDistance)
     121                && (std::abs(event->button.y - previousClickPoint.y()) < doubleClickDistance)
    123122                && (eventTime - previousClickTime < static_cast<unsigned>(doubleClickTime))
    124                 && (buttonEvent->button == previousClickButton)))
     123                && (event->button.button == previousClickButton)))
    125124            currentClickCount++;
    126125        else
     
    130129        gdk_event_get_coords(event, &x, &y);
    131130        previousClickPoint = IntPoint(x, y);
    132         previousClickButton = buttonEvent->button;
     131        previousClickButton = event->button.button;
    133132        previousClickTime = eventTime;
    134133
     
    742741}
    743742
    744 static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventButton* buttonEvent)
     743static void webkitWebViewBaseHandleMouseEvent(WebKitWebViewBase* webViewBase, GdkEvent* event)
     744{
     745    WebKitWebViewBasePrivate* priv = webViewBase->priv;
     746    ASSERT(!priv->authenticationDialog);
     747
     748    int clickCount = 0;
     749
     750    switch (event->type) {
     751    case GDK_BUTTON_PRESS:
     752    case GDK_2BUTTON_PRESS:
     753    case GDK_3BUTTON_PRESS: {
     754        // For double and triple clicks GDK sends both a normal button press event
     755        // and a specific type (like GDK_2BUTTON_PRESS). If we detect a special press
     756        // coming up, ignore this event as it certainly generated the double or triple
     757        // click. The consequence of not eating this event is two DOM button press events
     758        // are generated.
     759        GUniquePtr<GdkEvent> nextEvent(gdk_event_peek());
     760        if (nextEvent && (nextEvent->any.type == GDK_2BUTTON_PRESS || nextEvent->any.type == GDK_3BUTTON_PRESS))
     761            return;
     762
     763        priv->inputMethodFilter.notifyMouseButtonPress();
     764
     765        // If it's a right click event save it as a possible context menu event.
     766        if (event->button.button == GDK_BUTTON_SECONDARY)
     767            priv->contextMenuEvent.reset(gdk_event_copy(event));
     768
     769        clickCount = priv->clickCounter.currentClickCountForGdkButtonEvent(event);
     770    }
     771        FALLTHROUGH;
     772    case GDK_BUTTON_RELEASE:
     773        gtk_widget_grab_focus(GTK_WIDGET(webViewBase));
     774        break;
     775    case GDK_MOTION_NOTIFY:
     776    case GDK_ENTER_NOTIFY:
     777    case GDK_LEAVE_NOTIFY:
     778        break;
     779    default:
     780        ASSERT_NOT_REACHED();
     781    }
     782
     783    priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(event, clickCount));
     784}
     785
     786static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventButton* event)
    745787{
    746788    WebKitWebViewBase* webViewBase = WEBKIT_WEB_VIEW_BASE(widget);
     
    750792        return GDK_EVENT_STOP;
    751793
    752     gtk_widget_grab_focus(widget);
    753 
    754     priv->inputMethodFilter.notifyMouseButtonPress();
    755 
    756     // For double and triple clicks GDK sends both a normal button press event
    757     // and a specific type (like GDK_2BUTTON_PRESS). If we detect a special press
    758     // coming up, ignore this event as it certainly generated the double or triple
    759     // click. The consequence of not eating this event is two DOM button press events
    760     // are generated.
    761     GUniquePtr<GdkEvent> nextEvent(gdk_event_peek());
    762     if (nextEvent && (nextEvent->any.type == GDK_2BUTTON_PRESS || nextEvent->any.type == GDK_3BUTTON_PRESS))
    763         return GDK_EVENT_STOP;
    764 
    765     // If it's a right click event save it as a possible context menu event.
    766     if (buttonEvent->button == 3)
    767         priv->contextMenuEvent.reset(gdk_event_copy(reinterpret_cast<GdkEvent*>(buttonEvent)));
    768 
    769     priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(buttonEvent),
    770         priv->clickCounter.currentClickCountForGdkButtonEvent(buttonEvent)));
     794    webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
     795
    771796    return GDK_EVENT_STOP;
    772797}
     
    780805        return GDK_EVENT_STOP;
    781806
    782     gtk_widget_grab_focus(widget);
    783     priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(event), 0 /* currentClickCount */));
     807    webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
    784808
    785809    return GDK_EVENT_STOP;
     810}
     811
     812static void webkitWebViewBaseHandleWheelEvent(WebKitWebViewBase* webViewBase, GdkEvent* event, std::optional<WebWheelEvent::Phase> phase = std::nullopt, std::optional<WebWheelEvent::Phase> momentum = std::nullopt)
     813{
     814    WebKitWebViewBasePrivate* priv = webViewBase->priv;
     815    ASSERT(!priv->authenticationDialog);
     816    if (phase)
     817        priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(event, phase.value(), momentum.value_or(WebWheelEvent::Phase::PhaseNone)));
     818    else
     819        priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(event));
    786820}
    787821
     
    797831        return GDK_EVENT_PROPAGATE;
    798832
    799     priv->pageProxy->handleWheelEvent(NativeWebWheelEvent(reinterpret_cast<GdkEvent*>(event)));
     833    webkitWebViewBaseHandleWheelEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
    800834
    801835    return GDK_EVENT_STOP;
     
    826860    }
    827861
    828     priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(reinterpret_cast<GdkEvent*>(event), 0 /* currentClickCount */));
     862    webkitWebViewBaseHandleMouseEvent(webViewBase, reinterpret_cast<GdkEvent*>(event));
    829863
    830864    return GDK_EVENT_PROPAGATE;
     
    867901    }
    868902
    869     priv->pageProxy->handleMouseEvent(NativeWebMouseEvent(copiedEvent ? copiedEvent.get() : event, 0 /* currentClickCount */));
     903    webkitWebViewBaseHandleMouseEvent(webViewBase, copiedEvent ? copiedEvent.get() : event);
    870904
    871905    return GDK_EVENT_PROPAGATE;
     
    961995
    962996#if HAVE(GTK_GESTURES)
     997class ViewGestureController final : public GestureControllerClient {
     998    WTF_MAKE_FAST_ALLOCATED;
     999
     1000public:
     1001    explicit ViewGestureController(WebKitWebViewBase* webViewBase)
     1002        : m_webView(webViewBase)
     1003    {
     1004    }
     1005
     1006private:
     1007    static GUniquePtr<GdkEvent> createScrollEvent(GdkEventTouch* event, const FloatPoint& point, const FloatPoint& delta, bool isStop = false)
     1008    {
     1009        GUniquePtr<GdkEvent> scrollEvent(gdk_event_new(GDK_SCROLL));
     1010        scrollEvent->scroll.time = event->time;
     1011        scrollEvent->scroll.x = point.x();
     1012        scrollEvent->scroll.y = point.y();
     1013        scrollEvent->scroll.x_root = event->x_root;
     1014        scrollEvent->scroll.y_root = event->y_root;
     1015        scrollEvent->scroll.direction = GDK_SCROLL_SMOOTH;
     1016        scrollEvent->scroll.delta_x = delta.x();
     1017        scrollEvent->scroll.delta_y = delta.y();
     1018        scrollEvent->scroll.state = event->state;
     1019#if GTK_CHECK_VERSION(3, 20, 0)
     1020        scrollEvent->scroll.is_stop = isStop;
     1021#else
     1022        UNUSED_PARAM(isStop);
     1023#endif
     1024        return scrollEvent;
     1025    }
     1026
     1027    void simulateMouseClick(const GdkEventTouch* event, unsigned button)
     1028    {
     1029        GUniquePtr<GdkEvent> pointerEvent(gdk_event_new(GDK_MOTION_NOTIFY));
     1030        pointerEvent->motion.time = event->time;
     1031        pointerEvent->motion.x = event->x;
     1032        pointerEvent->motion.y = event->y;
     1033        pointerEvent->motion.x_root = event->x_root;
     1034        pointerEvent->motion.y_root = event->y_root;
     1035        pointerEvent->motion.state = event->state;
     1036        webkitWebViewBaseHandleMouseEvent(m_webView, pointerEvent.get());
     1037
     1038        pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS));
     1039        pointerEvent->button.button = button;
     1040        pointerEvent->button.time = event->time;
     1041        pointerEvent->button.x = event->x;
     1042        pointerEvent->button.y = event->y;
     1043        pointerEvent->button.x_root = event->x_root;
     1044        pointerEvent->button.y_root = event->y_root;
     1045        webkitWebViewBaseHandleMouseEvent(m_webView, pointerEvent.get());
     1046
     1047        pointerEvent->type = GDK_BUTTON_RELEASE;
     1048        webkitWebViewBaseHandleMouseEvent(m_webView, pointerEvent.get());
     1049    }
     1050
     1051    void tap(GdkEventTouch* event) final
     1052    {
     1053        simulateMouseClick(event, GDK_BUTTON_PRIMARY);
     1054    }
     1055
     1056    void startDrag(GdkEventTouch* event, const FloatPoint& startPoint) final
     1057    {
     1058        GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, startPoint, { });
     1059        webkitWebViewBaseHandleWheelEvent(m_webView, scrollEvent.get(), WebWheelEvent::Phase::PhaseBegan);
     1060    }
     1061
     1062    void drag(GdkEventTouch* event, const FloatPoint& point, const FloatPoint& delta) final
     1063    {
     1064        GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, point, delta);
     1065        webkitWebViewBaseHandleWheelEvent(m_webView, scrollEvent.get(), WebWheelEvent::Phase::PhaseChanged);
     1066    }
     1067
     1068    void swipe(GdkEventTouch* event, const FloatPoint& velocity) final
     1069    {
     1070        GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, FloatPoint::narrowPrecision(event->x, event->y), velocity, true);
     1071        webkitWebViewBaseHandleWheelEvent(m_webView, scrollEvent.get(), WebWheelEvent::Phase::PhaseNone, WebWheelEvent::Phase::PhaseBegan);
     1072    }
     1073
     1074    void startZoom(const IntPoint& center, double& initialScale, IntPoint& initialPoint) final
     1075    {
     1076        auto* page = webkitWebViewBaseGetPage(m_webView);
     1077        ASSERT(page);
     1078        initialScale = page->pageZoomFactor();
     1079        page->getCenterForZoomGesture(center, initialPoint);
     1080    }
     1081
     1082    void zoom(double scale) final
     1083    {
     1084        m_webView->priv->pageClient->zoom(scale);
     1085    }
     1086
     1087    void longPress(GdkEventTouch* event) final
     1088    {
     1089        simulateMouseClick(event, GDK_BUTTON_SECONDARY);
     1090    }
     1091
     1092    WebKitWebViewBase* m_webView;
     1093};
     1094
    9631095GestureController& webkitWebViewBaseGestureController(WebKitWebViewBase* webViewBase)
    9641096{
    9651097    WebKitWebViewBasePrivate* priv = webViewBase->priv;
    9661098    if (!priv->gestureController)
    967         priv->gestureController = std::make_unique<GestureController>(*priv->pageProxy);
     1099        priv->gestureController = std::make_unique<GestureController>(GTK_WIDGET(webViewBase), std::make_unique<ViewGestureController>(webViewBase));
    9681100    return *priv->gestureController;
    9691101}
  • trunk/Source/WebKit/UIProcess/gtk/GestureController.cpp

    r227744 r227893  
    2929#if HAVE(GTK_GESTURES)
    3030
    31 #include "NativeWebMouseEvent.h"
    32 #include "NativeWebWheelEvent.h"
    33 #include "WebKitWebView.h"
    34 #include "WebPageProxy.h"
    35 #include <WebCore/FloatPoint.h>
    3631#include <WebCore/Scrollbar.h>
    3732#include <gtk/gtk.h>
     
    4136namespace WebKit {
    4237
    43 GestureController::GestureController(WebPageProxy& page)
    44     : m_dragGesture(page)
    45     , m_swipeGesture(page)
    46     , m_zoomGesture(page)
    47     , m_longpressGesture(page)
    48 {
    49 }
    50 
    51 bool GestureController::handleEvent(const GdkEvent* event)
     38GestureController::GestureController(GtkWidget* widget, std::unique_ptr<GestureControllerClient>&& client)
     39    : m_client(WTFMove(client))
     40    , m_dragGesture(widget, *m_client)
     41    , m_swipeGesture(widget, *m_client)
     42    , m_zoomGesture(widget, *m_client)
     43    , m_longpressGesture(widget, *m_client)
     44{
     45}
     46
     47bool GestureController::handleEvent(GdkEvent* event)
    5248{
    5349    bool wasProcessingGestures = isProcessingGestures();
     
    6662}
    6763
    68 GestureController::Gesture::Gesture(GtkGesture* gesture, WebPageProxy& page)
     64GestureController::Gesture::Gesture(GtkGesture* gesture, GestureControllerClient& client)
    6965    : m_gesture(adoptGRef(gesture))
    70     , m_page(page)
     66    , m_client(client)
    7167{
    7268    gtk_event_controller_set_propagation_phase(GTK_EVENT_CONTROLLER(m_gesture.get()), GTK_PHASE_NONE);
     
    8379}
    8480
    85 void GestureController::Gesture::handleEvent(const GdkEvent* event)
     81void GestureController::Gesture::handleEvent(GdkEvent* event)
    8682{
    8783    gtk_event_controller_handle_event(GTK_EVENT_CONTROLLER(m_gesture.get()), event);
    8884}
    8985
    90 void GestureController::Gesture::simulateMouseClick(const GdkEvent* event, unsigned buttonType)
    91 {
    92     GUniquePtr<GdkEvent> pointerEvent(gdk_event_new(GDK_MOTION_NOTIFY));
    93     pointerEvent->motion.time = event->touch.time;
    94     pointerEvent->motion.x = event->touch.x;
    95     pointerEvent->motion.y = event->touch.y;
    96     pointerEvent->motion.x_root = event->touch.x_root;
    97     pointerEvent->motion.y_root = event->touch.y_root;
    98     pointerEvent->motion.state = event->touch.state;
    99     m_page.handleMouseEvent(NativeWebMouseEvent(pointerEvent.get(), 0));
    100 
    101     pointerEvent.reset(gdk_event_new(GDK_BUTTON_PRESS));
    102     pointerEvent->button.button = buttonType;
    103     pointerEvent->button.time = event->touch.time;
    104     pointerEvent->button.x = event->touch.x;
    105     pointerEvent->button.y = event->touch.y;
    106     pointerEvent->button.x_root = event->touch.x_root;
    107     pointerEvent->button.y_root = event->touch.y_root;
    108     m_page.handleMouseEvent(NativeWebMouseEvent(pointerEvent.get(), 1));
    109 
    110     pointerEvent->type = GDK_BUTTON_RELEASE;
    111     m_page.handleMouseEvent(NativeWebMouseEvent(pointerEvent.get(), 0));
    112 }
    113 
    114 static GUniquePtr<GdkEvent> createScrollEvent(const GdkEvent* event, double x, double y, double deltaX, double deltaY, gboolean isStop)
    115 {
    116     GUniquePtr<GdkEvent> scrollEvent(gdk_event_new(GDK_SCROLL));
    117     scrollEvent->scroll.time = event->touch.time;
    118     scrollEvent->scroll.x = x;
    119     scrollEvent->scroll.y = y;
    120     scrollEvent->scroll.x_root = event->touch.x_root;
    121     scrollEvent->scroll.y_root = event->touch.y_root;
    122     scrollEvent->scroll.direction = GDK_SCROLL_SMOOTH;
    123     scrollEvent->scroll.delta_x = deltaX;
    124     scrollEvent->scroll.delta_y = deltaY;
    125     scrollEvent->scroll.state = event->touch.state;
    126 #if GTK_CHECK_VERSION(3, 20, 0)
    127     scrollEvent->scroll.is_stop = isStop;
    128 #endif
    129     return scrollEvent;
    130 }
    131 
    132 void GestureController::DragGesture::startDrag(const GdkEvent* event)
     86void GestureController::DragGesture::startDrag(GdkEvent* event)
    13387{
    13488    ASSERT(!m_inDrag);
    135     GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, m_start.x(), m_start.y(), 0, 0, FALSE);
    136     m_page.handleWheelEvent(NativeWebWheelEvent(scrollEvent.get(), WebWheelEvent::Phase::PhaseBegan, WebWheelEvent::Phase::PhaseNone));
    137 }
    138 
    139 void GestureController::DragGesture::handleDrag(const GdkEvent* event, double x, double y)
     89    m_client.startDrag(reinterpret_cast<GdkEventTouch*>(event), m_start);
     90}
     91
     92void GestureController::DragGesture::handleDrag(GdkEvent* event, double x, double y)
    14093{
    14194    ASSERT(m_inDrag);
    142     GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event,
    143         m_start.x(), m_start.y(),
    144         (m_offset.x() - x) / Scrollbar::pixelsPerLineStep(),
    145         (m_offset.y() - y) / Scrollbar::pixelsPerLineStep(),
    146         FALSE);
    147     m_page.handleWheelEvent(NativeWebWheelEvent(scrollEvent.get(), WebWheelEvent::Phase::PhaseChanged, WebWheelEvent::Phase::PhaseNone));
    148 }
    149 
    150 void GestureController::DragGesture::handleTap(const GdkEvent* event)
     95    m_client.drag(reinterpret_cast<GdkEventTouch*>(event), m_start,
     96        FloatPoint::narrowPrecision((m_offset.x() - x) / Scrollbar::pixelsPerLineStep(), (m_offset.y() - y) / Scrollbar::pixelsPerLineStep()));
     97}
     98
     99void GestureController::DragGesture::handleTap(GdkEvent* event)
    151100{
    152101    ASSERT(!m_inDrag);
    153     simulateMouseClick(event, GDK_BUTTON_PRIMARY);
     102    m_client.tap(reinterpret_cast<GdkEventTouch*>(event));
    154103}
    155104
     
    166115    g_object_get(gtk_widget_get_settings(widget), "gtk-long-press-time", &delay, nullptr);
    167116    dragGesture->m_longPressTimeout.startOneShot(1_ms * delay);
    168     dragGesture->startDrag(gtk_gesture_get_last_event(gesture, sequence));
     117    dragGesture->startDrag(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)));
    169118}
    170119
     
    181130
    182131    if (dragGesture->m_inDrag)
    183         dragGesture->handleDrag(gtk_gesture_get_last_event(gesture, sequence), x, y);
     132        dragGesture->handleDrag(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)), x, y);
    184133    dragGesture->m_offset.set(x, y);
    185134}
     
    193142    }
    194143    if (!dragGesture->m_inDrag) {
    195         dragGesture->handleTap(gtk_gesture_get_last_event(gesture, sequence));
     144        dragGesture->handleTap(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)));
    196145        gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_DENIED);
    197146    }
     
    203152}
    204153
    205 GestureController::DragGesture::DragGesture(WebPageProxy& page)
    206     : Gesture(gtk_gesture_drag_new(page.viewWidget()), page)
     154GestureController::DragGesture::DragGesture(GtkWidget* widget, GestureControllerClient& client)
     155    : Gesture(gtk_gesture_drag_new(widget), client)
    207156    , m_longPressTimeout(RunLoop::main(), this, &GestureController::DragGesture::longPressFired)
    208     , m_inDrag(false)
    209157{
    210158    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(m_gesture.get()), TRUE);
     
    214162}
    215163
    216 void GestureController::SwipeGesture::startMomentumScroll(const GdkEvent* event, double velocityX, double velocityY)
    217 {
    218     GUniquePtr<GdkEvent> scrollEvent = createScrollEvent(event, event->touch.x, event->touch.y, velocityX, velocityY, TRUE);
    219     m_page.handleWheelEvent(NativeWebWheelEvent(scrollEvent.get(), WebWheelEvent::Phase::PhaseNone, WebWheelEvent::Phase::PhaseBegan));
     164void GestureController::SwipeGesture::startMomentumScroll(GdkEvent* event, double velocityX, double velocityY)
     165{
     166    m_client.swipe(reinterpret_cast<GdkEventTouch*>(event), FloatPoint::narrowPrecision(velocityX, velocityY));
    220167}
    221168
     
    228175    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
    229176
    230     swipeGesture->startMomentumScroll(gtk_gesture_get_last_event(gesture, sequence), velocityX, velocityY);
    231 }
    232 
    233 GestureController::SwipeGesture::SwipeGesture(WebPageProxy& page)
    234     : Gesture(gtk_gesture_swipe_new(page.viewWidget()), page)
     177    swipeGesture->startMomentumScroll(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)), velocityX, velocityY);
     178}
     179
     180GestureController::SwipeGesture::SwipeGesture(GtkWidget* widget, GestureControllerClient& client)
     181    : Gesture(gtk_gesture_swipe_new(widget), client)
    235182{
    236183    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(m_gesture.get()), TRUE);
    237184    g_signal_connect_swapped(m_gesture.get(), "swipe", G_CALLBACK(swipe), this);
     185}
     186
     187void GestureController::ZoomGesture::begin(ZoomGesture* zoomGesture, GdkEventSequence*, GtkGesture* gesture)
     188{
     189    gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);
     190    zoomGesture->startZoom();
    238191}
    239192
     
    245198}
    246199
    247 void GestureController::ZoomGesture::begin(ZoomGesture* zoomGesture, GdkEventSequence*, GtkGesture* gesture)
    248 {
    249     gtk_gesture_set_state(gesture, GTK_EVENT_SEQUENCE_CLAIMED);
    250 
    251     zoomGesture->m_initialScale = zoomGesture->m_page.pageZoomFactor();
    252     zoomGesture->m_page.getCenterForZoomGesture(zoomGesture->center(), zoomGesture->m_initialPoint);
     200void GestureController::ZoomGesture::startZoom()
     201{
     202    m_client.startZoom(center(), m_initialScale, m_initialPoint);
    253203}
    254204
    255205void GestureController::ZoomGesture::handleZoom()
    256206{
    257     webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(m_page.viewWidget()), m_scale);
     207    m_client.zoom(m_scale);
    258208}
    259209
     
    268218}
    269219
    270 GestureController::ZoomGesture::ZoomGesture(WebPageProxy& page)
    271     : Gesture(gtk_gesture_zoom_new(page.viewWidget()), page)
    272     , m_initialScale(0)
    273     , m_scale(0)
     220GestureController::ZoomGesture::ZoomGesture(GtkWidget* widget, GestureControllerClient& client)
     221    : Gesture(gtk_gesture_zoom_new(widget), client)
    274222    , m_idle(RunLoop::main(), this, &GestureController::ZoomGesture::handleZoom)
    275223{
     
    278226}
    279227
    280 void GestureController::LongPressGesture::longPressed(const GdkEvent* event)
    281 {
    282     simulateMouseClick(event, GDK_BUTTON_SECONDARY);
     228void GestureController::LongPressGesture::longPressed(GdkEvent* event)
     229{
     230    m_client.longPress(reinterpret_cast<GdkEventTouch*>(event));
    283231}
    284232
     
    291239    gtk_gesture_set_sequence_state(gesture, sequence, GTK_EVENT_SEQUENCE_CLAIMED);
    292240
    293     longpressGesture->longPressed(gtk_gesture_get_last_event(gesture, sequence));
    294 }
    295 
    296 GestureController::LongPressGesture::LongPressGesture(WebPageProxy& page)
    297     : Gesture(gtk_gesture_long_press_new(page.viewWidget()), page)
     241    longpressGesture->longPressed(const_cast<GdkEvent*>(gtk_gesture_get_last_event(gesture, sequence)));
     242}
     243
     244GestureController::LongPressGesture::LongPressGesture(GtkWidget* widget, GestureControllerClient& client)
     245    : Gesture(gtk_gesture_long_press_new(widget), client)
    298246{
    299247    gtk_gesture_single_set_touch_only(GTK_GESTURE_SINGLE(m_gesture.get()), TRUE);
  • trunk/Source/WebKit/UIProcess/gtk/GestureController.h

    r227675 r227893  
    2424 */
    2525
    26 #ifndef GestureController_h
    27 #define GestureController_h
     26#pragma once
    2827
    2928#if HAVE(GTK_GESTURES)
     
    3534
    3635typedef union _GdkEvent GdkEvent;
     36typedef struct _GdkEventTouch GdkEventTouch;
    3737typedef struct _GdkEventSequence GdkEventSequence;
    3838typedef struct _GtkGesture GtkGesture;
    3939
    4040namespace WebKit {
    41 class WebPageProxy;
     41
     42class GestureControllerClient {
     43public:
     44    virtual void tap(GdkEventTouch*) = 0;
     45
     46    virtual void startDrag(GdkEventTouch*, const WebCore::FloatPoint&) = 0;
     47    virtual void drag(GdkEventTouch*, const WebCore::FloatPoint&, const WebCore::FloatPoint&) = 0;
     48
     49    virtual void swipe(GdkEventTouch*, const WebCore::FloatPoint&) = 0;
     50
     51    virtual void startZoom(const WebCore::IntPoint& center, double& initialScale, WebCore::IntPoint& initialPoint) = 0;
     52    virtual void zoom(double) = 0;
     53
     54    virtual void longPress(GdkEventTouch*) = 0;
     55};
    4256
    4357class GestureController {
    4458    WTF_MAKE_NONCOPYABLE(GestureController);
     59    WTF_MAKE_FAST_ALLOCATED;
    4560
    4661public:
    47     GestureController(WebPageProxy&);
     62    GestureController(GtkWidget*, std::unique_ptr<GestureControllerClient>&&);
    4863
    4964    bool isProcessingGestures() const;
    50     bool handleEvent(const GdkEvent*);
     65    bool handleEvent(GdkEvent*);
    5166
    5267    void reset()
     
    6378        void reset();
    6479        bool isActive() const;
    65         void handleEvent(const GdkEvent*);
    66         void simulateMouseClick(const GdkEvent*, unsigned);
     80        void handleEvent(GdkEvent*);
    6781
    6882    protected:
    69         Gesture(GtkGesture*, WebPageProxy&);
     83        Gesture(GtkGesture*, GestureControllerClient&);
    7084
    7185        GRefPtr<GtkGesture> m_gesture;
    72         WebPageProxy& m_page;
     86        GestureControllerClient& m_client;
    7387    };
    7488
    7589    class DragGesture final : public Gesture {
    7690    public:
    77         DragGesture(WebPageProxy&);
     91        DragGesture(GtkWidget*, GestureControllerClient&);
    7892
    7993    private:
    8094        // Notify that a drag started, allowing to stop kinetic deceleration.
    81         void startDrag(const GdkEvent*);
    82         void handleDrag(const GdkEvent*, double x, double y);
    83         void handleTap(const GdkEvent*);
     95        void startDrag(GdkEvent*);
     96        void handleDrag(GdkEvent*, double x, double y);
     97        void handleTap(GdkEvent*);
    8498        void longPressFired();
    8599
     
    92106        RunLoop::Timer<DragGesture> m_longPressTimeout;
    93107        GRefPtr<GtkGesture> m_longPress;
    94         bool m_inDrag;
     108        bool m_inDrag { false };
    95109    };
    96110
    97111    class SwipeGesture final : public Gesture {
    98112    public:
    99         SwipeGesture(WebPageProxy&);
     113        SwipeGesture(GtkWidget*, GestureControllerClient&);
    100114
    101115    private:
    102         void startMomentumScroll(const GdkEvent*, double velocityX, double velocityY);
     116        void startMomentumScroll(GdkEvent*, double velocityX, double velocityY);
    103117
    104118        static void swipe(SwipeGesture*, double velocityX, double velocityY, GtkGesture*);
     
    107121    class ZoomGesture final : public Gesture {
    108122    public:
    109         ZoomGesture(WebPageProxy&);
     123        ZoomGesture(GtkWidget*, GestureControllerClient&);
    110124
    111125    private:
    112126        WebCore::IntPoint center() const;
     127        void startZoom();
    113128        void handleZoom();
    114129
     
    116131        static void scaleChanged(ZoomGesture*, double scale, GtkGesture*);
    117132
    118         gdouble m_initialScale;
    119         gdouble m_scale;
     133        double m_initialScale { 0 };
     134        double m_scale { 0 };
    120135        WebCore::IntPoint m_initialPoint;
    121136        WebCore::IntPoint m_viewPoint;
     
    125140    class LongPressGesture final : public Gesture {
    126141    public:
    127         LongPressGesture(WebPageProxy&);
     142        LongPressGesture(GtkWidget*, GestureControllerClient&);
    128143
    129144    private:
    130         void longPressed(const GdkEvent*);
     145        void longPressed(GdkEvent*);
    131146
    132147        static void pressed(LongPressGesture*, double x, double y, GtkGesture*);
    133148    };
    134149
     150    std::unique_ptr<GestureControllerClient> m_client;
    135151    DragGesture m_dragGesture;
    136152    SwipeGesture m_swipeGesture;
     
    142158
    143159#endif // HAVE(GTK_GESTURES)
    144 
    145 #endif // GestureController_h
Note: See TracChangeset for help on using the changeset viewer.