.: [GTK] Enable touch features
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 Feb 2014 10:55:50 +0000 (10:55 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 Feb 2014 10:55:50 +0000 (10:55 +0000)
https://bugs.webkit.org/show_bug.cgi?id=98931

Patch by Carlos Garnacho <carlosg@gnome.org> on 2014-02-09
Reviewed by Carlos Garcia Campos.

* Source/autotools/SetupWebKitFeatures.m4:
* Source/cmake/OptionsGTK.cmake: set ENABLE_TOUCH_EVENTS to 1 if building with GTK+.

Source/WebCore: [GTK] Add touch-events related code to build
https://bugs.webkit.org/show_bug.cgi?id=98931

Patch by Carlos Garnacho <carlosg@gnome.org> on 2014-02-09
Reviewed by Carlos Garcia Campos.

Tests in fast/events/touch have been enabled on GTK+ now that touch
support is implemented, and thus all expected bits are there.

* platform/gtk/GtkTouchContextHelper.cpp:
* platform/gtk/GtkTouchContextHelper.h: Add helper object to track all touchpoints, handy
when creating WebTouchEvents.
* GNUmakefile.list.am:
* PlatformGTK.cmake:
* bindings/gobject/GNUmakefile.am: Add touch related code and idls to build, those are
necessary now that GTK+ implements touch events.

Source/WebKit/gtk: [GTK] Allow building with touch events enabled
https://bugs.webkit.org/show_bug.cgi?id=98931

Patch by Carlos Garnacho <carlosg@gnome.org> on 2014-02-09
Reviewed by Carlos Garcia Campos.

Even though WebKit1 GTK code doesn't implement touch events,
Fix build if ENABLE_TOUCH_EVENTS is present for WK2.

* WebCoreSupport/ChromeClientGtk.h:
(WebKit::ChromeClient::needTouchEvents): Add empty stub

Source/WebKit2: [GTK] Implement support touch events
https://bugs.webkit.org/show_bug.cgi?id=98931

Patch by Carlos Garnacho <carlosg@gnome.org> on 2014-02-09
Reviewed by Carlos Garcia Campos.

In GTK+ >= 3.4.0, GdkEventTouch is available to inform about multitouch events. Use these to implement
touch events on this platform. If a touch is left unhandled and is the "pointer emulating" one, mouse
events will be generated as a fallback.

* GNUmakefile.list.am:
* PlatformGTK.cmake:
* Shared/gtk/NativeWebTouchEventGtk.cpp:
* Shared/NativeWebTouchEvent.h:
(WebKit::NativeWebTouchEvent::nativeEvent):
(WebKit::NativeWebTouchEvent::touchContext): Add GTK+ implementation of NativeWebTouchEvent.
* Shared/gtk/WebEventFactory.cpp:
(WebKit::touchPhaseFromEvents):
(WebKit::WebEventFactory::createWebTouchEvent): Add methods to generate WebTouchEvents out
of GdkEventTouch events, a GtkTouchContextHelper object is used to hold information about all current
touches, in order to build information about all individual touchpoints.
* Shared/gtk/WebEventFactory.h:
* UIProcess/API/gtk/PageClientImpl.cpp:
(WebKit::PageClientImpl::doneWithTouchEvent): Implement pointer emulation. If a touch event was unhandled
in DOM and pertains to the touch sequence that emulates pointer events. The event gets transformed to its
mouse event counterpart and handled by the widget again.
* UIProcess/API/gtk/PageClientImpl.h:
* UIProcess/API/gtk/WebKitWebViewBase.cpp:
(webkitWebViewBaseRealize): Listen for touch events
(webkitWebViewBaseTouchEvent):
(webkit_web_view_base_class_init): Add implementation for the touch_events() handler, this merely
lets the pageProxy handle the NativeWebTouchEvent we create to wrap the GdkEvent received.

Tools: [GTK] Enable touch features
https://bugs.webkit.org/show_bug.cgi?id=98931

Patch by Carlos Garnacho <carlosg@gnome.org> on 2014-02-09
Reviewed by Carlos Garcia Campos.

* WebKitTestRunner/EventSenderProxy.h:
* WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
(WTR::updateEventCoordinates):
(WTR::EventSenderProxy::createTouchEvent):
(WTR::EventSenderProxy::addTouchPoint):
(WTR::EventSenderProxy::updateTouchPoint):
(WTR::EventSenderProxy::sendUpdatedTouchEvents):
(WTR::EventSenderProxy::setTouchPointRadius):
(WTR::EventSenderProxy::setTouchModifier): Implement touch event proxying.

LayoutTests: [GTK] Enable touch features
https://bugs.webkit.org/show_bug.cgi?id=98931

Patch by Carlos Garnacho <carlosg@gnome.org> on 2014-02-09
Reviewed by Carlos Garcia Campos.

* platform/gtk/TestExpectations: remove fast/events/touch
* platform/gtk-wk2/TestExpectations: Add new expectations on
fast/events/touch events.

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

31 files changed:
ChangeLog
LayoutTests/ChangeLog
LayoutTests/platform/gtk-wk1/TestExpectations
LayoutTests/platform/gtk-wk2/TestExpectations
LayoutTests/platform/gtk/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/PlatformGTK.cmake
Source/WebCore/bindings/gobject/GNUmakefile.am
Source/WebCore/bindings/gobject/webkitdom.symbols
Source/WebCore/platform/gtk/GtkTouchContextHelper.cpp [new file with mode: 0644]
Source/WebCore/platform/gtk/GtkTouchContextHelper.h [new file with mode: 0644]
Source/WebKit/gtk/ChangeLog
Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
Source/WebKit2/ChangeLog
Source/WebKit2/GNUmakefile.list.am
Source/WebKit2/PlatformGTK.cmake
Source/WebKit2/Shared/NativeWebTouchEvent.h
Source/WebKit2/Shared/gtk/NativeWebTouchEventGtk.cpp [new file with mode: 0644]
Source/WebKit2/Shared/gtk/WebEventFactory.cpp
Source/WebKit2/Shared/gtk/WebEventFactory.h
Source/WebKit2/UIProcess/API/gtk/PageClientImpl.cpp
Source/WebKit2/UIProcess/API/gtk/PageClientImpl.h
Source/WebKit2/UIProcess/API/gtk/WebKitWebViewBase.cpp
Source/autotools/SetupWebKitFeatures.m4
Source/cmake/OptionsGTK.cmake
Tools/ChangeLog
Tools/DumpRenderTree/gtk/EventSender.cpp
Tools/Scripts/webkitperl/FeatureList.pm
Tools/WebKitTestRunner/EventSenderProxy.h
Tools/WebKitTestRunner/gtk/EventSenderProxyGtk.cpp

index 9c15f9a..25d0034 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-02-09  Carlos Garnacho  <carlosg@gnome.org>
+
+        [GTK] Enable touch features
+        https://bugs.webkit.org/show_bug.cgi?id=98931
+
+        Reviewed by Carlos Garcia Campos.
+
+        * Source/autotools/SetupWebKitFeatures.m4:
+        * Source/cmake/OptionsGTK.cmake: set ENABLE_TOUCH_EVENTS to 1 if building with GTK+.
+
 2014-02-06  Andreas Kling  <akling@apple.com>
 
         Remove unused ENABLE(REPAINT_THROTTLING) flag.
index c00e0ed..8442a87 100644 (file)
@@ -1,3 +1,14 @@
+2014-02-09  Carlos Garnacho  <carlosg@gnome.org>
+
+        [GTK] Enable touch features
+        https://bugs.webkit.org/show_bug.cgi?id=98931
+
+        Reviewed by Carlos Garcia Campos.
+
+        * platform/gtk/TestExpectations: remove fast/events/touch
+        * platform/gtk-wk2/TestExpectations: Add new expectations on
+        fast/events/touch events.
+
 2014-02-08  Brady Eidson  <beidson@apple.com>
 
         IDB: storage/indexeddb/mozilla/object-cursors.html fails
index 8977b05..f0d278d 100644 (file)
@@ -257,6 +257,9 @@ webkit.org/b/35300 http/tests/loading/307-after-303-after-post.html [ Failure ]
 # Needs custom policy delegate enhancement to log downloads
 Bug(GTK) http/tests/download [ Failure ]
 
+# Touch support only implemented in WK2
+fast/events/touch [ Skip ]
+
 #////////////////////////////////////////////////////////////////////////////////////////
 # End of Tests failing
 #////////////////////////////////////////////////////////////////////////////////////////
index c440355..3c159a3 100644 (file)
@@ -186,6 +186,23 @@ webkit.org/b/85463 editing/inserting/smart-link-when-caret-is-moved-before-URL.h
 webkit.org/b/120401 fast/events [ Skip ]
 webkit.org/b/120401 editing/selection [ Skip ]
 
+# Tests in the gesture folder exercise IOS-specific code, non appliable to GTK+
+fast/events/touch/gesture [ Skip ]
+
+# These tests rely on touch event grouping, which X11/GTK+ doesn't do by design
+webkit.org/b/128172 fast/events/touch/basic-multi-touch-events-limited.html [ Failure ]
+webkit.org/b/128172 fast/events/touch/basic-multi-touch-events.html [ Failure ]
+webkit.org/b/128172 fast/events/touch/touch-input-element-change-documents.html [ Failure ]
+webkit.org/b/128172 fast/events/touch/frame-hover-update.html [ Failure ]
+webkit.org/b/128172 fast/events/touch/multi-touch-grouped-targets.html [ Timeout Failure ]
+webkit.org/b/128172 fast/events/touch/multi-touch-inside-nested-iframes.html [ Timeout ]
+webkit.org/b/128172 fast/events/touch/multi-touch-inside-iframes.html [ Timeout ]
+webkit.org/b/128172 fast/events/touch/basic-single-touch-events.html [ Timeout ]
+webkit.org/b/128172 fast/events/touch/page-scaled-touch-gesture-click.html [ Timeout ]
+webkit.org/b/128172 fast/events/touch/touch-target.html [ Timeout ]
+webkit.org/b/128172 fast/events/touch/touch-target-limited.html [ Timeout ]
+webkit.org/b/128172 fast/events/touch/send-oncancel-event.html [ Timeout ]
+
 #////////////////////////////////////////////////////////////////////////////////////////
 # End of Expected failures
 #////////////////////////////////////////////////////////////////////////////////////////
index 919b600..1f420f0 100644 (file)
@@ -153,9 +153,6 @@ webkit.org/b/98927 fast/dom/DeviceOrientation [ Skip ]
 webkit.org/b/61140 fast/notifications [ Skip ]
 webkit.org/b/61140 http/tests/notifications [ Skip ]
 
-# These tests require touch support.
-webkit.org/b/98931 fast/events/touch [ Skip ]
-
 # StorageTracker is not enabled.
 webkit.org/b/98933 storage/domstorage/localstorage/storagetracker [ Skip ]
 
index 7710dfb..63aeacd 100644 (file)
@@ -1,3 +1,21 @@
+2014-02-09  Carlos Garnacho  <carlosg@gnome.org>
+
+        [GTK] Add touch-events related code to build
+        https://bugs.webkit.org/show_bug.cgi?id=98931
+
+        Reviewed by Carlos Garcia Campos.
+
+        Tests in fast/events/touch have been enabled on GTK+ now that touch
+        support is implemented, and thus all expected bits are there.
+
+        * platform/gtk/GtkTouchContextHelper.cpp:
+        * platform/gtk/GtkTouchContextHelper.h: Add helper object to track all touchpoints, handy
+        when creating WebTouchEvents.
+        * GNUmakefile.list.am:
+        * PlatformGTK.cmake:
+        * bindings/gobject/GNUmakefile.am: Add touch related code and idls to build, those are
+        necessary now that GTK+ implements touch events.
+
 2014-02-09  Zan Dobersek  <zdobersek@igalia.com>
 
         Switch the rest of CSS code from OwnPtr over to std::unique_ptr
index b7cbf84..88adc6f 100644 (file)
@@ -2997,8 +2997,11 @@ webcore_sources += \
        Source/WebCore/dom/TextNodeTraversal.cpp \
        Source/WebCore/dom/TextNodeTraversal.h \
        Source/WebCore/dom/Text.h \
+       Source/WebCore/dom/Touch.cpp \
        Source/WebCore/dom/Touch.h \
+       Source/WebCore/dom/TouchEvent.cpp \
        Source/WebCore/dom/TouchEvent.h \
+       Source/WebCore/dom/TouchList.cpp \
        Source/WebCore/dom/TouchList.h \
        Source/WebCore/dom/TransformSource.h \
        Source/WebCore/dom/TransformSourceLibxslt.cpp \
@@ -6178,6 +6181,8 @@ platformgtk_sources += \
        Source/WebCore/platform/gtk/GtkInputMethodFilter.h \
        Source/WebCore/platform/gtk/GtkPopupMenu.cpp \
        Source/WebCore/platform/gtk/GtkPopupMenu.h \
+       Source/WebCore/platform/gtk/GtkTouchContextHelper.cpp \
+       Source/WebCore/platform/gtk/GtkTouchContextHelper.h \
        Source/WebCore/platform/gtk/GtkUtilities.cpp \
        Source/WebCore/platform/gtk/GtkUtilities.h \
        Source/WebCore/platform/gtk/GtkVersioning.c \
index 6bdbf87..947815e 100644 (file)
@@ -202,6 +202,7 @@ list(APPEND WebCorePlatformGTK_SOURCES
     platform/gtk/GtkInputMethodFilter.cpp
     platform/gtk/GtkPluginWidget.cpp
     platform/gtk/GtkPopupMenu.cpp
+    platform/gtk/GtkTouchContextHelper.cpp
     platform/gtk/GtkUtilities.cpp
     platform/gtk/GtkVersioning.c
     platform/gtk/KeyBindingTranslator.cpp
@@ -529,6 +530,7 @@ if (ENABLE_WEBKIT2)
         dom/Range.idl
         dom/ShadowRoot.idl
         dom/Text.idl
+        dom/Touch.idl
         dom/TreeWalker.idl
         dom/UIEvent.idl
         dom/WebKitNamedFlow.idl
index be5e2a5..68cdbe5 100644 (file)
@@ -262,6 +262,8 @@ webkitgtk_gdom_built_sources += \
        DerivedSources/webkitdom/WebKitDOMStyleSheetPrivate.h \
        DerivedSources/webkitdom/WebKitDOMText.cpp \
        DerivedSources/webkitdom/WebKitDOMTextPrivate.h \
+       DerivedSources/webkitdom/WebKitDOMTouch.cpp \
+       DerivedSources/webkitdom/WebKitDOMTouchPrivate.h \
        DerivedSources/webkitdom/WebKitDOMTimeRanges.cpp \
        DerivedSources/webkitdom/WebKitDOMTimeRangesPrivate.h \
        DerivedSources/webkitdom/WebKitDOMTreeWalker.cpp \
@@ -323,6 +325,7 @@ webkitgtk_gdom_built_h_api += \
        DerivedSources/webkitdom/WebKitDOMProcessingInstruction.h \
        DerivedSources/webkitdom/WebKitDOMRange.h \
        DerivedSources/webkitdom/WebKitDOMText.h \
+       DerivedSources/webkitdom/WebKitDOMTouch.h \
        DerivedSources/webkitdom/WebKitDOMTreeWalker.h \
        DerivedSources/webkitdom/WebKitDOMUIEvent.h \
        DerivedSources/webkitdom/WebKitDOMBlob.h \
index 9e2bd5b..2e54c2a 100644 (file)
@@ -104,6 +104,7 @@ WebKitDOMTreeWalker* webkit_dom_document_create_tree_walker(WebKitDOMDocument*,
 WebKitDOMCSSStyleDeclaration* webkit_dom_document_get_override_style(WebKitDOMDocument*, WebKitDOMElement*, const gchar*)
 WebKitDOMXPathExpression* webkit_dom_document_create_expression(WebKitDOMDocument*, const gchar*, WebKitDOMXPathNSResolver*, GError**)
 WebKitDOMXPathNSResolver* webkit_dom_document_create_ns_resolver(WebKitDOMDocument*, WebKitDOMNode*)
+WebKitDOMTouch* webkit_dom_document_create_touch(WebKitDOMDocument*, WebKitDOMDOMWindow*, WebKitDOMEventTarget*, glong, glong, glong, glong, glong, glong, glong, gfloat, gfloat, GError**)
 WebKitDOMXPathResult* webkit_dom_document_evaluate(WebKitDOMDocument*, const gchar*, WebKitDOMNode*, WebKitDOMXPathNSResolver*, gushort, WebKitDOMXPathResult*, GError**)
 gboolean webkit_dom_document_exec_command(WebKitDOMDocument*, const gchar*, gboolean, const gchar*)
 gboolean webkit_dom_document_query_command_enabled(WebKitDOMDocument*, const gchar*)
@@ -1662,6 +1663,18 @@ glong webkit_dom_wheel_event_get_wheel_delta_x(WebKitDOMWheelEvent*)
 glong webkit_dom_wheel_event_get_wheel_delta_y(WebKitDOMWheelEvent*)
 glong webkit_dom_wheel_event_get_wheel_delta(WebKitDOMWheelEvent*)
 gboolean webkit_dom_wheel_event_get_webkit_direction_inverted_from_device(WebKitDOMWheelEvent*)
+WebKitDOMEventTarget* webkit_dom_touch_get_target(WebKitDOMTouch*)
+gfloat webkit_dom_touch_get_webkit_force(WebKitDOMTouch*)
+gfloat webkit_dom_touch_get_webkit_rotation_angle(WebKitDOMTouch*)
+glong webkit_dom_touch_get_client_x(WebKitDOMTouch*)
+glong webkit_dom_touch_get_client_y(WebKitDOMTouch*)
+glong webkit_dom_touch_get_page_x(WebKitDOMTouch*)
+glong webkit_dom_touch_get_page_y(WebKitDOMTouch*)
+glong webkit_dom_touch_get_screen_x(WebKitDOMTouch*)
+glong webkit_dom_touch_get_screen_y(WebKitDOMTouch*)
+glong webkit_dom_touch_get_webkit_radius_x(WebKitDOMTouch*)
+glong webkit_dom_touch_get_webkit_radius_y(WebKitDOMTouch*)
+gulong webkit_dom_touch_get_identifier(WebKitDOMTouch*)
 gchar* webkit_dom_audio_track_get_id(WebKitDOMAudioTrack*)
 gchar* webkit_dom_audio_track_get_kind(WebKitDOMAudioTrack*)
 gchar* webkit_dom_audio_track_get_label(WebKitDOMAudioTrack*)
diff --git a/Source/WebCore/platform/gtk/GtkTouchContextHelper.cpp b/Source/WebCore/platform/gtk/GtkTouchContextHelper.cpp
new file mode 100644 (file)
index 0000000..0e1bc9b
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2013 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * 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 "GtkTouchContextHelper.h"
+
+#include <gtk/gtk.h>
+
+namespace WebCore {
+
+bool GtkTouchContextHelper::handleEvent(GdkEvent* touchEvent)
+{
+#ifndef GTK_API_VERSION_2
+    uint32_t sequence = GPOINTER_TO_UINT(gdk_event_get_event_sequence(touchEvent));
+
+    switch (touchEvent->type) {
+    case GDK_TOUCH_BEGIN: {
+        ASSERT(m_touchEvents.contains(sequence));
+        GUniquePtr<GdkEvent> event(gdk_event_copy(touchEvent));
+        m_touchEvents.add(sequence, std::move(event));
+        break;
+    }
+    case GDK_TOUCH_UPDATE: {
+        auto it = m_touchEvents.find(sequence);
+        ASSERT(it != m_touchEvents.end());
+        it->value.reset(gdk_event_copy(touchEvent));
+        break;
+    }
+    case GDK_TOUCH_END:
+        ASSERT(m_touchEvents.contains(sequence));
+        m_touchEvents.remove(sequence);
+        break;
+    default:
+        return false;
+    }
+#endif // GTK_API_VERSION_2
+
+    return true;
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/gtk/GtkTouchContextHelper.h b/Source/WebCore/platform/gtk/GtkTouchContextHelper.h
new file mode 100644 (file)
index 0000000..2b285a0
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2013 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * 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.
+ */
+
+#ifndef GtkTouchContextHelper_h
+#define GtkTouchContextHelper_h
+
+#include "GUniquePtrGtk.h"
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+typedef HashMap<uint32_t, GUniquePtr<GdkEvent>> TouchEventsMap;
+
+class GtkTouchContextHelper {
+    WTF_MAKE_NONCOPYABLE(GtkTouchContextHelper);
+public:
+    GtkTouchContextHelper() { };
+    bool handleEvent(GdkEvent*);
+    const TouchEventsMap& touchEvents() const { return m_touchEvents; };
+
+private:
+    TouchEventsMap m_touchEvents;
+};
+
+} // namespace WebCore
+
+#endif
index 5f40de8..45c6fe8 100644 (file)
@@ -1,3 +1,16 @@
+2014-02-09  Carlos Garnacho  <carlosg@gnome.org>
+
+        [GTK] Allow building with touch events enabled
+        https://bugs.webkit.org/show_bug.cgi?id=98931
+
+        Reviewed by Carlos Garcia Campos.
+
+        Even though WebKit1 GTK code doesn't implement touch events,
+        Fix build if ENABLE_TOUCH_EVENTS is present for WK2.
+
+        * WebCoreSupport/ChromeClientGtk.h:
+        (WebKit::ChromeClient::needTouchEvents): Add empty stub
+
 2014-02-08  Ryosuke Niwa  <rniwa@webkit.org>
 
         Cleanup the interface of FrameSelection
index cb0382e..9790fcd 100644 (file)
@@ -141,6 +141,7 @@ namespace WebKit {
 #endif
 
         virtual void numWheelEventHandlersChanged(unsigned) { }
+        virtual void needTouchEvents(bool) { }
 
         virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*);
         virtual void setNeedsOneShotDrawingSynchronization();
index 90ef92f..f4c4885 100644 (file)
@@ -1,3 +1,37 @@
+2014-02-09  Carlos Garnacho  <carlosg@gnome.org>
+
+        [GTK] Implement support touch events
+        https://bugs.webkit.org/show_bug.cgi?id=98931
+
+        Reviewed by Carlos Garcia Campos.
+
+        In GTK+ >= 3.4.0, GdkEventTouch is available to inform about multitouch events. Use these to implement
+        touch events on this platform. If a touch is left unhandled and is the "pointer emulating" one, mouse
+        events will be generated as a fallback.
+
+        * GNUmakefile.list.am:
+        * PlatformGTK.cmake:
+        * Shared/gtk/NativeWebTouchEventGtk.cpp:
+        * Shared/NativeWebTouchEvent.h:
+        (WebKit::NativeWebTouchEvent::nativeEvent):
+        (WebKit::NativeWebTouchEvent::touchContext): Add GTK+ implementation of NativeWebTouchEvent.
+        * Shared/gtk/WebEventFactory.cpp:
+        (WebKit::touchPhaseFromEvents):
+        (WebKit::WebEventFactory::createWebTouchEvent): Add methods to generate WebTouchEvents out
+        of GdkEventTouch events, a GtkTouchContextHelper object is used to hold information about all current
+        touches, in order to build information about all individual touchpoints.
+        * Shared/gtk/WebEventFactory.h:
+        * UIProcess/API/gtk/PageClientImpl.cpp:
+        (WebKit::PageClientImpl::doneWithTouchEvent): Implement pointer emulation. If a touch event was unhandled
+        in DOM and pertains to the touch sequence that emulates pointer events. The event gets transformed to its
+        mouse event counterpart and handled by the widget again.
+        * UIProcess/API/gtk/PageClientImpl.h:
+        * UIProcess/API/gtk/WebKitWebViewBase.cpp:
+        (webkitWebViewBaseRealize): Listen for touch events
+        (webkitWebViewBaseTouchEvent):
+        (webkit_web_view_base_class_init): Add implementation for the touch_events() handler, this merely
+        lets the pageProxy handle the NativeWebTouchEvent we create to wrap the GdkEvent received.
+
 2014-02-09  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r162768.
index 15eded3..38ece7b 100644 (file)
@@ -384,6 +384,7 @@ webkit2_sources += \
        Source/WebKit2/Shared/gtk/LayerTreeContextGtk.cpp \
        Source/WebKit2/Shared/gtk/NativeWebKeyboardEventGtk.cpp \
        Source/WebKit2/Shared/gtk/NativeWebMouseEventGtk.cpp \
+       Source/WebKit2/Shared/gtk/NativeWebTouchEventGtk.cpp \
        Source/WebKit2/Shared/gtk/NativeWebWheelEventGtk.cpp \
        Source/WebKit2/Shared/gtk/PrintInfoGtk.cpp \
        Source/WebKit2/Shared/gtk/ProcessExecutablePathGtk.cpp \
index 4a84a92..8442dd5 100644 (file)
@@ -56,6 +56,7 @@ list(APPEND WebKit2_SOURCES
     Shared/gtk/LayerTreeContextGtk.cpp
     Shared/gtk/NativeWebKeyboardEventGtk.cpp
     Shared/gtk/NativeWebMouseEventGtk.cpp
+    Shared/gtk/NativeWebTouchEventGtk.cpp
     Shared/gtk/NativeWebWheelEventGtk.cpp
     Shared/gtk/PrintInfoGtk.cpp
     Shared/gtk/ProcessExecutablePathGtk.cpp
@@ -565,6 +566,8 @@ if (ENABLE_PLUGIN_PROCESS)
         Shared/WebKeyboardEvent.cpp
         Shared/WebKit2Initialize.cpp
         Shared/WebMouseEvent.cpp
+        Shared/WebPlatformTouchPoint.cpp
+        Shared/WebTouchEvent.cpp
         Shared/WebWheelEvent.cpp
 
         Shared/Plugins/NPIdentifierData.cpp
@@ -583,6 +586,7 @@ if (ENABLE_PLUGIN_PROCESS)
 
         Shared/gtk/NativeWebKeyboardEventGtk.cpp
         Shared/gtk/NativeWebMouseEventGtk.cpp
+        Shared/gtk/NativeWebTouchEventGtk.cpp
         Shared/gtk/NativeWebWheelEventGtk.cpp
         Shared/gtk/ProcessExecutablePathGtk.cpp
         Shared/gtk/WebEventFactory.cpp
index 0d4b2cf..ef5bf65 100644 (file)
 #if PLATFORM(IOS)
 #include <wtf/RetainPtr.h>
 OBJC_CLASS UIWebTouchEventsGestureRecognizer;
-#endif // PLATFORM(IOS)
-
-#if PLATFORM(EFL)
+#elif PLATFORM(GTK)
+#include <WebCore/GUniquePtrGtk.h>
+#include <WebCore/GtkTouchContextHelper.h>
+#elif PLATFORM(EFL)
 #include "EwkTouchEvent.h"
 #include <WebCore/AffineTransform.h>
 #include <wtf/RefPtr.h>
@@ -46,8 +47,12 @@ public:
 #if PLATFORM(IOS)
     explicit NativeWebTouchEvent(UIWebTouchEventsGestureRecognizer *);
     const UIWebTouchEventsGestureRecognizer* nativeEvent() const { return m_nativeEvent.get(); }
-#endif
-#if PLATFORM(EFL)
+#elif PLATFORM(GTK)
+    NativeWebTouchEvent(const NativeWebTouchEvent&);
+    NativeWebTouchEvent(GdkEvent*, WebCore::GtkTouchContextHelper&);
+    const GdkEvent* nativeEvent() const { return m_nativeEvent.get(); }
+    const WebCore::GtkTouchContextHelper& touchContext() const { return m_touchContext; }
+#elif PLATFORM(EFL)
     NativeWebTouchEvent(EwkTouchEvent*, const WebCore::AffineTransform&);
     const EwkTouchEvent* nativeEvent() const { return m_nativeEvent.get(); }
 #endif
@@ -55,8 +60,10 @@ public:
 private:
 #if PLATFORM(IOS)
     RetainPtr<UIWebTouchEventsGestureRecognizer> m_nativeEvent;
-#endif
-#if PLATFORM(EFL)
+#elif PLATFORM(GTK)
+    GUniquePtr<GdkEvent> m_nativeEvent;
+    const WebCore::GtkTouchContextHelper& m_touchContext;
+#elif PLATFORM(EFL)
     RefPtr<EwkTouchEvent> m_nativeEvent;
 #endif
 };
diff --git a/Source/WebKit2/Shared/gtk/NativeWebTouchEventGtk.cpp b/Source/WebKit2/Shared/gtk/NativeWebTouchEventGtk.cpp
new file mode 100644 (file)
index 0000000..b2cd4a5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2013 Carlos Garnacho <carlosg@gnome.org>
+ *
+ * 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 "NativeWebTouchEvent.h"
+
+#include "WebEventFactory.h"
+#include <gdk/gdk.h>
+
+namespace WebKit {
+
+NativeWebTouchEvent::NativeWebTouchEvent(GdkEvent* event, WebCore::GtkTouchContextHelper& context)
+    : WebTouchEvent(WebEventFactory::createWebTouchEvent(event, context))
+    , m_nativeEvent(gdk_event_copy(event))
+    , m_touchContext(context)
+{
+}
+
+NativeWebTouchEvent::NativeWebTouchEvent(const NativeWebTouchEvent& event)
+    : WebTouchEvent(WebEventFactory::createWebTouchEvent(event.nativeEvent(), event.touchContext()))
+    , m_nativeEvent(gdk_event_copy(event.nativeEvent()))
+    , m_touchContext(event.touchContext())
+{
+}
+
+} // namespace WebKit
index cb88a82..462b11b 100644 (file)
@@ -34,6 +34,7 @@
 #include <WebCore/GtkVersioning.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
 #include <wtf/ASCIICType.h>
 
 using namespace WebCore;
@@ -203,4 +204,75 @@ WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(const GdkEvent* event,
                             gdk_event_get_time(event));
 }
 
+#ifndef GTK_API_VERSION_2
+static WebPlatformTouchPoint::TouchPointState touchPhaseFromEvents(const GdkEvent* current, const GdkEvent* event)
+{
+    if (gdk_event_get_event_sequence(current) != gdk_event_get_event_sequence(event))
+        return WebPlatformTouchPoint::TouchStationary;
+
+    switch (current->type) {
+    case GDK_TOUCH_UPDATE:
+        return WebPlatformTouchPoint::TouchMoved;
+    case GDK_TOUCH_BEGIN:
+        return WebPlatformTouchPoint::TouchPressed;
+    case GDK_TOUCH_END:
+        return WebPlatformTouchPoint::TouchReleased;
+    default:
+        return WebPlatformTouchPoint::TouchStationary;
+    }
+}
+
+static void appendTouchEvent(Vector<WebPlatformTouchPoint>& touchPointList, const GdkEvent* event, WebPlatformTouchPoint::TouchPointState state)
+{
+    uint32_t identifier = GPOINTER_TO_UINT(gdk_event_get_event_sequence(event));
+
+    gdouble x, y;
+    gdk_event_get_coords(event, &x, &y);
+
+    gdouble xRoot, yRoot;
+    gdk_event_get_root_coords(event, &xRoot, &yRoot);
+
+    WebPlatformTouchPoint touchPoint(identifier, state, IntPoint(xRoot, yRoot), IntPoint(x, y));
+    touchPointList.uncheckedAppend(touchPoint);
+}
+#endif // GTK_API_VERSION_2
+
+WebTouchEvent WebEventFactory::createWebTouchEvent(const GdkEvent* event, const WebCore::GtkTouchContextHelper& touchContext)
+{
+#ifndef GTK_API_VERSION_2
+    WebEvent::Type type = WebEvent::NoType;
+    const auto& touchEvents = touchContext.touchEvents();
+    int numEvents = touchEvents.size();
+
+    switch (event->type) {
+    case GDK_TOUCH_BEGIN:
+        type = WebEvent::TouchStart;
+        break;
+    case GDK_TOUCH_UPDATE:
+        type = WebEvent::TouchMove;
+        break;
+    case GDK_TOUCH_END:
+        type = WebEvent::TouchEnd;
+        ++numEvents;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    Vector<WebPlatformTouchPoint> touchPointList;
+    touchPointList.reserveInitialCapacity(numEvents);
+
+    for (auto it = touchEvents.begin(); it != touchEvents.end(); ++it)
+        appendTouchEvent(touchPointList, it->value.get(), touchPhaseFromEvents(it->value.get(), event));
+
+    // Touch was already removed from the GtkTouchContextHelper, add it here.
+    if (event->type == GDK_TOUCH_END)
+        appendTouchEvent(touchPointList, event, WebPlatformTouchPoint::TouchReleased);
+
+    return WebTouchEvent(type, touchPointList, modifiersForEvent(event), gdk_event_get_time(event));
+#else
+    return WebTouchEvent();
+#endif // GTK_API_VERSION_2
+}
+
 } // namespace WebKit
index 085815c..fc30296 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "WebEvent.h"
 #include <WebCore/CompositionResults.h>
+#include <WebCore/GtkTouchContextHelper.h>
 
 typedef union _GdkEvent GdkEvent;
 
@@ -39,6 +40,7 @@ public:
     static WebMouseEvent createWebMouseEvent(const GdkEvent*, int);
     static WebWheelEvent createWebWheelEvent(const GdkEvent*);
     static WebKeyboardEvent createWebKeyboardEvent(const GdkEvent*, const WebCore::CompositionResults&);
+    static WebTouchEvent createWebTouchEvent(const GdkEvent*, const WebCore::GtkTouchContextHelper&);
 };
 
 } // namespace WebKit
index 4b7da1d..3d07d8d 100644 (file)
@@ -327,4 +327,54 @@ void PageClientImpl::beganExitFullScreen(const IntRect& initialFrame, const IntR
 
 #endif // ENABLE(FULLSCREEN_API)
 
+void PageClientImpl::doneWithTouchEvent(const NativeWebTouchEvent& event, bool wasEventHandled)
+{
+    if (wasEventHandled)
+        return;
+
+    // Emulate pointer events if unhandled.
+    const GdkEvent* touchEvent = event.nativeEvent();
+
+    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_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());
+}
+
 } // namespace WebKit
