WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Updated patch.
patch (text/plain), 77.70 KB, created by
Carlos Garnacho
on 2021-05-06 04:31:26 PDT
(
hide
)
Description:
Updated patch.
Filename:
MIME Type:
Creator:
Carlos Garnacho
Created:
2021-05-06 04:31:26 PDT
Size:
77.70 KB
patch
obsolete
>diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index ff75c5cc1453..657fc1c19800 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,17 @@ >+2021-05-05 Carlos Garnacho <carlosg@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 NOBODY (OOPS!). >+ >+ No new tests (OOPS!). >+ >+ * 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-03 Philippe Normand <pnormand@igalia.com> > > [GTK] Build with VIDEO=OFF fails >diff --git a/Source/WebCore/platform/gtk/GtkVersioning.h b/Source/WebCore/platform/gtk/GtkVersioning.h >index 729cd276edf0..7941e911c627 100644 >--- a/Source/WebCore/platform/gtk/GtkVersioning.h >+++ b/Source/WebCore/platform/gtk/GtkVersioning.h >@@ -276,4 +276,18 @@ gtk_scrolled_window_new() > 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) >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index ca57da44aaeb..02f86b4fae74 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,115 @@ >+2021-05-05 Carlos Garnacho <carlosg@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 NOBODY (OOPS!). >+ >+ 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 (OOPS!). >+ >+ * 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-03 Aditya Keerthi <akeerthi@apple.com> > > [iOS] Crash when tapping fields on cycle.travel >diff --git a/Source/WebKit/PlatformGTK.cmake b/Source/WebKit/PlatformGTK.cmake >index b01447ba4f6c..6cfaf2882a71 100644 >--- a/Source/WebKit/PlatformGTK.cmake >+++ b/Source/WebKit/PlatformGTK.cmake >@@ -33,20 +33,11 @@ list(APPEND WebKit_UNIFIED_SOURCE_LIST_FILES > "SourcesGTK.txt" > ) > >-if (NOT USE_GTK4) >- list(APPEND WebKit_SOURCES >- UIProcess/ViewGestureController.cpp >- >- UIProcess/gtk/ViewGestureControllerGtk.cpp >- >- WebProcess/WebPage/ViewGestureGeometryCollector.cpp >- ) >- list(APPEND WebKit_MESSAGES_IN_FILES >- UIProcess/ViewGestureController >+list(APPEND WebKit_MESSAGES_IN_FILES >+ UIProcess/ViewGestureController > >- WebProcess/WebPage/ViewGestureGeometryCollector >- ) >-endif () >+ WebProcess/WebPage/ViewGestureGeometryCollector >+) > > list(APPEND WebKit_DERIVED_SOURCES > ${WebKit2Gtk_DERIVED_SOURCES_DIR}/InspectorGResourceBundle.c >diff --git a/Source/WebKit/SourcesGTK.txt b/Source/WebKit/SourcesGTK.txt >index c85f5ce2a8f4..894e5d4d325e 100644 >--- a/Source/WebKit/SourcesGTK.txt >+++ b/Source/WebKit/SourcesGTK.txt >@@ -105,6 +105,7 @@ Shared/unix/AuxiliaryProcessMain.cpp > 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/Clipboard.cpp > 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/PointerLockManagerWayland.cpp @no-unify > 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/gtk/WebEditorClientGtk.cpp > WebProcess/WebCoreSupport/soup/WebFrameNetworkingContext.cpp > > WebProcess/WebPage/AcceleratedSurface.cpp >+WebProcess/WebPage/ViewGestureGeometryCollector.cpp > > WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp > WebProcess/WebPage/CoordinatedGraphics/DrawingAreaCoordinatedGraphics.cpp >diff --git a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp >index 2cf4f433d82d..2fbcb32740df 100644 >--- a/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp >+++ b/Source/WebKit/UIProcess/API/gtk/PageClientImpl.cpp >@@ -412,65 +412,8 @@ void PageClientImpl::beganExitFullScreen(const IntRect& /* initialFrame */, cons > #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 @@ void PageClientImpl::wheelEventWasNotHandledByWebCore(const NativeWebWheelEvent& > #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; > } > >diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp >index 578bf98278ba..c3bdeb34c730 100644 >--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp >+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBase.cpp >@@ -316,11 +316,9 @@ struct _WebKitWebViewBasePrivate { > 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 @@ struct _WebKitWebViewBasePrivate { > 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,9 +752,21 @@ static void webkitWebViewBaseSnapshot(GtkWidget* widget, GtkSnapshot* snapshot) > 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) >@@ -1157,6 +1175,9 @@ static gboolean webkitWebViewBaseButtonPressEvent(GtkWidget* widget, GdkEventBut > 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 @@ static gboolean webkitWebViewBaseButtonReleaseEvent(GtkWidget* widget, GdkEventB > > 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 @@ static gboolean webkitWebViewBaseButtonReleaseEvent(GtkWidget* widget, GdkEventB > #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 webkitWebViewBaseButtonPressed(WebKitWebViewBase* webViewBase, int c > > 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 bool shouldInvertDirectionForScrollEvent(WebHitTestResultData::IsScrollba > 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,13 +1317,22 @@ static gboolean webkitWebViewBaseScrollEvent(GtkWidget* widget, GdkEventScroll* > #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 @@ static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMo > 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 @@ static void webkitWebViewBaseLeave(WebKitWebViewBase* webViewBase, GdkCrossingMo > } > #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 @@ static void appendTouchEvent(Vector<WebPlatformTouchPoint>& touchPoints, const G > 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 @@ static void webkitWebViewBaseGetTouchPointsForEvent(WebKitWebViewBase* webViewBa > 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 @@ static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEventTouch* ev > 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,149 +1590,23 @@ static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEventTouch* ev > priv->touchEvents.remove(sequence); > break; > default: >- break; >+ return GDK_EVENT_PROPAGATE; > } > > Vector<WebPlatformTouchPoint> touchPoints; > 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,32 +1614,25 @@ void webkitWebViewBaseSetEnableBackForwardNavigationGesture(WebKitWebViewBase* w > 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; > } > > bool webkitWebViewBaseCompleteBackSwipeForTesting(WebKitWebViewBase* webViewBase) > { >-#if !USE(GTK4) > if (auto* gestureController = webkitWebViewBaseViewGestureController(webViewBase)) > return gestureController->completeSimulatedSwipeInDirectionForTesting(ViewGestureController::SwipeDirection::Back); >-#endif > > return FALSE; > } >@@ -1736,13 +1661,6 @@ static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint /* x */, g > } > > #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 +1842,170 @@ static gboolean webkitWebViewBaseFocus(GtkWidget* widget, GtkDirectionType direc > 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; >+#if USE(GTK4) >+ eventTime = static_cast<int32_t>(gtk_event_controller_get_current_event_time(GTK_EVENT_CONTROLLER(gesture))); >+#else >+ eventTime = static_cast<int32_t>(gtk_get_current_event_time()); >+#endif >+ 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); >+} >+ >+#if !USE(GTK4) >+static void gestureWeakNotify(gpointer data, GObject* oldLocation) >+{ >+ g_object_unref(data); >+} >+#endif >+ > static void webkitWebViewBaseConstructed(GObject* object) > { > G_OBJECT_CLASS(webkit_web_view_base_parent_class)->constructed(object); >@@ -1961,12 +2043,77 @@ static void webkitWebViewBaseConstructed(GObject* object) > 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_weak_ref(viewWidget, gestureWeakNotify, priv->touchGestureGroup); >+#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_weak_ref(viewWidget, gestureWeakNotify, gesture); >+#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_weak_ref(viewWidget, gestureWeakNotify, gesture); >+#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_weak_ref(viewWidget, gestureWeakNotify, gesture); >+#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_weak_ref(viewWidget, gestureWeakNotify, gesture); >+#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 +2156,6 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie > #endif > widgetClass->query_tooltip = webkitWebViewBaseQueryTooltip; > #if !USE(GTK4) >- widgetClass->event = webkitWebViewBaseEvent; > widgetClass->get_accessible = webkitWebViewBaseGetAccessible; > #endif > #if USE(GTK4) >@@ -2298,18 +2444,14 @@ bool webkitWebViewBaseMakeGLContextCurrent(WebKitWebViewBase* webkitWebViewBase) > > 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,14 +2464,12 @@ void webkitWebViewBaseDidRelaunchWebProcess(WebKitWebViewBase* webkitWebViewBase > auto* drawingArea = static_cast<DrawingAreaProxyCoordinatedGraphics*>(priv->pageProxy->drawingArea()); > priv->acceleratedBackingStore->update(drawingArea->layerTreeContext()); > } >-#if !USE(GTK4) > if (priv->viewGestureController) > priv->viewGestureController->connectToProcess(); > else { > priv->viewGestureController = makeUnique<WebKit::ViewGestureController>(*priv->pageProxy); > priv->viewGestureController->setSwipeGestureEnabled(priv->isBackForwardNavigationGestureEnabled); > } >-#endif > } > > void webkitWebViewBasePageClosed(WebKitWebViewBase* webkitWebViewBase) >@@ -2364,56 +2504,44 @@ RefPtr<WebKit::ViewSnapshot> webkitWebViewBaseTakeViewSnapshot(WebKitWebViewBase > > 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 +2920,10 @@ void webkitWebViewBaseMakeBlank(WebKitWebViewBase* webViewBase, bool makeBlank) > 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); >+} >diff --git a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h >index ed2699dbe0db..7e78a6a4cc4b 100644 >--- a/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h >+++ b/Source/WebKit/UIProcess/API/gtk/WebKitWebViewBasePrivate.h >@@ -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 webkitWebViewBaseStartDrag(WebKitWebViewBase*, WebCore::SelectionData&&, Op > 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 @@ WebKitInputMethodContext* webkitWebViewBaseGetInputMethodContext(WebKitWebViewBa > void webkitWebViewBaseSynthesizeCompositionKeyPress(WebKitWebViewBase*, const String& text, Optional<Vector<WebCore::CompositionUnderline>>&&, Optional<WebKit::EditingRange>&&); > > void webkitWebViewBaseMakeBlank(WebKitWebViewBase*, bool); >+void webkitWebViewBasePageGrabbedTouch(WebKitWebViewBase* webkitWebViewBase); >diff --git a/Source/WebKit/UIProcess/ViewGestureController.h b/Source/WebKit/UIProcess/ViewGestureController.h >index f25e7923d3af..b86e00b6c29d 100644 >--- a/Source/WebKit/UIProcess/ViewGestureController.h >+++ b/Source/WebKit/UIProcess/ViewGestureController.h >@@ -74,8 +74,13 @@ class Navigation; > #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,7 +178,11 @@ public: > > #if PLATFORM(GTK) > void cancelSwipe(); >+#if USE(GTK4) >+ void snapshot(GtkSnapshot*, GskRenderNode*); >+#else > void draw(cairo_t*, cairo_pattern_t*); >+#endif > #endif > > // Testing >diff --git a/Source/WebKit/UIProcess/gtk/GestureController.cpp b/Source/WebKit/UIProcess/gtk/GestureController.cpp >deleted file mode 100644 >index f2c451cf5c42..000000000000 >--- a/Source/WebKit/UIProcess/gtk/GestureController.cpp >+++ /dev/null >@@ -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 >diff --git a/Source/WebKit/UIProcess/gtk/GestureController.h b/Source/WebKit/UIProcess/gtk/GestureController.h >deleted file mode 100644 >index 5146d4584e61..000000000000 >--- a/Source/WebKit/UIProcess/gtk/GestureController.h >+++ /dev/null >@@ -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 >diff --git a/Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp b/Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp >index 35a79a5f79d8..d4cccd3bc2cd 100644 >--- a/Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp >+++ b/Source/WebKit/UIProcess/gtk/ViewGestureControllerGtk.cpp >@@ -48,9 +48,9 @@ static const double swipeAnimationDurationMultiplier = 3; > 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 @@ void ViewGestureController::platformTeardown() > 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 @@ void ViewGestureController::SwipeProgressTracker::reset() > 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 @@ bool ViewGestureController::SwipeProgressTracker::handleEvent(GdkEventScroll* ev > 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 @@ void ViewGestureController::SwipeProgressTracker::endAnimation() > 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 @@ static int elementWidth(GtkStyleContext* context) > > return width; > } >+#endif > > void ViewGestureController::beginSwipeGesture(WebBackForwardListItem* targetItem, SwipeDirection direction) > { >@@ -346,6 +336,7 @@ void ViewGestureController::beginSwipeGesture(WebBackForwardListItem* targetItem > } > } > >+#if !USE(GTK4) > if (!m_currentSwipeSnapshotPattern) { > GdkRGBA color; > auto* context = gtk_widget_get_style_context(m_webPageProxy.viewWidget()); >@@ -382,6 +373,7 @@ void ViewGestureController::beginSwipeGesture(WebBackForwardListItem* targetItem > 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 @@ void ViewGestureController::cancelSwipe() > } > } > >+#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 @@ void ViewGestureController::draw(cairo_t* cr, cairo_pattern_t* pageGroup) > > cairo_restore(cr); > } >+#endif > > void ViewGestureController::removeSwipeSnapshot() > { >@@ -518,37 +554,6 @@ void ViewGestureController::removeSwipeSnapshot() > 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,17 +566,16 @@ bool ViewGestureController::beginSimulatedSwipeInDirectionForTesting(SwipeDirect > 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; > } > > 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;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
ews-feeder
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 212324
:
427570
|
427869
|
427876
|
427984