index 963c2ce..0d63e3b 100644 (file)
@@ -119,6 +119,8 @@ private:
     virtual void beganExitFullScreen(const WebCore::IntRect& initialFrame, const WebCore::IntRect& finalFrame) override;
 #endif
 
+    virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) override;
+
     // Members of PageClientImpl class
     GtkWidget* m_viewWidget;
     DefaultUndoController m_undoController;
index 9b96f0d..9e54361 100644 (file)
@@ -53,6 +53,7 @@
 #include <WebCore/GUniquePtrGtk.h>
 #include <WebCore/GtkClickCounter.h>
 #include <WebCore/GtkDragAndDropHelper.h>
+#include <WebCore/GtkTouchContextHelper.h>
 #include <WebCore/GtkUtilities.h>
 #include <WebCore/GtkVersioning.h>
 #include <WebCore/NotImplemented.h>
@@ -110,6 +111,7 @@ struct _WebKitWebViewBasePrivate {
     GUniquePtr<GdkEvent> contextMenuEvent;
     WebContextMenuProxyGtk* activeContextMenuProxy;
     WebViewBaseInputMethodFilter inputMethodFilter;
+    GtkTouchContextHelper touchContext;
 
     GtkWindow* toplevelOnScreenWindow;
     unsigned long toplevelResizeGripVisibilityID;
@@ -272,7 +274,8 @@ static void webkitWebViewBaseRealize(GtkWidget* widget)
         | GDK_BUTTON_MOTION_MASK
         | GDK_BUTTON1_MOTION_MASK
         | GDK_BUTTON2_MOTION_MASK
-        | GDK_BUTTON3_MOTION_MASK;
+        | GDK_BUTTON3_MOTION_MASK
+        | GDK_TOUCH_MASK;
 
     gint attributesMask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
@@ -712,6 +715,19 @@ static gboolean webkitWebViewBaseMotionNotifyEvent(GtkWidget* widget, GdkEventMo
     return TRUE;
 }
 
+static gboolean webkitWebViewBaseTouchEvent(GtkWidget* widget, GdkEventTouch* event)
+{
+    WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
+
+    if (priv->authenticationDialog)
+        return TRUE;
+
+    priv->touchContext.handleEvent(reinterpret_cast<GdkEvent*>(event));
+    priv->pageProxy->handleTouchEvent(NativeWebTouchEvent(reinterpret_cast<GdkEvent*>(event), priv->touchContext));
+
+    return TRUE;
+}
+
 static gboolean webkitWebViewBaseQueryTooltip(GtkWidget* widget, gint x, gint y, gboolean keyboardMode, GtkTooltip* tooltip)
 {
     WebKitWebViewBasePrivate* priv = WEBKIT_WEB_VIEW_BASE(widget)->priv;
@@ -896,6 +912,7 @@ static void webkit_web_view_base_class_init(WebKitWebViewBaseClass* webkitWebVie
     widgetClass->button_release_event = webkitWebViewBaseButtonReleaseEvent;
     widgetClass->scroll_event = webkitWebViewBaseScrollEvent;
     widgetClass->motion_notify_event = webkitWebViewBaseMotionNotifyEvent;
+    widgetClass->touch_event = webkitWebViewBaseTouchEvent;
     widgetClass->query_tooltip = webkitWebViewBaseQueryTooltip;
 #if ENABLE(DRAG_SUPPORT)
     widgetClass->drag_end = webkitWebViewBaseDragEnd;
index 5daf7b9..d30738e 100644 (file)
@@ -159,7 +159,7 @@ $srcdir/Tools/gtk/generate-feature-defines-files $CONFIGURABLE_FEATURE_DEFINES \
     ENABLE_TEMPLATE_ELEMENT=1 \
     ENABLE_SATURATED_LAYOUT_ARITHMETIC=1\
     ENABLE_TEXT_AUTOSIZING=0 \
-    ENABLE_TOUCH_EVENTS=0 \
+    ENABLE_TOUCH_EVENTS=1 \
     ENABLE_TOUCH_ICON_LOADING=0 \
     ENABLE_USER_TIMING=0 \
     ENABLE_VIBRATION=0 \
index 27af146..b1c2cad 100644 (file)
@@ -66,7 +66,7 @@ WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHADOW_DOM OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SHARED_WORKERS ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_SPELLCHECK ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TEMPLATE_ELEMENT ON)
-WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS OFF)
+WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_TOUCH_EVENTS ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_USERSELECT_ALL ON)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIBRATION OFF)
 WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_VIDEO ON)
index 37c3d7b..9f650e2 100644 (file)
@@ -1,3 +1,20 @@
+2014-02-09  Carlos Garnacho  <carlosg@gnome.org>
+
+        [GTK] Enable touch features
+        https://bugs.webkit.org/show_bug.cgi?id=98931
+
+        Reviewed by Carlos Garcia Campos.
+
+        * WebKitTestRunner/EventSenderProxy.h:
+        * WebKitTestRunner/gtk/EventSenderProxyGtk.cpp:
+        (WTR::updateEventCoordinates):
+        (WTR::EventSenderProxy::createTouchEvent):
+        (WTR::EventSenderProxy::addTouchPoint):
+        (WTR::EventSenderProxy::updateTouchPoint):
+        (WTR::EventSenderProxy::sendUpdatedTouchEvents):
+        (WTR::EventSenderProxy::setTouchPointRadius):
+        (WTR::EventSenderProxy::setTouchModifier): Implement touch event proxying.
+
 2014-02-08  Andreas Kling  <akling@apple.com>
 
         Let Instruments time profiler run until tests finish.
index 5826027..c0cb452 100644 (file)
@@ -912,6 +912,11 @@ static JSValueRef scheduleAsynchronousKeyDownCallback(JSContextRef context, JSOb
     return JSValueMakeUndefined(context);
 }
 
+static JSValueRef clearTouchPointsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    return JSValueMakeUndefined(context);
+}
+
 static JSStaticFunction staticFunctions[] = {
     { "mouseScrollBy", mouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
     { "continuousMouseScrollBy", continuousMouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
index 5b62646..531037f 100644 (file)
@@ -426,7 +426,7 @@ my @features = (
       define => "WTF_USE_TILED_BACKING_STORE", default => isEfl(), value => \$tiledBackingStoreSupport },
 
     { option => "touch-events", desc => "Toggle Touch Events support",
-      define => "ENABLE_TOUCH_EVENTS", default => (isIOSWebKit() || isEfl()), value => \$touchEventsSupport },
+      define => "ENABLE_TOUCH_EVENTS", default => (isIOSWebKit() || isEfl() || isGtk()), value => \$touchEventsSupport },
 
     { option => "touch-slider", desc => "Toggle Touch Slider support",
       define => "ENABLE_TOUCH_SLIDER", default => 0, value => \$touchSliderSupport },
index 5d3a048..db2c58b 100644 (file)
 #define EventSenderProxy_h
 
 #include <wtf/Deque.h>
+#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
 
 #if PLATFORM(GTK)
+#include <WebCore/GUniquePtrGtk.h>
 #include <gdk/gdk.h>
+#include <wtf/HashSet.h>
 #elif PLATFORM(EFL)
 #include <WebKit2/EWebKit2.h>
 #endif
@@ -90,6 +94,8 @@ private:
 #if PLATFORM(GTK)
     void sendOrQueueEvent(GdkEvent*);
     GdkEvent* createMouseButtonEvent(GdkEventType, unsigned button, WKEventModifiers);
+    GUniquePtr<GdkEvent> createTouchEvent(GdkEventType, int id);
+    void sendUpdatedTouchEvents();
 #elif PLATFORM(EFL)
     void sendOrQueueEvent(const WTREvent&);
     void dispatchEvent(const WTREvent&);
@@ -110,6 +116,8 @@ private:
 #elif PLATFORM(GTK)
     Deque<WTREventQueueItem> m_eventQueue;
     unsigned m_mouseButtonCurrentlyDown;
+    Vector<GUniquePtr<GdkEvent>> m_touchEvents;
+    HashSet<int> m_updatedTouchEvents;
 #elif PLATFORM(EFL)
     Deque<WTREvent> m_eventQueue;
     WKEventMouseButton m_mouseButton;
index 40f659e..96d3b9f 100644 (file)
@@ -33,6 +33,7 @@
 #include "config.h"
 #include "EventSenderProxy.h"
 
+#include "NotImplemented.h"
 #include "PlatformWebView.h"
 #include "TestController.h"
 #include <gdk/gdkkeysyms.h>
@@ -441,4 +442,120 @@ void EventSenderProxy::leapForward(int milliseconds)
     m_time += milliseconds / 1000.0;
 }
 
+void updateEventCoordinates(GdkEvent* touchEvent, int x, int y)
+{
+    touchEvent->touch.x = x;
+    touchEvent->touch.y = y;
+
+    int xRoot, yRoot;
+    gdk_window_get_root_coords(touchEvent->touch.window, x, y, &xRoot, &yRoot);
+    touchEvent->touch.x_root = xRoot;
+    touchEvent->touch.y_root = yRoot;
+}
+
+GUniquePtr<GdkEvent> EventSenderProxy::createTouchEvent(GdkEventType eventType, int id)
+{
+    GUniquePtr<GdkEvent> touchEvent(gdk_event_new(eventType));
+
+    touchEvent->touch.sequence = static_cast<GdkEventSequence*>(GINT_TO_POINTER(id));
+    touchEvent->touch.window = gtk_widget_get_window(GTK_WIDGET(m_testController->mainWebView()->platformView()));
+    g_object_ref(touchEvent->touch.window);
+    gdk_event_set_device(touchEvent.get(), gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_window_get_display(touchEvent->button.window))));
+    touchEvent->touch.time = GDK_CURRENT_TIME;
+
+    return touchEvent;
+}
+
+void EventSenderProxy::addTouchPoint(int x, int y)
+{
+    // Touch ID is array index plus one, so 0 is skipped.
+    GUniquePtr<GdkEvent> event = createTouchEvent(static_cast<GdkEventType>(GDK_TOUCH_BEGIN), m_touchEvents.size() + 1);
+    updateEventCoordinates(event.get(), x, y);
+    m_touchEvents.append(std::move(event));
+    m_updatedTouchEvents.add(GPOINTER_TO_INT(event->touch.sequence));
+}
+
+void EventSenderProxy::updateTouchPoint(int index, int x, int y)
+{
+    ASSERT(index >= 0 && index < m_touchEvents.size());
+
+    const auto& event = m_touchEvents[index];
+    ASSERT(event);
+
+    event->type = GDK_TOUCH_UPDATE;
+    updateEventCoordinates(event.get(), x, y);
+    m_updatedTouchEvents.add(GPOINTER_TO_INT(event->touch.sequence));
+}
+
+void EventSenderProxy::sendUpdatedTouchEvents()
+{
+    for (auto id : m_updatedTouchEvents)
+        sendOrQueueEvent(gdk_event_copy(m_touchEvents[id - 1].get()));
+
+    m_updatedTouchEvents.clear();
+}
+
+void EventSenderProxy::touchStart()
+{
+    sendUpdatedTouchEvents();
+}
+
+void EventSenderProxy::touchMove()
+{
+    sendUpdatedTouchEvents();
+}
+
+void EventSenderProxy::touchEnd()
+{
+    sendUpdatedTouchEvents();
+}
+
+void EventSenderProxy::touchCancel()
+{
+    notImplemented();
+}
+
+void EventSenderProxy::clearTouchPoints()
+{
+    m_updatedTouchEvents.clear();
+    m_touchEvents.clear();
+}
+
+void EventSenderProxy::releaseTouchPoint(int index)
+{
+    ASSERT(index >= 0 && index < m_touchEvents.size());
+
+    const auto& event = m_touchEvents[index];
+    event->type = GDK_TOUCH_END;
+    m_updatedTouchEvents.add(GPOINTER_TO_INT(event->touch.sequence));
+}
+
+void EventSenderProxy::cancelTouchPoint(int index)
+{
+    notImplemented();
+}
+
+void EventSenderProxy::setTouchPointRadius(int radiusX, int radiusY)
+{
+    notImplemented();
+}
+
+void EventSenderProxy::setTouchModifier(WKEventModifiers modifier, bool enable)
+{
+    guint state = webkitModifiersToGDKModifiers(modifier);
+
+    for (const auto& event : m_touchEvents) {
+        if (event->type == GDK_TOUCH_END)
+            continue;
+
+        if (enable)
+            event->touch.state |= state;
+        else
+            event->touch.state &= ~(state);
+
+        m_updatedTouchEvents.add(GPOINTER_TO_INT(event->touch.sequence));
+    }
+}
+
+
 } // namespace WTR