summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2017-03-26 13:55:39 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-03-26 18:56:55 +0000
commiteaaf1391d58f17bde794d6c8634e092209898941 (patch)
treeff3702a6509dc9333ffd7515cf078cf69478fcc3
parentfdcba363c7e7e01790ba4b946e4f53f8600d8a20 (diff)
downloadqtwebkit-eaaf1391d58f17bde794d6c8634e092209898941.tar.gz
Import WebKit commit 17e8bfb1ff30314a838b9bf641c112f63a11dba4
Change-Id: Ib6549e44a04300c7b7b07ddc9094b823b37f3183 Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
-rw-r--r--Source/WebCore/PlatformQt.cmake6
-rw-r--r--Source/WebCore/dom/Node.cpp23
-rw-r--r--Source/WebCore/dom/Node.h7
-rw-r--r--Source/WebCore/dom/qt/GestureEvent.cpp67
-rw-r--r--Source/WebCore/dom/qt/GestureEvent.h57
-rw-r--r--Source/WebCore/page/EventHandler.cpp197
-rw-r--r--Source/WebCore/page/EventHandler.h28
-rw-r--r--Source/WebCore/page/Settings.in5
-rw-r--r--Source/WebCore/page/qt/TouchAdjustment.cpp503
-rw-r--r--Source/WebCore/page/qt/TouchAdjustment.h40
-rw-r--r--Source/WebCore/platform/MainThreadSharedTimer.h4
-rw-r--r--Source/WebCore/platform/PlatformEvent.h6
-rw-r--r--Source/WebCore/platform/Scrollbar.cpp22
-rw-r--r--Source/WebCore/platform/Scrollbar.h8
-rw-r--r--Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h10
-rw-r--r--Source/WebCore/platform/qt/MainThreadSharedTimerQt.cpp4
-rw-r--r--Source/WebCore/platform/qt/PlatformGestureEvent.h60
-rw-r--r--Source/WebCore/platform/qt/WidgetQt.cpp1
-rw-r--r--Source/WebCore/testing/Internals.cpp103
-rw-r--r--Source/WebCore/testing/Internals.h8
-rw-r--r--Source/WebCore/testing/Internals.idl7
-rw-r--r--Source/WebKit/PlatformQt.cmake3
-rw-r--r--Source/WebKit/qt/Api/qwebfullscreenrequest.h3
-rw-r--r--Source/WebKit/qt/Api/qwebhistory.cpp1
-rw-r--r--Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp1
-rw-r--r--Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp4
-rw-r--r--Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h6
-rw-r--r--Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp4
-rw-r--r--Source/WebKit/qt/WebCoreSupport/WebEventConversion.cpp6
-rw-r--r--Source/WebKit/qt/WebCoreSupport/WebEventConversion.h2
-rw-r--r--Source/WebKit/qt/WidgetApi/qwebpage.cpp12
-rw-r--r--Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp1
-rw-r--r--Source/WebKit/qt/tests/qwebhistoryinterface/tst_qwebhistoryinterface.cpp1
-rw-r--r--Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp1
-rw-r--r--Source/WebKit/qt/tests/qwebsecurityorigin/tst_qwebsecurityorigin.cpp1
-rw-r--r--Source/WebKit2/Platform/qt/LoggingQt.cpp2
-rw-r--r--Source/WebKit2/PlatformQt.cmake1
-rw-r--r--Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp1
-rw-r--r--Source/WebKit2/Shared/WebEvent.h30
-rw-r--r--Source/WebKit2/Shared/WebEventConversion.cpp40
-rw-r--r--Source/WebKit2/Shared/WebEventConversion.h12
-rw-r--r--Source/WebKit2/Shared/qt/WebGestureEvent.cpp76
-rw-r--r--Source/WebKit2/UIProcess/PageClient.h7
-rw-r--r--Source/WebKit2/UIProcess/WebPageProxy.cpp29
-rw-r--r--Source/WebKit2/UIProcess/WebPageProxy.h11
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPageClient.cpp2
-rw-r--r--Source/WebKit2/UIProcess/qt/QtPageClient.h2
-rw-r--r--Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp6
-rw-r--r--Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp3
-rw-r--r--Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp22
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp4
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.h4
-rw-r--r--Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in2
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.cpp2
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.h6
-rw-r--r--Source/cmake/OptionsCommon.cmake27
-rw-r--r--Source/cmake/OptionsQt.cmake9
-rw-r--r--Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp1
-rw-r--r--Tools/DumpRenderTree/qt/EventSenderQt.cpp4
-rw-r--r--Tools/MiniBrowser/qt/main.cpp1
-rw-r--r--Tools/QtTestBrowser/CMakeLists.txt4
-rw-r--r--Tools/QtTestBrowser/qttestbrowser.cpp1
-rw-r--r--Tools/Scripts/update-qtwebkit-win-libs2
-rw-r--r--Tools/qmake/mkspecs/features/functions.prf2
-rw-r--r--Tools/qmake/projects/run_cmake.pro2
65 files changed, 1477 insertions, 50 deletions
diff --git a/Source/WebCore/PlatformQt.cmake b/Source/WebCore/PlatformQt.cmake
index 2e649507d..5d2d01cc9 100644
--- a/Source/WebCore/PlatformQt.cmake
+++ b/Source/WebCore/PlatformQt.cmake
@@ -26,7 +26,10 @@ list(APPEND WebCore_INCLUDE_DIRECTORIES
"${THIRDPARTY_DIR}/ANGLE/include/KHR"
"${WEBCORE_DIR}/Modules/gamepad"
"${WEBCORE_DIR}/bridge/qt"
+ "${WEBCORE_DIR}/dom/qt"
+ "${WEBCORE_DIR}/editing/qt"
"${WEBCORE_DIR}/history/qt"
+ "${WEBCORE_DIR}/page/qt"
"${WEBCORE_DIR}/platform/qt"
"${WEBCORE_DIR}/platform/audio/qt"
"${WEBCORE_DIR}/platform/graphics/egl"
@@ -53,10 +56,13 @@ list(APPEND WebCore_SOURCES
bridge/qt/qt_pixmapruntime.cpp
bridge/qt/qt_runtime.cpp
+ dom/qt/GestureEvent.cpp
+
editing/qt/EditorQt.cpp
page/qt/DragControllerQt.cpp
page/qt/EventHandlerQt.cpp
+ page/qt/TouchAdjustment.cpp
platform/KillRingNone.cpp
diff --git a/Source/WebCore/dom/Node.cpp b/Source/WebCore/dom/Node.cpp
index 34495b5c7..be23d49f2 100644
--- a/Source/WebCore/dom/Node.cpp
+++ b/Source/WebCore/dom/Node.cpp
@@ -75,6 +75,10 @@
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
+#if ENABLE(QT_GESTURE_EVENTS)
+#include "GestureEvent.h"
+#endif
+
#if ENABLE(INDIE_UI)
#include "UIRequestEvent.h"
#endif
@@ -2149,6 +2153,25 @@ bool Node::dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEven
return event->defaultHandled();
}
+#if ENABLE(QT_GESTURE_EVENTS)
+bool Node::dispatchGestureEvent(const PlatformGestureEvent& event)
+{
+ RefPtr<GestureEvent> gestureEvent = GestureEvent::create(document().defaultView(), event);
+ if (!gestureEvent.get())
+ return false;
+
+ if (!is<Element>(*this))
+ return false;
+ if (downcast<Element>(*this).isDisabledFormControl())
+ return false;
+
+ EventDispatcher::dispatchEvent(this, *gestureEvent);
+
+ ASSERT(!gestureEvent->defaultPrevented());
+ return gestureEvent->defaultHandled() || gestureEvent->defaultPrevented();
+}
+#endif
+
#if ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)
bool Node::dispatchTouchEvent(TouchEvent& event)
{
diff --git a/Source/WebCore/dom/Node.h b/Source/WebCore/dom/Node.h
index 842bd8775..480655e32 100644
--- a/Source/WebCore/dom/Node.h
+++ b/Source/WebCore/dom/Node.h
@@ -75,6 +75,10 @@ class SVGQualifiedName;
class ShadowRoot;
class TagCollection;
+#if ENABLE(QT_GESTURE_EVENTS)
+class PlatformGestureEvent;
+#endif
+
#if ENABLE(INDIE_UI)
class UIRequestEvent;
#endif
@@ -534,6 +538,9 @@ public:
void dispatchSubtreeModifiedEvent();
bool dispatchDOMActivateEvent(int detail, PassRefPtr<Event> underlyingEvent);
+#if ENABLE(QT_GESTURE_EVENTS)
+ bool dispatchGestureEvent(const PlatformGestureEvent&);
+#endif
#if ENABLE(TOUCH_EVENTS)
virtual bool allowsDoubleTapGesture() const { return true; }
#endif
diff --git a/Source/WebCore/dom/qt/GestureEvent.cpp b/Source/WebCore/dom/qt/GestureEvent.cpp
new file mode 100644
index 000000000..12dddf1cd
--- /dev/null
+++ b/Source/WebCore/dom/qt/GestureEvent.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, INC. OR
+ * 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 "GestureEvent.h"
+
+#if ENABLE(QT_GESTURE_EVENTS)
+
+#include "Element.h"
+#include <wtf/text/AtomicString.h>
+
+namespace WebCore {
+
+RefPtr<GestureEvent> GestureEvent::create(AbstractView* view, const PlatformGestureEvent& event)
+{
+ AtomicString eventType;
+ switch (event.type()) {
+ case PlatformEvent::GestureTap:
+ eventType = eventNames().gesturetapEvent; break;
+ case PlatformEvent::GestureLongPress:
+ default:
+ return 0;
+ }
+ return adoptRef(new GestureEvent(eventType, event.timestamp(), view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey()));
+}
+
+EventInterface GestureEvent::eventInterface() const
+{
+ // FIXME: This makes it so we never wrap GestureEvents in the right bindings.
+ return EventInterfaceType;
+}
+
+GestureEvent::GestureEvent(const AtomicString& type, double timestamp, AbstractView* view, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
+ : MouseRelatedEvent(type, true, true, timestamp, view, 0, IntPoint(screenX, screenY), IntPoint(clientX, clientY)
+#if ENABLE(POINTER_LOCK)
+ , IntPoint(0, 0)
+#endif
+ , ctrlKey, altKey, shiftKey, metaKey)
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(QT_GESTURE_EVENTS)
diff --git a/Source/WebCore/dom/qt/GestureEvent.h b/Source/WebCore/dom/qt/GestureEvent.h
new file mode 100644
index 000000000..518923744
--- /dev/null
+++ b/Source/WebCore/dom/qt/GestureEvent.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 THE COPYRIGHT HOLDERS ``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 COMPUTER, INC. OR
+ * 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 GestureEvent_h
+#define GestureEvent_h
+
+#if ENABLE(QT_GESTURE_EVENTS)
+
+#include "EventNames.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "MouseRelatedEvent.h"
+#include "PlatformEvent.h"
+#include "PlatformGestureEvent.h"
+
+namespace WebCore {
+
+class GestureEvent : public MouseRelatedEvent {
+public:
+ virtual ~GestureEvent() { }
+
+ static RefPtr<GestureEvent> create(AbstractView*, const PlatformGestureEvent&);
+
+ EventInterface eventInterface() const override;
+
+private:
+ GestureEvent(const AtomicString& type, double timestamp, AbstractView*, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(QT_GESTURE_EVENTS)
+
+#endif // GestureEvent_h
diff --git a/Source/WebCore/page/EventHandler.cpp b/Source/WebCore/page/EventHandler.cpp
index e8aa9dfb3..a40b4bfab 100644
--- a/Source/WebCore/page/EventHandler.cpp
+++ b/Source/WebCore/page/EventHandler.cpp
@@ -105,6 +105,15 @@
#include "StyleCachedImageSet.h"
#endif
+#if ENABLE(QT_GESTURE_EVENTS)
+#include "PlatformGestureEvent.h"
+#include "ScrollAnimator.h"
+#endif
+
+#if ENABLE(TOUCH_ADJUSTMENT)
+#include "TouchAdjustment.h"
+#endif
+
#if ENABLE(IOS_TOUCH_EVENTS)
#include "PlatformTouchEventIOS.h"
#endif
@@ -347,7 +356,7 @@ static inline bool handleWheelEventInAppropriateEnclosingBox(Node* startNode, Wh
return false;
}
-#if (ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS))
+#if (ENABLE(TOUCH_EVENTS) && !PLATFORM(IOS)) || ENABLE(QT_GESTURE_EVENTS)
static inline bool shouldGesturesTriggerActive()
{
// If the platform we're on supports GestureTapDown and GestureTapCancel then we'll
@@ -2704,6 +2713,169 @@ void EventHandler::defaultWheelEventHandler(Node* startNode, WheelEvent* wheelEv
#endif
}
+#if ENABLE(QT_GESTURE_EVENTS)
+bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
+{
+ Node* eventTarget = 0;
+ Scrollbar* scrollbar = 0;
+
+ IntPoint adjustedPoint = gestureEvent.position();
+ HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
+ if (gestureEvent.type() == PlatformEvent::GestureTap) {
+ // The mouseup event synthesized for this gesture will clear the active state of the
+ // targeted node, so performing a ReadOnly hit test here is fine.
+ hitType |= HitTestRequest::ReadOnly;
+ } else
+ hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
+
+ if (!shouldGesturesTriggerActive())
+ hitType |= HitTestRequest::ReadOnly;
+
+ if ((!scrollbar && !eventTarget) || !(hitType & HitTestRequest::ReadOnly)) {
+ IntPoint hitTestPoint = m_frame.view()->windowToContents(adjustedPoint);
+ HitTestResult result = hitTestResultAtPoint(hitTestPoint, hitType | HitTestRequest::AllowFrameScrollbars);
+ eventTarget = result.targetNode();
+ if (!scrollbar)
+ scrollbar = result.scrollbar();
+ }
+
+ if (scrollbar) {
+ bool eventSwallowed = scrollbar->gestureEvent(gestureEvent);
+ if (eventSwallowed)
+ return true;
+ }
+
+ if (eventTarget) {
+ bool eventSwallowed = eventTarget->dispatchGestureEvent(gestureEvent);
+ if (eventSwallowed)
+ return true;
+ }
+
+ // FIXME: A more general scroll system (https://bugs.webkit.org/show_bug.cgi?id=80596) will
+ // eliminate the need for this.
+ TemporaryChange<PlatformEvent::Type> baseEventType(m_baseEventType, gestureEvent.type());
+
+ switch (gestureEvent.type()) {
+ case PlatformEvent::GestureTap:
+ return handleGestureTap(gestureEvent);
+ case PlatformEvent::GestureLongPress:
+ return handleGestureLongPress(gestureEvent);
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ return false;
+}
+
+bool EventHandler::handleGestureTap(const PlatformGestureEvent& gestureEvent)
+{
+ // FIXME: Refactor this code to not hit test multiple times. We use the adjusted position to ensure that the correct node is targeted by the later redundant hit tests.
+ IntPoint adjustedPoint = gestureEvent.position();
+#if ENABLE(TOUCH_ADJUSTMENT)
+ adjustGesturePosition(gestureEvent, adjustedPoint);
+#endif
+
+ PlatformMouseEvent fakeMouseMove(adjustedPoint, gestureEvent.globalPosition(),
+ NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
+ gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp(), ForceAtClick);
+ mouseMoved(fakeMouseMove);
+
+ int tapCount = 1;
+
+ bool defaultPrevented = false;
+ PlatformMouseEvent fakeMouseDown(adjustedPoint, gestureEvent.globalPosition(),
+ LeftButton, PlatformEvent::MousePressed, tapCount,
+ gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp(), ForceAtClick);
+ defaultPrevented |= handleMousePressEvent(fakeMouseDown);
+
+ PlatformMouseEvent fakeMouseUp(adjustedPoint, gestureEvent.globalPosition(),
+ LeftButton, PlatformEvent::MouseReleased, tapCount,
+ gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp(), ForceAtClick);
+ defaultPrevented |= handleMouseReleaseEvent(fakeMouseUp);
+
+ return defaultPrevented;
+}
+
+bool EventHandler::handleGestureLongPress(const PlatformGestureEvent& gestureEvent)
+{
+ return handleGestureForTextSelectionOrContextMenu(gestureEvent);
+}
+
+bool EventHandler::handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent& gestureEvent)
+{
+#if ENABLE(CONTEXT_MENUS)
+ return sendContextMenuEventForGesture(gestureEvent);
+#else
+ return false;
+#endif
+}
+#endif // ENABLE(QT_GESTURE_EVENTS)
+
+#if ENABLE(TOUCH_ADJUSTMENT)
+bool EventHandler::shouldApplyTouchAdjustment(const PlatformGestureEvent& event) const
+{
+ if (!m_frame.settings().touchAdjustmentEnabled())
+ return false;
+ return !event.area().isEmpty();
+}
+
+
+bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
+{
+ IntPoint hitTestPoint = m_frame.view()->windowToContents(touchCenter);
+ HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active, touchRadius);
+
+ IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
+
+ // FIXME: Should be able to handle targetNode being a shadow DOM node to avoid performing uncessary hit tests
+ // in the case where further processing on the node is required. Returning the shadow ancestor prevents a
+ // regression in touchadjustment/html-label.html. Some refinement is required to testing/internals to
+ // handle targetNode being a shadow DOM node.
+ bool success = findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, result.rectBasedTestResult());
+ if (success && targetNode)
+ targetNode = targetNode->deprecatedShadowAncestorNode();
+ return success;
+}
+
+bool EventHandler::bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
+{
+ IntPoint hitTestPoint = m_frame.view()->windowToContents(touchCenter);
+ HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active, touchRadius);
+
+ IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
+ return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, result.rectBasedTestResult());
+}
+
+bool EventHandler::bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode)
+{
+ IntPoint hitTestPoint = m_frame.view()->windowToContents(touchCenter);
+ HitTestResult result = hitTestResultAtPoint(hitTestPoint, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent, touchRadius);
+
+ IntRect touchRect(touchCenter - touchRadius, touchRadius + touchRadius);
+ return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, result.rectBasedTestResult());
+}
+
+bool EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint)
+{
+ if (!shouldApplyTouchAdjustment(gestureEvent))
+ return false;
+
+ Node* targetNode = 0;
+ switch (gestureEvent.type()) {
+ case PlatformEvent::GestureTap:
+ bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targetNode);
+ break;
+ case PlatformEvent::GestureLongPress:
+ bestContextMenuNodeForTouchPoint(gestureEvent.position(), IntSize(gestureEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targetNode);
+ break;
+ default:
+ // FIXME: Implement handling for other types as needed.
+ ASSERT_NOT_REACHED();
+ }
+ return targetNode;
+}
+#endif
+
#if ENABLE(CONTEXT_MENUS)
bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
{
@@ -2811,6 +2983,29 @@ bool EventHandler::sendContextMenuEventForKey()
return !dispatchMouseEvent(eventNames().contextmenuEvent, targetNode, true, 0, platformMouseEvent, false);
}
+
+#if ENABLE(QT_GESTURE_EVENTS)
+bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& event)
+{
+#if OS(WINDOWS)
+ PlatformEvent::Type eventType = PlatformEvent::MouseReleased;
+#else
+ PlatformEvent::Type eventType = PlatformEvent::MousePressed;
+#endif
+
+ IntPoint adjustedPoint = event.position();
+#if ENABLE(TOUCH_ADJUSTMENT)
+ adjustGesturePosition(event, adjustedPoint);
+#endif
+ PlatformMouseEvent mouseEvent(adjustedPoint, event.globalPosition(), RightButton, eventType, 1, false, false, false, false, WTF::currentTime(), ForceAtClick);
+ // To simulate right-click behavior, we send a right mouse down and then
+ // context menu event.
+ handleMousePressEvent(mouseEvent);
+ return sendContextMenuEvent(mouseEvent);
+ // We do not need to send a corresponding mouse release because in case of
+ // right-click, the context menu takes capture and consumes all events.
+}
+#endif // ENABLE(QT_GESTURE_EVENTS)
#endif // ENABLE(CONTEXT_MENUS)
void EventHandler::scheduleHoverStateUpdate()
diff --git a/Source/WebCore/page/EventHandler.h b/Source/WebCore/page/EventHandler.h
index f666a1b40..a11e042ee 100644
--- a/Source/WebCore/page/EventHandler.h
+++ b/Source/WebCore/page/EventHandler.h
@@ -96,6 +96,11 @@ class Widget;
struct DragState;
+#if ENABLE(QT_GESTURE_EVENTS)
+class PlatformGestureEvent;
+class RenderObject;
+#endif
+
#if ENABLE(DRAG_SUPPORT)
extern const int LinkDragHysteresis;
extern const int ImageDragHysteresis;
@@ -217,6 +222,12 @@ public:
typedef HashSet<RefPtr<EventTarget>> EventTargetSet;
#endif
+#if ENABLE(QT_GESTURE_EVENTS)
+ bool handleGestureEvent(const PlatformGestureEvent&);
+ bool handleGestureTap(const PlatformGestureEvent&);
+ bool handleGestureLongPress(const PlatformGestureEvent&);
+#endif
+
#if ENABLE(IOS_TOUCH_EVENTS)
bool dispatchTouchEvent(const PlatformTouchEvent&, const AtomicString&, const EventTargetTouchMap&, float, float);
bool dispatchSimulatedTouchEvent(IntPoint location);
@@ -233,9 +244,22 @@ public:
void defaultTouchEventHandler(Node*, TouchEvent*);
#endif
+#if ENABLE(TOUCH_ADJUSTMENT)
+ bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
+
+ bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
+ bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
+ bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
+
+ bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
+#endif
+
#if ENABLE(CONTEXT_MENUS)
WEBCORE_EXPORT bool sendContextMenuEvent(const PlatformMouseEvent&);
bool sendContextMenuEventForKey();
+#if ENABLE(QT_GESTURE_EVENTS)
+ bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
+#endif
#endif
void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
@@ -451,6 +475,10 @@ private:
bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
#endif
+#if ENABLE(QT_GESTURE_EVENTS)
+ bool handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent&);
+#endif
+
void setLastKnownMousePosition(const PlatformMouseEvent&);
#if ENABLE(CURSOR_VISIBILITY)
diff --git a/Source/WebCore/page/Settings.in b/Source/WebCore/page/Settings.in
index 24f7e40ec..84a9f0cd0 100644
--- a/Source/WebCore/page/Settings.in
+++ b/Source/WebCore/page/Settings.in
@@ -154,6 +154,11 @@ imageSubsamplingEnabled initial=defaultImageSubsamplingEnabled
wantsBalancedSetDefersLoadingBehavior initial=false
requestAnimationFrameEnabled initial=true
+# For touch adjustment to apply, the compile option TOUCH_ADJUSTMENT must also be enabled.
+# This setting adds a means to dynamically disable the feature at runtime on systems with
+# support for touch adjustment.
+touchAdjustmentEnabled initial=true
+
fixedPositionCreatesStackingContext initial=defaultFixedPositionCreatesStackingContext
syncXHRInDocumentsEnabled initial=true
cookieEnabled initial=true
diff --git a/Source/WebCore/page/qt/TouchAdjustment.cpp b/Source/WebCore/page/qt/TouchAdjustment.cpp
new file mode 100644
index 000000000..5c393efb5
--- /dev/null
+++ b/Source/WebCore/page/qt/TouchAdjustment.cpp
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "TouchAdjustment.h"
+
+#include "ContainerNode.h"
+#include "Editor.h"
+#include "FloatPoint.h"
+#include "FloatQuad.h"
+#include "Frame.h"
+#include "FrameView.h"
+#include "HTMLFrameOwnerElement.h"
+#include "HTMLInputElement.h"
+#include "HTMLLabelElement.h"
+#include "HTMLNames.h"
+#include "IntPoint.h"
+#include "IntSize.h"
+#include "Node.h"
+#include "NodeRenderStyle.h"
+#include "RenderBox.h"
+#include "RenderObject.h"
+#include "RenderStyle.h"
+#include "RenderText.h"
+#include "RenderView.h"
+#include "ShadowRoot.h"
+#include "Text.h"
+#include "TextBreakIterator.h"
+
+namespace WebCore {
+
+namespace TouchAdjustment {
+
+const float zeroTolerance = 1e-6f;
+
+// Class for remembering absolute quads of a target node and what node they represent.
+class SubtargetGeometry {
+public:
+ SubtargetGeometry(Node* node, const FloatQuad& quad)
+ : m_node(node)
+ , m_quad(quad)
+ { }
+
+ Node* node() const { return m_node; }
+ FloatQuad quad() const { return m_quad; }
+ IntRect boundingBox() const { return m_quad.enclosingBoundingBox(); }
+
+private:
+ Node* m_node;
+ FloatQuad m_quad;
+};
+
+typedef Vector<SubtargetGeometry> SubtargetGeometryList;
+typedef bool (*NodeFilter)(Node*);
+typedef void (*AppendSubtargetsForNode)(Node*, SubtargetGeometryList&);
+typedef float (*DistanceFunction)(const IntPoint&, const IntRect&, const SubtargetGeometry&);
+
+// Takes non-const Node* because isContentEditable is a non-const function.
+bool nodeRespondsToTapGesture(Node* node)
+{
+ if (node->willRespondToMouseClickEvents() || node->willRespondToMouseMoveEvents())
+ return true;
+ // Accept nodes that has a CSS effect when touched.
+ if (node->isElementNode()) {
+ Element* element = downcast<Element>(node);
+ if (element->isMouseFocusable())
+ return true;
+ if (element->childrenAffectedByActive() || element->childrenAffectedByHover())
+ return true;
+ }
+ if (RenderStyle* renderStyle = node->renderStyle()) {
+ if (renderStyle->affectedByActive() || renderStyle->affectedByHover())
+ return true;
+ }
+ return false;
+}
+
+bool nodeIsZoomTarget(Node* node)
+{
+ if (node->isTextNode() || node->isShadowRoot())
+ return false;
+
+ ASSERT(node->renderer());
+ return node->renderer()->isBox();
+}
+
+bool providesContextMenuItems(Node* node)
+{
+ // This function tries to match the nodes that receive special context-menu items in
+ // ContextMenuController::populate(), and should be kept uptodate with those.
+ ASSERT(node->renderer() || node->isShadowRoot());
+ if (!node->renderer())
+ return false;
+ if (node->isContentEditable())
+ return true;
+ if (node->isLink())
+ return true;
+ if (node->renderer()->isImage())
+ return true;
+ if (node->renderer()->isMedia())
+ return true;
+ if (node->renderer()->canBeSelectionLeaf()) {
+ // If the context menu gesture will trigger a selection all selectable nodes are valid targets.
+ if (node->renderer()->frame().editor().behavior().shouldSelectOnContextualMenuClick())
+ return true;
+ // Only the selected part of the renderer is a valid target, but this will be corrected in
+ // appendContextSubtargetsForNode.
+ if (node->renderer()->selectionState() != RenderObject::SelectionNone)
+ return true;
+ }
+ return false;
+}
+
+static inline void appendQuadsToSubtargetList(Vector<FloatQuad>& quads, Node* node, SubtargetGeometryList& subtargets)
+{
+ Vector<FloatQuad>::const_iterator it = quads.begin();
+ const Vector<FloatQuad>::const_iterator end = quads.end();
+ for (; it != end; ++it)
+ subtargets.append(SubtargetGeometry(node, *it));
+}
+
+static inline void appendBasicSubtargetsForNode(Node* node, SubtargetGeometryList& subtargets)
+{
+ // Node guaranteed to have renderer due to check in node filter.
+ ASSERT(node->renderer());
+
+ Vector<FloatQuad> quads;
+ node->renderer()->absoluteQuads(quads);
+
+ appendQuadsToSubtargetList(quads, node, subtargets);
+}
+
+static inline void appendContextSubtargetsForNode(Node* node, SubtargetGeometryList& subtargets)
+{
+ // This is a variant of appendBasicSubtargetsForNode that adds special subtargets for
+ // selected or auto-selectable parts of text nodes.
+ ASSERT(node->renderer());
+
+ if (!node->isTextNode())
+ return appendBasicSubtargetsForNode(node, subtargets);
+
+ Text* textNode = static_cast<WebCore::Text*>(node);
+ RenderText* textRenderer = textNode->renderer();
+
+ if (textRenderer->frame().editor().behavior().shouldSelectOnContextualMenuClick()) {
+ // Make subtargets out of every word.
+ String textValue = textNode->data();
+ TextBreakIterator* wordIterator = wordBreakIterator(StringView(textValue));
+ int lastOffset = textBreakFirst(wordIterator);
+ if (lastOffset == -1)
+ return;
+ int offset;
+ while ((offset = textBreakNext(wordIterator)) != -1) {
+ if (isWordTextBreak(wordIterator)) {
+ Vector<FloatQuad> quads = textRenderer->absoluteQuadsForRange(lastOffset, offset);
+ appendQuadsToSubtargetList(quads, textNode, subtargets);
+ }
+ lastOffset = offset;
+ }
+ } else {
+ if (textRenderer->selectionState() == RenderObject::SelectionNone)
+ return appendBasicSubtargetsForNode(node, subtargets);
+ // If selected, make subtargets out of only the selected part of the text.
+ int startPos, endPos;
+ switch (textRenderer->selectionState()) {
+ case RenderObject::SelectionInside:
+ startPos = 0;
+ endPos = textRenderer->textLength();
+ break;
+ case RenderObject::SelectionStart:
+ textRenderer->selectionStartEnd(startPos, endPos);
+ endPos = textRenderer->textLength();
+ break;
+ case RenderObject::SelectionEnd:
+ textRenderer->selectionStartEnd(startPos, endPos);
+ startPos = 0;
+ break;
+ case RenderObject::SelectionBoth:
+ textRenderer->selectionStartEnd(startPos, endPos);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ return;
+ }
+ Vector<FloatQuad> quads = textRenderer->absoluteQuadsForRange(startPos, endPos);
+ appendQuadsToSubtargetList(quads, textNode, subtargets);
+ }
+}
+
+static inline void appendZoomableSubtargets(Node* node, SubtargetGeometryList& subtargets)
+{
+ RenderBox* renderer = downcast<RenderBox>(node->renderer());
+ ASSERT(renderer);
+
+ Vector<FloatQuad> quads;
+ FloatRect borderBoxRect = renderer->borderBoxRect();
+ FloatRect contentBoxRect = renderer->contentBoxRect();
+ quads.append(renderer->localToAbsoluteQuad(borderBoxRect));
+ if (borderBoxRect != contentBoxRect)
+ quads.append(renderer->localToAbsoluteQuad(contentBoxRect));
+ // FIXME: For RenderBlocks, add column boxes and content boxes cleared for floats.
+
+ Vector<FloatQuad>::const_iterator it = quads.begin();
+ const Vector<FloatQuad>::const_iterator end = quads.end();
+ for (; it != end; ++it)
+ subtargets.append(SubtargetGeometry(node, *it));
+}
+
+static inline Node* parentShadowHostOrOwner(const Node* node)
+{
+ if (Node* ancestor = node->parentOrShadowHostNode())
+ return ancestor;
+ if (node->isDocumentNode())
+ return downcast<Document>(node)->ownerElement();
+ return 0;
+}
+
+// Compiles a list of subtargets of all the relevant target nodes.
+void compileSubtargetList(const NodeListHashSet& intersectedNodes, SubtargetGeometryList& subtargets, NodeFilter nodeFilter, AppendSubtargetsForNode appendSubtargetsForNode)
+{
+ // Find candidates responding to tap gesture events in O(n) time.
+ HashMap<Node*, Node*> responderMap;
+ HashSet<Node*> ancestorsToRespondersSet;
+ Vector<Node*> candidates;
+ HashSet<Node*> editableAncestors;
+
+ // A node matching the NodeFilter is called a responder. Candidate nodes must either be a
+ // responder or have an ancestor that is a responder.
+ // This iteration tests all ancestors at most once by caching earlier results.
+ NodeListHashSet::const_iterator end = intersectedNodes.end();
+ for (NodeListHashSet::const_iterator it = intersectedNodes.begin(); it != end; ++it) {
+ Node* const node = it->get();
+ Vector<Node*> visitedNodes;
+ Node* respondingNode = 0;
+ for (Node* visitedNode = node; visitedNode; visitedNode = visitedNode->parentOrShadowHostNode()) {
+ // Check if we already have a result for a common ancestor from another candidate.
+ respondingNode = responderMap.get(visitedNode);
+ if (respondingNode)
+ break;
+ visitedNodes.append(visitedNode);
+ // Check if the node filter applies, which would mean we have found a responding node.
+ if (nodeFilter(visitedNode)) {
+ respondingNode = visitedNode;
+ // Continue the iteration to collect the ancestors of the responder, which we will need later.
+ for (visitedNode = parentShadowHostOrOwner(visitedNode); visitedNode; visitedNode = parentShadowHostOrOwner(visitedNode)) {
+ HashSet<Node*>::AddResult addResult = ancestorsToRespondersSet.add(visitedNode);
+ if (!addResult.isNewEntry)
+ break;
+ }
+ break;
+ }
+ }
+ // Insert the detected responder for all the visited nodes.
+ for (unsigned j = 0; j < visitedNodes.size(); j++)
+ responderMap.add(visitedNodes[j], respondingNode);
+
+ if (respondingNode)
+ candidates.append(node);
+ }
+
+ // We compile the list of component absolute quads instead of using the bounding rect
+ // to be able to perform better hit-testing on inline links on line-breaks.
+ unsigned length = candidates.size();
+ for (unsigned i = 0; i < length; i++) {
+ Node* candidate = candidates[i];
+ // Skip nodes who's responders are ancestors of other responders. This gives preference to
+ // the inner-most event-handlers. So that a link is always preferred even when contained
+ // in an element that monitors all click-events.
+ Node* respondingNode = responderMap.get(candidate);
+ ASSERT(respondingNode);
+ if (ancestorsToRespondersSet.contains(respondingNode))
+ continue;
+ // Consolidate bounds for editable content.
+ if (editableAncestors.contains(candidate))
+ continue;
+ if (candidate->isContentEditable()) {
+ Node* replacement = candidate;
+ Node* parent = candidate->parentOrShadowHostNode();
+ while (parent && parent->isContentEditable()) {
+ replacement = parent;
+ if (editableAncestors.contains(replacement)) {
+ replacement = 0;
+ break;
+ }
+ editableAncestors.add(replacement);
+ parent = parent->parentOrShadowHostNode();
+ }
+ candidate = replacement;
+ }
+ if (candidate)
+ appendSubtargetsForNode(candidate, subtargets);
+ }
+}
+
+// Compiles a list of zoomable subtargets.
+void compileZoomableSubtargets(const NodeListHashSet& intersectedNodes, SubtargetGeometryList& subtargets)
+{
+ NodeListHashSet::const_iterator end = intersectedNodes.end();
+ for (NodeListHashSet::const_iterator it = intersectedNodes.begin(); it != end; ++it) {
+ Node* const candidate = it->get();
+ if (nodeIsZoomTarget(candidate))
+ appendZoomableSubtargets(candidate, subtargets);
+ }
+}
+
+// This returns quotient of the target area and its intersection with the touch area.
+// This will prioritize largest intersection and smallest area, while balancing the two against each other.
+float zoomableIntersectionQuotient(const IntPoint& touchHotspot, const IntRect& touchArea, const SubtargetGeometry& subtarget)
+{
+ IntRect rect = subtarget.boundingBox();
+
+ // Convert from frame coordinates to window coordinates.
+ rect = subtarget.node()->document().view()->contentsToWindow(rect);
+
+ // Check the rectangle is meaningful zoom target. It should at least contain the hotspot.
+ if (!rect.contains(touchHotspot))
+ return std::numeric_limits<float>::infinity();
+ IntRect intersection = rect;
+ intersection.intersect(touchArea);
+
+ // Return the quotient of the intersection.
+ return rect.size().area() / (float)intersection.size().area();
+}
+
+// Uses a hybrid of distance to adjust and intersect ratio, normalizing each score between 0 and 1
+// and combining them. The distance to adjust works best for disambiguating clicks on targets such
+// as links, where the width may be significantly larger than the touch width. Using area of overlap
+// in such cases can lead to a bias towards shorter links. Conversely, percentage of overlap can
+// provide strong confidence in tapping on a small target, where the overlap is often quite high,
+// and works well for tightly packed controls.
+float hybridDistanceFunction(const IntPoint& touchHotspot, const IntRect& touchRect, const SubtargetGeometry& subtarget)
+{
+ IntRect rect = subtarget.boundingBox();
+
+ // Convert from frame coordinates to window coordinates.
+ rect = subtarget.node()->document().view()->contentsToWindow(rect);
+
+ float radiusSquared = 0.25f * (touchRect.size().diagonalLengthSquared());
+ float distanceToAdjustScore = rect.distanceSquaredToPoint(touchHotspot) / radiusSquared;
+
+ int maxOverlapWidth = std::min(touchRect.width(), rect.width());
+ int maxOverlapHeight = std::min(touchRect.height(), rect.height());
+ float maxOverlapArea = std::max(maxOverlapWidth * maxOverlapHeight, 1);
+ rect.intersect(touchRect);
+ float intersectArea = rect.size().area();
+ float intersectionScore = 1 - intersectArea / maxOverlapArea;
+
+ float hybridScore = intersectionScore + distanceToAdjustScore;
+
+ return hybridScore;
+}
+
+FloatPoint contentsToWindow(FrameView *view, FloatPoint pt)
+{
+ int x = static_cast<int>(pt.x() + 0.5f);
+ int y = static_cast<int>(pt.y() + 0.5f);
+ IntPoint adjusted = view->contentsToWindow(IntPoint(x, y));
+ return FloatPoint(adjusted.x(), adjusted.y());
+}
+
+// Adjusts 'point' to the nearest point inside rect, and leaves it unchanged if already inside.
+void adjustPointToRect(FloatPoint& point, const FloatRect& rect)
+{
+ if (point.x() < rect.x())
+ point.setX(rect.x());
+ else if (point.x() > rect.maxX())
+ point.setX(rect.maxX());
+
+ if (point.y() < rect.y())
+ point.setY(rect.y());
+ else if (point.y() > rect.maxY())
+ point.setY(rect.maxY());
+}
+
+bool snapTo(const SubtargetGeometry& geom, const IntPoint& touchPoint, const IntRect& touchArea, IntPoint& adjustedPoint)
+{
+ FrameView* view = geom.node()->document().view();
+ FloatQuad quad = geom.quad();
+
+ if (quad.isRectilinear()) {
+ IntRect contentBounds = geom.boundingBox();
+ // Convert from frame coordinates to window coordinates.
+ IntRect bounds = view->contentsToWindow(contentBounds);
+ if (bounds.contains(touchPoint)) {
+ adjustedPoint = touchPoint;
+ return true;
+ }
+ if (bounds.intersects(touchArea)) {
+ bounds.intersect(touchArea);
+ adjustedPoint = bounds.center();
+ return true;
+ }
+ return false;
+ }
+
+ // The following code tries to adjust the point to place inside a both the touchArea and the non-rectilinear quad.
+ // FIXME: This will return the point inside the touch area that is the closest to the quad center, but does not
+ // guarantee that the point will be inside the quad. Corner-cases exist where the quad will intersect but this
+ // will fail to adjust the point to somewhere in the intersection.
+
+ // Convert quad from content to window coordinates.
+ FloatPoint p1 = contentsToWindow(view, quad.p1());
+ FloatPoint p2 = contentsToWindow(view, quad.p2());
+ FloatPoint p3 = contentsToWindow(view, quad.p3());
+ FloatPoint p4 = contentsToWindow(view, quad.p4());
+ quad = FloatQuad(p1, p2, p3, p4);
+
+ if (quad.containsPoint(touchPoint)) {
+ adjustedPoint = touchPoint;
+ return true;
+ }
+
+ // Pull point towards the center of the element.
+ FloatPoint center = quad.center();
+
+ adjustPointToRect(center, touchArea);
+ adjustedPoint = roundedIntPoint(center);
+
+ return quad.containsPoint(adjustedPoint);
+}
+
+// A generic function for finding the target node with the lowest distance metric. A distance metric here is the result
+// of a distance-like function, that computes how well the touch hits the node.
+// Distance functions could for instance be distance squared or area of intersection.
+bool findNodeWithLowestDistanceMetric(Node*& targetNode, IntPoint& targetPoint, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, SubtargetGeometryList& subtargets, DistanceFunction distanceFunction)
+{
+ targetNode = 0;
+ float bestDistanceMetric = std::numeric_limits<float>::infinity();
+ SubtargetGeometryList::const_iterator it = subtargets.begin();
+ const SubtargetGeometryList::const_iterator end = subtargets.end();
+ IntPoint adjustedPoint;
+
+ for (; it != end; ++it) {
+ Node* node = it->node();
+ float distanceMetric = distanceFunction(touchHotspot, touchArea, *it);
+ if (distanceMetric < bestDistanceMetric) {
+ if (snapTo(*it, touchHotspot, touchArea, adjustedPoint)) {
+ targetPoint = adjustedPoint;
+ targetArea = it->boundingBox();
+ targetNode = node;
+ bestDistanceMetric = distanceMetric;
+ }
+ } else if (distanceMetric - bestDistanceMetric < zeroTolerance) {
+ if (snapTo(*it, touchHotspot, touchArea, adjustedPoint)) {
+ if (node->isDescendantOf(targetNode)) {
+ // Try to always return the inner-most element.
+ targetPoint = adjustedPoint;
+ targetNode = node;
+ targetArea = it->boundingBox();
+ }
+ }
+ }
+ }
+
+ if (targetNode)
+ targetArea = targetNode->document().view()->contentsToWindow(targetArea);
+
+ return targetNode;
+}
+
+} // namespace TouchAdjustment
+
+bool findBestClickableCandidate(Node*& targetNode, IntPoint &targetPoint, const IntPoint &touchHotspot, const IntRect &touchArea, const NodeListHashSet& nodeList)
+{
+ IntRect targetArea;
+ TouchAdjustment::SubtargetGeometryList subtargets;
+ TouchAdjustment::compileSubtargetList(nodeList, subtargets, TouchAdjustment::nodeRespondsToTapGesture, TouchAdjustment::appendBasicSubtargetsForNode);
+ return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction);
+}
+
+bool findBestContextMenuCandidate(Node*& targetNode, IntPoint &targetPoint, const IntPoint &touchHotspot, const IntRect &touchArea, const NodeListHashSet& nodeList)
+{
+ IntRect targetArea;
+ TouchAdjustment::SubtargetGeometryList subtargets;
+ TouchAdjustment::compileSubtargetList(nodeList, subtargets, TouchAdjustment::providesContextMenuItems, TouchAdjustment::appendContextSubtargetsForNode);
+ return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::hybridDistanceFunction);
+}
+
+bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const NodeListHashSet& nodeList)
+{
+ IntPoint targetPoint;
+ TouchAdjustment::SubtargetGeometryList subtargets;
+ TouchAdjustment::compileZoomableSubtargets(nodeList, subtargets);
+ return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::zoomableIntersectionQuotient);
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/page/qt/TouchAdjustment.h b/Source/WebCore/page/qt/TouchAdjustment.h
new file mode 100644
index 000000000..06ac00813
--- /dev/null
+++ b/Source/WebCore/page/qt/TouchAdjustment.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef TouchAdjustment_h
+#define TouchAdjustment_h
+
+#include "IntPoint.h"
+#include "IntRect.h"
+#include "Node.h"
+#include "NodeList.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+typedef ListHashSet<RefPtr<Node> > NodeListHashSet;
+
+bool findBestClickableCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const NodeListHashSet&);
+bool findBestContextMenuCandidate(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, const NodeListHashSet&);
+bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const NodeListHashSet&);
+// FIXME: Implement the similar functions for other gestures here as well.
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/platform/MainThreadSharedTimer.h b/Source/WebCore/platform/MainThreadSharedTimer.h
index f7a0c91da..a8421c3fa 100644
--- a/Source/WebCore/platform/MainThreadSharedTimer.h
+++ b/Source/WebCore/platform/MainThreadSharedTimer.h
@@ -50,6 +50,10 @@ public:
// need to call this from non-member functions at the moment.
void fired();
+#if PLATFORM(QT)
+ bool hasFiredFunction() const { return bool(m_firedFunction); }
+#endif
+
private:
MainThreadSharedTimer();
diff --git a/Source/WebCore/platform/PlatformEvent.h b/Source/WebCore/platform/PlatformEvent.h
index 6e263122f..402052dc4 100644
--- a/Source/WebCore/platform/PlatformEvent.h
+++ b/Source/WebCore/platform/PlatformEvent.h
@@ -51,6 +51,12 @@ public:
// PlatformWheelEvent
Wheel,
+#if ENABLE(QT_GESTURE_EVENTS)
+ // PlatformGestureEvent
+ GestureTap,
+ GestureLongPress,
+#endif
+
#if ENABLE(TOUCH_EVENTS)
// PlatformTouchEvent
TouchStart,
diff --git a/Source/WebCore/platform/Scrollbar.cpp b/Source/WebCore/platform/Scrollbar.cpp
index 05bf16a29..617d9a0e1 100644
--- a/Source/WebCore/platform/Scrollbar.cpp
+++ b/Source/WebCore/platform/Scrollbar.cpp
@@ -35,6 +35,10 @@
#include "ScrollbarTheme.h"
#include <algorithm>
+#if ENABLE(QT_GESTURE_EVENTS)
+#include "PlatformGestureEvent.h"
+#endif
+
#if PLATFORM(GTK)
// The position of the scrollbar thumb affects the appearance of the steppers, so
// when the thumb moves, we have to invalidate them for painting.
@@ -319,6 +323,24 @@ void Scrollbar::setPressedPart(ScrollbarPart part)
theme().invalidatePart(*this, m_hoveredPart);
}
+#if ENABLE(QT_GESTURE_EVENTS)
+bool Scrollbar::gestureEvent(const PlatformGestureEvent& evt)
+{
+ bool handled = false;
+ switch (evt.type()) {
+ case PlatformEvent::GestureTap:
+ if (m_pressedPart != ThumbPart && m_pressedPart != NoPart)
+ handled = m_scrollableArea.scroll(pressedPartScrollDirection(), pressedPartScrollGranularity());
+ break;
+ default:
+ break;
+ }
+ setPressedPart(NoPart);
+ m_pressedPos = 0;
+ return handled;
+}
+#endif
+
#if !PLATFORM(IOS)
bool Scrollbar::mouseMoved(const PlatformMouseEvent& evt)
{
diff --git a/Source/WebCore/platform/Scrollbar.h b/Source/WebCore/platform/Scrollbar.h
index 2491b9c74..ad29b502f 100644
--- a/Source/WebCore/platform/Scrollbar.h
+++ b/Source/WebCore/platform/Scrollbar.h
@@ -40,6 +40,10 @@ class PlatformMouseEvent;
class ScrollableArea;
class ScrollbarTheme;
+#if ENABLE(QT_GESTURE_EVENTS)
+class PlatformGestureEvent;
+#endif
+
class Scrollbar : public Widget {
public:
// Must be implemented by platforms that can't simply use the Scrollbar base class. Right now the only platform that is not using the base class is GTK.
@@ -96,6 +100,10 @@ public:
bool isWindowActive() const;
+#if ENABLE(QT_GESTURE_EVENTS)
+ bool gestureEvent(const PlatformGestureEvent&);
+#endif
+
// These methods are used for platform scrollbars to give :hover feedback. They will not get called
// when the mouse went down in a scrollbar, since it is assumed the scrollbar will start
// grabbing all events in that case anyway.
diff --git a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h
index 2038416a8..71efb55e0 100644
--- a/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h
+++ b/Source/WebCore/platform/graphics/texmap/TextureMapperShaderProgram.h
@@ -22,15 +22,23 @@
#define TextureMapperShaderProgram_h
#if USE(TEXTURE_MAPPER_GL)
+
#include "GraphicsContext3D.h"
#include "TransformationMatrix.h"
#include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/text/AtomicStringHash.h>
namespace WebCore {
-#define TEXMAP_DECLARE_VARIABLE(Accessor, Name, Type) GC3Duint Accessor##Location() { static const AtomicString name(Name); return getLocation(name, Type); }
+
+#define TEXMAP_DECLARE_VARIABLE(Accessor, Name, Type) \
+ GC3Duint Accessor##Location() { \
+ static NeverDestroyed<const AtomicString> name(Name, AtomicString::ConstructFromLiteral); \
+ return getLocation(name.get(), Type); \
+ }
+
#define TEXMAP_DECLARE_UNIFORM(Accessor) TEXMAP_DECLARE_VARIABLE(Accessor, "u_"#Accessor, UniformVariable)
#define TEXMAP_DECLARE_ATTRIBUTE(Accessor) TEXMAP_DECLARE_VARIABLE(Accessor, "a_"#Accessor, AttribVariable)
#define TEXMAP_DECLARE_SAMPLER(Accessor) TEXMAP_DECLARE_VARIABLE(Accessor, "s_"#Accessor, UniformVariable)
diff --git a/Source/WebCore/platform/qt/MainThreadSharedTimerQt.cpp b/Source/WebCore/platform/qt/MainThreadSharedTimerQt.cpp
index 11c507d66..7aae3f1de 100644
--- a/Source/WebCore/platform/qt/MainThreadSharedTimerQt.cpp
+++ b/Source/WebCore/platform/qt/MainThreadSharedTimerQt.cpp
@@ -33,7 +33,6 @@
#include <QBasicTimer>
#include <QCoreApplication>
-#include <QDebug>
#include <QPointer>
#include <wtf/CurrentTime.h>
@@ -104,7 +103,8 @@ void SharedTimerQt::timerEvent(QTimerEvent* ev)
return;
m_timer.stop();
- MainThreadSharedTimer::singleton().fired();
+ if (MainThreadSharedTimer::singleton().hasFiredFunction())
+ MainThreadSharedTimer::singleton().fired();
}
void MainThreadSharedTimer::setFireInterval(double interval)
diff --git a/Source/WebCore/platform/qt/PlatformGestureEvent.h b/Source/WebCore/platform/qt/PlatformGestureEvent.h
new file mode 100644
index 000000000..1beac6a68
--- /dev/null
+++ b/Source/WebCore/platform/qt/PlatformGestureEvent.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
+ * 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 PlatformGestureEvent_h
+#define PlatformGestureEvent_h
+
+#if ENABLE(QT_GESTURE_EVENTS)
+
+#include "FloatPoint.h"
+#include "IntPoint.h"
+#include "IntSize.h"
+#include "PlatformEvent.h"
+
+namespace WebCore {
+
+class PlatformGestureEvent : public PlatformEvent {
+public:
+ PlatformGestureEvent()
+ : PlatformEvent(PlatformEvent::GestureTap)
+ {
+ }
+
+ const IntPoint& position() const { return m_position; } // PlatformWindow coordinates.
+ const IntPoint& globalPosition() const { return m_globalPosition; } // Screen coordinates.
+
+ const IntSize& area() const { return m_area; }
+
+protected:
+ IntPoint m_position;
+ IntPoint m_globalPosition;
+ IntSize m_area;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(QT_GESTURE_EVENTS)
+
+#endif // PlatformGestureEvent_h
diff --git a/Source/WebCore/platform/qt/WidgetQt.cpp b/Source/WebCore/platform/qt/WidgetQt.cpp
index f3f04b157..0d1669941 100644
--- a/Source/WebCore/platform/qt/WidgetQt.cpp
+++ b/Source/WebCore/platform/qt/WidgetQt.cpp
@@ -42,7 +42,6 @@
#include "FrameView.h"
#include <QCoreApplication>
-#include <QDebug>
#include <QPaintEngine>
#include <QPainter>
diff --git a/Source/WebCore/testing/Internals.cpp b/Source/WebCore/testing/Internals.cpp
index e4db91695..b46112a22 100644
--- a/Source/WebCore/testing/Internals.cpp
+++ b/Source/WebCore/testing/Internals.cpp
@@ -145,6 +145,10 @@
#include "DeviceProximityController.h"
#endif
+#if ENABLE(TOUCH_ADJUSTMENT)
+#include "WebKitPoint.h"
+#endif
+
#if ENABLE(MOUSE_CURSOR_SCALE)
#include <wtf/dtoa.h>
#endif
@@ -1483,6 +1487,105 @@ void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
document->view()->setDelegatesScrolling(enabled);
}
+#if ENABLE(TOUCH_ADJUSTMENT)
+PassRefPtr<WebKitPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, ExceptionCode& ec)
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame()) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ IntSize radius(width / 2, height / 2);
+ IntPoint point(x + radius.width(), y + radius.height());
+
+ Node* targetNode;
+ IntPoint adjustedPoint;
+
+ bool foundNode = document->frame()->eventHandler().bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
+ if (foundNode)
+ return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y());
+
+ return 0;
+}
+
+Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, ExceptionCode& ec)
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame()) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ IntSize radius(width / 2, height / 2);
+ IntPoint point(x + radius.width(), y + radius.height());
+
+ Node* targetNode;
+ IntPoint adjustedPoint;
+ document->frame()->eventHandler().bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
+ return targetNode;
+}
+
+PassRefPtr<WebKitPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, ExceptionCode& ec)
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame()) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ IntSize radius(width / 2, height / 2);
+ IntPoint point(x + radius.width(), y + radius.height());
+
+ Node* targetNode = 0;
+ IntPoint adjustedPoint;
+
+ bool foundNode = document->frame()->eventHandler().bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
+ if (foundNode)
+ return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y());
+
+ return WebKitPoint::create(x, y);
+}
+
+Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, ExceptionCode& ec)
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame()) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ IntSize radius(width / 2, height / 2);
+ IntPoint point(x + radius.width(), y + radius.height());
+
+ Node* targetNode = 0;
+ IntPoint adjustedPoint;
+ document->frame()->eventHandler().bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
+ return targetNode;
+}
+
+PassRefPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, ExceptionCode& ec)
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame()) {
+ ec = INVALID_ACCESS_ERR;
+ return 0;
+ }
+
+ IntSize radius(width / 2, height / 2);
+ IntPoint point(x + radius.width(), y + radius.height());
+
+ Node* targetNode;
+ IntRect zoomableArea;
+ bool foundNode = document->frame()->eventHandler().bestZoomableAreaForTouchPoint(point, radius, zoomableArea, targetNode);
+ if (foundNode)
+ return ClientRect::create(zoomableArea);
+
+ return 0;
+}
+#endif
+
+
int Internals::lastSpellCheckRequestSequence(ExceptionCode& ec)
{
Document* document = contextDocument();
diff --git a/Source/WebCore/testing/Internals.h b/Source/WebCore/testing/Internals.h
index 67a0193cd..95ed9357d 100644
--- a/Source/WebCore/testing/Internals.h
+++ b/Source/WebCore/testing/Internals.h
@@ -64,6 +64,7 @@ class Page;
class Range;
class RenderedDocumentMarker;
class ScriptExecutionContext;
+class WebKitPoint;
class SerializedScriptValue;
class SourceBuffer;
class TimeRanges;
@@ -193,6 +194,13 @@ public:
RefPtr<Range> rangeForDictionaryLookupAtLocation(int x, int y, ExceptionCode&);
void setDelegatesScrolling(bool enabled, ExceptionCode&);
+#if ENABLE(TOUCH_ADJUSTMENT)
+ PassRefPtr<WebKitPoint> touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, ExceptionCode&);
+ Node* touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, ExceptionCode&);
+ PassRefPtr<WebKitPoint> touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, ExceptionCode&);
+ Node* touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, ExceptionCode&);
+ PassRefPtr<ClientRect> bestZoomableAreaForTouchPoint(long x, long y, long width, long height, ExceptionCode&);
+#endif
int lastSpellCheckRequestSequence(ExceptionCode&);
int lastSpellCheckProcessedSequence(ExceptionCode&);
diff --git a/Source/WebCore/testing/Internals.idl b/Source/WebCore/testing/Internals.idl
index 8043d6752..12cbad516 100644
--- a/Source/WebCore/testing/Internals.idl
+++ b/Source/WebCore/testing/Internals.idl
@@ -174,6 +174,13 @@ enum AutoFillButtonType {
[RaisesException] Range rangeForDictionaryLookupAtLocation(long x, long y);
[RaisesException] void setDelegatesScrolling(boolean enabled);
+#if defined(ENABLE_TOUCH_ADJUSTMENT) && ENABLE_TOUCH_ADJUSTMENT
+ [RaisesException] WebKitPoint touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height);
+ [RaisesException] Node touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height);
+ [RaisesException] WebKitPoint touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height);
+ [RaisesException] Node touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height);
+ [RaisesException] ClientRect bestZoomableAreaForTouchPoint(long x, long y, long width, long height);
+#endif
[RaisesException] long lastSpellCheckRequestSequence();
[RaisesException] long lastSpellCheckProcessedSequence();
diff --git a/Source/WebKit/PlatformQt.cmake b/Source/WebKit/PlatformQt.cmake
index 61fb76047..7e319fade 100644
--- a/Source/WebKit/PlatformQt.cmake
+++ b/Source/WebKit/PlatformQt.cmake
@@ -653,9 +653,6 @@ if (MSVC)
string(REPLACE "INCREMENTAL:YES" "INCREMENTAL:NO" replace_CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO})
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${replace_CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /INCREMENTAL:NO")
- set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:WINDOWS")
-
list(APPEND WebKit_INCLUDE_DIRECTORIES
${DERIVED_SOURCES_WEBKIT_DIR}
)
diff --git a/Source/WebKit/qt/Api/qwebfullscreenrequest.h b/Source/WebKit/qt/Api/qwebfullscreenrequest.h
index b86418c19..280e89caa 100644
--- a/Source/WebKit/qt/Api/qwebfullscreenrequest.h
+++ b/Source/WebKit/qt/Api/qwebfullscreenrequest.h
@@ -68,7 +68,10 @@ private:
QScopedPointer<QWebFullScreenRequestPrivate> d;
};
+QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(QWebFullScreenRequest, Q_MOVABLE_TYPE);
+QT_END_NAMESPACE
+
Q_DECLARE_METATYPE(QWebFullScreenRequest)
#endif
diff --git a/Source/WebKit/qt/Api/qwebhistory.cpp b/Source/WebKit/qt/Api/qwebhistory.cpp
index 6c5934156..64e607af9 100644
--- a/Source/WebKit/qt/Api/qwebhistory.cpp
+++ b/Source/WebKit/qt/Api/qwebhistory.cpp
@@ -37,7 +37,6 @@
#include <wtf/text/WTFString.h>
#include <QSharedData>
-#include <QDebug>
#include <QJsonObject>
static const int HistoryStreamVersion = 3;
diff --git a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
index 1ba5a8aa1..b45fb6b2a 100644
--- a/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
+++ b/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
@@ -82,7 +82,6 @@
#include "qwebpluginfactory.h"
#include "qwebsettings.h"
#include <QCoreApplication>
-#include <QDebug>
#include <QFileInfo>
#include <QMouseEvent>
#include <QNetworkReply>
diff --git a/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp b/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp
index 62b2f38be..de90866c6 100644
--- a/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp
+++ b/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.cpp
@@ -64,7 +64,7 @@
#include <QFileInfo>
#include <QNetworkRequest>
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
#include "PlatformGestureEvent.h"
#include "WebEventConversion.h"
#endif
@@ -165,7 +165,7 @@ bool QWebFrameAdapter::hasView() const
return frame && frame->view();
}
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
void QWebFrameAdapter::handleGestureEvent(QGestureEventFacade* gestureEvent)
{
ASSERT(frame && frame->view());
diff --git a/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h b/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h
index 42e02459d..c445a3240 100644
--- a/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h
+++ b/Source/WebKit/qt/WebCoreSupport/QWebFrameAdapter.h
@@ -47,8 +47,8 @@ QT_BEGIN_NAMESPACE
class QPoint;
QT_END_NAMESPACE
-#if ENABLE(GESTURE_EVENTS)
-class QGestureEventFacade;
+#if ENABLE(QT_GESTURE_EVENTS)
+struct QGestureEventFacade;
#endif
class QWebFrame;
class QWebFrameData;
@@ -133,7 +133,7 @@ public:
void load(const QNetworkRequest&, QNetworkAccessManager::Operation = QNetworkAccessManager::GetOperation, const QByteArray& body = QByteArray());
bool hasView() const;
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
void handleGestureEvent(QGestureEventFacade*);
#endif
QWebFrameAdapter* createFrame(QWebFrameData*);
diff --git a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp
index ee3339594..4d2b30d37 100644
--- a/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp
+++ b/Source/WebKit/qt/WebCoreSupport/QWebPageAdapter.cpp
@@ -454,7 +454,7 @@ void QWebPageAdapter::adjustPointForClicking(QMouseEvent* ev)
{
#if ENABLE(TOUCH_ADJUSTMENT)
QtPlatformPlugin platformPlugin;
- OwnPtr<QWebTouchModifier> touchModifier = platformPlugin.createTouchModifier();
+ std::unique_ptr<QWebTouchModifier> touchModifier = platformPlugin.createTouchModifier();
if (!touchModifier)
return;
@@ -468,7 +468,7 @@ void QWebPageAdapter::adjustPointForClicking(QMouseEvent* ev)
if (!topPadding && !rightPadding && !bottomPadding && !leftPadding)
return;
- FrameView* view = page->mainFrame()->view();
+ FrameView* view = page->mainFrame().view();
ASSERT(view);
if (view->scrollbarAtPoint(ev->pos()))
return;
diff --git a/Source/WebKit/qt/WebCoreSupport/WebEventConversion.cpp b/Source/WebKit/qt/WebCoreSupport/WebEventConversion.cpp
index cf10a113e..ee847787c 100644
--- a/Source/WebKit/qt/WebCoreSupport/WebEventConversion.cpp
+++ b/Source/WebKit/qt/WebCoreSupport/WebEventConversion.cpp
@@ -22,7 +22,7 @@
#include "config.h"
#include "WebEventConversion.h"
-//#include "PlatformGestureEvent.h" FIXME: GestureEvents were removed in r157316
+#include "PlatformGestureEvent.h"
#include "PlatformMouseEvent.h"
#include "PlatformTouchEvent.h"
#include "PlatformTouchPoint.h"
@@ -240,7 +240,7 @@ WebKitPlatformTouchPoint::WebKitPlatformTouchPoint(const QTouchEvent::TouchPoint
}
#endif
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
class WebKitPlatformGestureEvent : public PlatformGestureEvent {
public:
WebKitPlatformGestureEvent(QGestureEventFacade*);
@@ -281,7 +281,7 @@ PlatformTouchEvent convertTouchEvent(QTouchEvent* event)
}
#endif
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
PlatformGestureEvent convertGesture(QGestureEventFacade* event)
{
return WebKitPlatformGestureEvent(event);
diff --git a/Source/WebKit/qt/WebCoreSupport/WebEventConversion.h b/Source/WebKit/qt/WebCoreSupport/WebEventConversion.h
index 0cf8cd849..3cb7a3093 100644
--- a/Source/WebKit/qt/WebCoreSupport/WebEventConversion.h
+++ b/Source/WebKit/qt/WebCoreSupport/WebEventConversion.h
@@ -49,7 +49,7 @@ class PlatformTouchEvent;
PlatformTouchEvent convertTouchEvent(QTouchEvent*);
#endif
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
class PlatformGestureEvent;
PlatformGestureEvent convertGesture(QGestureEventFacade*);
#endif
diff --git a/Source/WebKit/qt/WidgetApi/qwebpage.cpp b/Source/WebKit/qt/WidgetApi/qwebpage.cpp
index 009842830..5bb2f315d 100644
--- a/Source/WebKit/qt/WidgetApi/qwebpage.cpp
+++ b/Source/WebKit/qt/WidgetApi/qwebpage.cpp
@@ -31,6 +31,7 @@
#include "QtFallbackWebPopup.h"
#include "QtPlatformPlugin.h"
#include "UndoStepQt.h"
+#include "WebEventConversion.h"
#include "qwebframe.h"
#include "qwebframe_p.h"
@@ -48,7 +49,6 @@
#include <QBitArray>
#include <QClipboard>
#include <QColorDialog>
-#include <QDebug>
#include <QDesktopWidget>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
@@ -976,7 +976,7 @@ bool QWebPagePrivate::gestureEvent(QGestureEvent* event)
return false;
// QGestureEvents can contain updates for multiple gestures.
bool handled = false;
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
// QGestureEvent lives in Widgets, we'll need a dummy struct to mule the info it contains to the "other side"
QGestureEventFacade gestureFacade;
@@ -1000,7 +1000,7 @@ bool QWebPagePrivate::gestureEvent(QGestureEvent* event)
frame->handleGestureEvent(&gestureFacade);
handled = true;
}
-#endif // ENABLE(GESTURE_EVENTS)
+#endif // ENABLE(QT_GESTURE_EVENTS)
event->setAccepted(handled);
return handled;
@@ -3064,7 +3064,7 @@ bool QWebPage::extension(Extension extension, const ExtensionOption *option, Ext
if (extension == ChooseMultipleFilesExtension) {
// FIXME: do not ignore suggestedFiles
QStringList suggestedFiles = static_cast<const ChooseMultipleFilesExtensionOption*>(option)->suggestedFileNames;
- QStringList names = QFileDialog::getOpenFileNames(view(), QString::null);
+ QStringList names = QFileDialog::getOpenFileNames(view(), QString());
static_cast<ChooseMultipleFilesExtensionReturn*>(output)->fileNames = names;
return true;
}
@@ -3139,9 +3139,9 @@ QString QWebPage::chooseFile(QWebFrame *parentFrame, const QString& suggestedFil
{
Q_UNUSED(parentFrame);
#ifndef QT_NO_FILEDIALOG
- return QFileDialog::getOpenFileName(view(), QString::null, suggestedFile);
+ return QFileDialog::getOpenFileName(view(), QString(), suggestedFile);
#else
- return QString::null;
+ return QString();
#endif
}
diff --git a/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp b/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
index f792befcd..17bc703fc 100644
--- a/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
+++ b/Source/WebKit/qt/tests/qwebframe/tst_qwebframe.cpp
@@ -30,7 +30,6 @@
#include <QComboBox>
#include <QPaintEngine>
#include <QPicture>
-#include <QRegExp>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTextCodec>
diff --git a/Source/WebKit/qt/tests/qwebhistoryinterface/tst_qwebhistoryinterface.cpp b/Source/WebKit/qt/tests/qwebhistoryinterface/tst_qwebhistoryinterface.cpp
index f4571cf74..1612eb7b9 100644
--- a/Source/WebKit/qt/tests/qwebhistoryinterface/tst_qwebhistoryinterface.cpp
+++ b/Source/WebKit/qt/tests/qwebhistoryinterface/tst_qwebhistoryinterface.cpp
@@ -25,7 +25,6 @@
#include <qwebframe.h>
#include <qwebelement.h>
#include <qwebhistoryinterface.h>
-#include <QDebug>
class tst_QWebHistoryInterface : public QObject
{
diff --git a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
index bef98fee6..67fe242f9 100644
--- a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
+++ b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
@@ -28,6 +28,7 @@
#include <QMenu>
#include <QMimeDatabase>
#include <QPushButton>
+#include <QRegExp>
#include <QStateMachine>
#include <QStyle>
#include <QtTest/QtTest>
diff --git a/Source/WebKit/qt/tests/qwebsecurityorigin/tst_qwebsecurityorigin.cpp b/Source/WebKit/qt/tests/qwebsecurityorigin/tst_qwebsecurityorigin.cpp
index 835f243f7..a15838274 100644
--- a/Source/WebKit/qt/tests/qwebsecurityorigin/tst_qwebsecurityorigin.cpp
+++ b/Source/WebKit/qt/tests/qwebsecurityorigin/tst_qwebsecurityorigin.cpp
@@ -19,7 +19,6 @@
*/
-#include <QDebug>
#include <QNetworkReply>
#include <QtTest>
#include <qwebframe.h>
diff --git a/Source/WebKit2/Platform/qt/LoggingQt.cpp b/Source/WebKit2/Platform/qt/LoggingQt.cpp
index 6f7951857..fd7809cce 100644
--- a/Source/WebKit2/Platform/qt/LoggingQt.cpp
+++ b/Source/WebKit2/Platform/qt/LoggingQt.cpp
@@ -28,8 +28,6 @@
#include "config.h"
#include "Logging.h"
-#include <QDebug>
-
namespace WebKit {
#if !LOG_DISABLED
diff --git a/Source/WebKit2/PlatformQt.cmake b/Source/WebKit2/PlatformQt.cmake
index 38080b1a4..3d74594f0 100644
--- a/Source/WebKit2/PlatformQt.cmake
+++ b/Source/WebKit2/PlatformQt.cmake
@@ -75,6 +75,7 @@ list(APPEND WebKit2_SOURCES
Shared/qt/ShareableBitmapQt.cpp
Shared/qt/WebCoreArgumentCodersQt.cpp
Shared/qt/WebEventFactoryQt.cpp
+ Shared/qt/WebGestureEvent.cpp
Shared/unix/ChildProcessMain.cpp
diff --git a/Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp b/Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp
index 8de65216b..96e676d6e 100644
--- a/Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp
+++ b/Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp
@@ -31,7 +31,6 @@
#include "NetscapePluginModule.h"
#include "PluginProcess.h"
#include "WebKit2Initialize.h"
-#include <QDebug>
#include <QGuiApplication>
#include <QStringList>
#include <QtGlobal>
diff --git a/Source/WebKit2/Shared/WebEvent.h b/Source/WebKit2/Shared/WebEvent.h
index 4bfa0d822..c7548203a 100644
--- a/Source/WebKit2/Shared/WebEvent.h
+++ b/Source/WebKit2/Shared/WebEvent.h
@@ -71,6 +71,11 @@ public:
RawKeyDown,
Char,
+#if ENABLE(QT_GESTURE_EVENTS)
+ // WebGestureEvent
+ GestureSingleTap,
+#endif
+
#if ENABLE(TOUCH_EVENTS)
// WebTouchEvent
TouchStart,
@@ -290,6 +295,31 @@ private:
bool m_isSystemKey;
};
+
+#if ENABLE(QT_GESTURE_EVENTS)
+// FIXME: Move this class to its own header file.
+class WebGestureEvent : public WebEvent {
+public:
+ WebGestureEvent() { }
+ WebGestureEvent(Type, const WebCore::IntPoint& position, const WebCore::IntPoint& globalPosition, Modifiers, double timestamp, const WebCore::IntSize& area);
+
+ const WebCore::IntPoint position() const { return m_position; }
+ const WebCore::IntPoint globalPosition() const { return m_globalPosition; }
+ const WebCore::IntSize area() const { return m_area; }
+
+ void encode(IPC::ArgumentEncoder&) const;
+ static bool decode(IPC::ArgumentDecoder&, WebGestureEvent&);
+
+private:
+ static bool isGestureEventType(Type);
+
+ WebCore::IntPoint m_position;
+ WebCore::IntPoint m_globalPosition;
+ WebCore::IntSize m_area;
+};
+#endif // ENABLE(QT_GESTURE_EVENTS)
+
+
#if ENABLE(TOUCH_EVENTS)
#if PLATFORM(IOS)
class WebPlatformTouchPoint {
diff --git a/Source/WebKit2/Shared/WebEventConversion.cpp b/Source/WebKit2/Shared/WebEventConversion.cpp
index eeb74413f..f401a53bd 100644
--- a/Source/WebKit2/Shared/WebEventConversion.cpp
+++ b/Source/WebKit2/Shared/WebEventConversion.cpp
@@ -223,6 +223,46 @@ WebCore::PlatformKeyboardEvent platform(const WebKeyboardEvent& webEvent)
return WebKit2PlatformKeyboardEvent(webEvent);
}
+#if ENABLE(QT_GESTURE_EVENTS)
+class WebKit2PlatformGestureEvent : public WebCore::PlatformGestureEvent {
+public:
+ WebKit2PlatformGestureEvent(const WebGestureEvent& webEvent)
+ {
+ // PlatformEvent
+ switch (webEvent.type()) {
+ case WebEvent::GestureSingleTap:
+ m_type = WebCore::PlatformEvent::GestureTap;
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+
+ m_modifiers = 0;
+ if (webEvent.shiftKey())
+ m_modifiers |= ShiftKey;
+ if (webEvent.controlKey())
+ m_modifiers |= CtrlKey;
+ if (webEvent.altKey())
+ m_modifiers |= AltKey;
+ if (webEvent.metaKey())
+ m_modifiers |= MetaKey;
+
+ m_timestamp = webEvent.timestamp();
+
+ // PlatformGestureEvent
+ m_position = webEvent.position();
+ m_globalPosition = webEvent.globalPosition();
+
+ m_area = webEvent.area();
+ }
+};
+
+WebCore::PlatformGestureEvent platform(const WebGestureEvent& webEvent)
+{
+ return WebKit2PlatformGestureEvent(webEvent);
+}
+#endif
+
#if ENABLE(TOUCH_EVENTS)
#if PLATFORM(IOS)
diff --git a/Source/WebKit2/Shared/WebEventConversion.h b/Source/WebKit2/Shared/WebEventConversion.h
index 827f4f7b2..ea0aad421 100644
--- a/Source/WebKit2/Shared/WebEventConversion.h
+++ b/Source/WebKit2/Shared/WebEventConversion.h
@@ -41,12 +41,20 @@
#include <WebKitAdditions/PlatformGestureEventMac.h>
#endif
+#if ENABLE(QT_GESTURE_EVENTS)
+#include <WebCore/PlatformGestureEvent.h>
+#endif
+
namespace WebKit {
class WebMouseEvent;
class WebWheelEvent;
class WebKeyboardEvent;
+#if ENABLE(QT_GESTURE_EVENTS)
+class WebGestureEvent;
+#endif
+
#if ENABLE(TOUCH_EVENTS)
class WebTouchEvent;
class WebTouchPoint;
@@ -60,6 +68,10 @@ WebCore::PlatformMouseEvent platform(const WebMouseEvent&);
WebCore::PlatformWheelEvent platform(const WebWheelEvent&);
WebCore::PlatformKeyboardEvent platform(const WebKeyboardEvent&);
+#if ENABLE(QT_GESTURE_EVENTS)
+WebCore::PlatformGestureEvent platform(const WebGestureEvent&);
+#endif
+
#if ENABLE(TOUCH_EVENTS)
WebCore::PlatformTouchEvent platform(const WebTouchEvent&);
#if !ENABLE(IOS_TOUCH_EVENTS)
diff --git a/Source/WebKit2/Shared/qt/WebGestureEvent.cpp b/Source/WebKit2/Shared/qt/WebGestureEvent.cpp
new file mode 100644
index 000000000..340658267
--- /dev/null
+++ b/Source/WebKit2/Shared/qt/WebGestureEvent.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * 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 "WebEvent.h"
+
+#if ENABLE(QT_GESTURE_EVENTS)
+
+#include "Arguments.h"
+#include "WebCoreArgumentCoders.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+WebGestureEvent::WebGestureEvent(Type type, const IntPoint& position, const IntPoint& globalPosition, Modifiers modifiers, double timestamp, const IntSize& area/*, const FloatPoint& delta*/)
+ : WebEvent(type, modifiers, timestamp)
+ , m_position(position)
+ , m_globalPosition(globalPosition)
+ , m_area(area)
+{
+ ASSERT(isGestureEventType(type));
+}
+
+void WebGestureEvent::encode(IPC::ArgumentEncoder& encoder) const
+{
+ WebEvent::encode(encoder);
+
+ encoder << m_position;
+ encoder << m_globalPosition;
+ encoder << m_area;
+}
+
+bool WebGestureEvent::decode(IPC::ArgumentDecoder& decoder, WebGestureEvent& t)
+{
+ if (!WebEvent::decode(decoder, t))
+ return false;
+ if (!decoder.decode(t.m_position))
+ return false;
+ if (!decoder.decode(t.m_globalPosition))
+ return false;
+ if (!decoder.decode(t.m_area))
+ return false;
+ return true;
+}
+
+bool WebGestureEvent::isGestureEventType(Type type)
+{
+ return type == GestureSingleTap;
+}
+
+} // namespace WebKit
+
+#endif // ENABLE(QT_GESTURE_EVENTS)
diff --git a/Source/WebKit2/UIProcess/PageClient.h b/Source/WebKit2/UIProcess/PageClient.h
index edb0897b0..86dae0c2a 100644
--- a/Source/WebKit2/UIProcess/PageClient.h
+++ b/Source/WebKit2/UIProcess/PageClient.h
@@ -66,6 +66,10 @@ class WebContextMenuProxy;
class WebEditCommandProxy;
class WebPopupMenuProxy;
+#if ENABLE(QT_GESTURE_EVENTS)
+class WebGestureEvent;
+#endif
+
#if ENABLE(TOUCH_EVENTS)
class NativeWebTouchEvent;
#endif
@@ -223,6 +227,9 @@ public:
#endif
virtual void doneWithKeyEvent(const NativeWebKeyboardEvent&, bool wasEventHandled) = 0;
+#if ENABLE(QT_GESTURE_EVENTS)
+ virtual void doneWithGestureEvent(const WebGestureEvent&, bool wasEventHandled) = 0;
+#endif
#if ENABLE(TOUCH_EVENTS)
virtual void doneWithTouchEvent(const NativeWebTouchEvent&, bool wasEventHandled) = 0;
#endif
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp
index 3e221a920..9b2033f32 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp
@@ -1929,6 +1929,19 @@ void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, cons
#endif // ENABLE(NETSCAPE_PLUGIN_API)
+#if ENABLE(QT_GESTURE_EVENTS)
+void WebPageProxy::handleGestureEvent(const WebGestureEvent& event)
+{
+ if (!isValid())
+ return;
+
+ m_gestureEventQueue.append(event);
+
+ m_process->responsivenessTimer().start();
+ m_process->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0);
+}
+#endif
+
#if ENABLE(TOUCH_EVENTS)
bool WebPageProxy::shouldStartTrackingTouchEvents(const WebTouchEvent& touchStartEvent) const
@@ -4588,6 +4601,9 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
case WebEvent::KeyUp:
case WebEvent::RawKeyDown:
case WebEvent::Char:
+#if ENABLE(QT_GESTURE_EVENTS)
+ case WebEvent::GestureSingleTap:
+#endif
#if ENABLE(TOUCH_EVENTS)
case WebEvent::TouchStart:
case WebEvent::TouchMove:
@@ -4613,6 +4629,16 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
break;
case WebEvent::MouseDown:
break;
+#if ENABLE(QT_GESTURE_EVENTS)
+ case WebEvent::GestureSingleTap: {
+ WebGestureEvent event = m_gestureEventQueue.first();
+ MESSAGE_CHECK(type == event.type());
+
+ m_gestureEventQueue.removeFirst();
+ m_pageClient.doneWithGestureEvent(event, handled);
+ break;
+ }
+#endif
case WebEvent::MouseUp:
m_currentlyProcessedMouseDownEvent = nullptr;
break;
@@ -5147,6 +5173,9 @@ void WebPageProxy::resetStateAfterProcessExited()
m_pendingLearnOrIgnoreWordMessageCount = 0;
// Can't expect DidReceiveEvent notifications from a crashed web process.
+#if ENABLE(QT_GESTURE_EVENTS)
+ m_gestureEventQueue.clear();
+#endif
m_keyEventQueue.clear();
m_wheelEventQueue.clear();
m_currentlyProcessedWheelEvents.clear();
diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h
index fb39d86f4..a404e8664 100644
--- a/Source/WebKit2/UIProcess/WebPageProxy.h
+++ b/Source/WebKit2/UIProcess/WebPageProxy.h
@@ -224,6 +224,10 @@ struct PlatformPopupMenuData;
struct PrintInfo;
struct WebPopupItem;
+#if ENABLE(QT_GESTURE_EVENTS)
+class WebGestureEvent;
+#endif
+
#if ENABLE(VIBRATION)
class WebVibrationProxy;
#endif
@@ -630,6 +634,10 @@ public:
void handleGestureEvent(const NativeWebGestureEvent&);
#endif
+#if ENABLE(QT_GESTURE_EVENTS)
+ void handleGestureEvent(const WebGestureEvent&);
+#endif
+
#if ENABLE(IOS_TOUCH_EVENTS)
void handleTouchEventSynchronously(const NativeWebTouchEvent&);
void handleTouchEventAsynchronously(const NativeWebTouchEvent&);
@@ -1689,6 +1697,9 @@ private:
DownloadID m_syncNavigationActionPolicyDownloadID;
bool m_shouldSuppressAppLinksInNextNavigationPolicyDecision { false };
+#if ENABLE(QT_GESTURE_EVENTS)
+ Deque<WebGestureEvent> m_gestureEventQueue;
+#endif
Deque<NativeWebKeyboardEvent> m_keyEventQueue;
Deque<NativeWebWheelEvent> m_wheelEventQueue;
Deque<std::unique_ptr<Vector<NativeWebWheelEvent>>> m_currentlyProcessedWheelEvents;
diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp
index 1b62c94ba..d5afa7996 100644
--- a/Source/WebKit2/UIProcess/qt/QtPageClient.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtPageClient.cpp
@@ -251,7 +251,7 @@ void QtPageClient::handleWillSetInputMethodState()
m_eventHandler->handleWillSetInputMethodState();
}
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
void QtPageClient::doneWithGestureEvent(const WebGestureEvent& event, bool wasEventHandled)
{
ASSERT(m_eventHandler);
diff --git a/Source/WebKit2/UIProcess/qt/QtPageClient.h b/Source/WebKit2/UIProcess/qt/QtPageClient.h
index 393629731..a30b25dd3 100644
--- a/Source/WebKit2/UIProcess/qt/QtPageClient.h
+++ b/Source/WebKit2/UIProcess/qt/QtPageClient.h
@@ -93,7 +93,7 @@ public:
void didFindZoomableArea(const WebCore::IntPoint&, const WebCore::IntRect&) override;
void updateTextInputState() override;
void handleWillSetInputMethodState() override;
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
void doneWithGestureEvent(const WebGestureEvent&, bool wasEventHandled) override;
#endif
#if ENABLE(TOUCH_EVENTS)
diff --git a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp
index 9b620fb9d..b56f475cc 100644
--- a/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp
+++ b/Source/WebKit2/UIProcess/qt/QtWebPageEventHandler.cpp
@@ -261,12 +261,12 @@ void QtWebPageEventHandler::deactivateTapHighlight()
void QtWebPageEventHandler::handleSingleTapEvent(const QTouchEvent::TouchPoint& point)
{
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
deactivateTapHighlight();
m_postponeTextInputStateChanged = true;
QTransform fromItemTransform = m_webPage->transformFromItem();
- WebGestureEvent gesture(WebEvent::GestureSingleTap, fromItemTransform.map(point.pos()).toPoint(), point.screenPos().toPoint(), WebEvent::Modifiers(0), 0, IntSize(point.rect().size().toSize()), FloatPoint(0, 0));
+ WebGestureEvent gesture(WebEvent::GestureSingleTap, fromItemTransform.map(point.pos()).toPoint(), point.screenPos().toPoint(), WebEvent::Modifiers(0), 0, IntSize(point.rect().size().toSize()));
m_webPageProxy->handleGestureEvent(gesture);
#endif
}
@@ -448,7 +448,7 @@ void QtWebPageEventHandler::handleWillSetInputMethodState()
void QtWebPageEventHandler::doneWithGestureEvent(const WebGestureEvent& event, bool wasEventHandled)
{
-#if ENABLE(GESTURE_EVENTS)
+#if ENABLE(QT_GESTURE_EVENTS)
if (event.type() != WebEvent::GestureSingleTap)
return;
diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp
index 3418d8b0c..ee7d32600 100644
--- a/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp
+++ b/Source/WebKit2/WebProcess/Plugins/Netscape/x11/NetscapePluginX11.cpp
@@ -488,6 +488,9 @@ bool NetscapePluginX11::handleMouseEvent(const WebMouseEvent& event)
case WebEvent::KeyUp:
case WebEvent::RawKeyDown:
case WebEvent::Char:
+#if ENABLE(QT_GESTURE_EVENTS)
+ case WebEvent::GestureSingleTap:
+#endif
#if ENABLE(TOUCH_EVENTS)
case WebEvent::TouchStart:
case WebEvent::TouchMove:
diff --git a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp
index 345648baa..a3335430a 100644
--- a/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/CoordinatedGraphics/WebPageCoordinatedGraphics.cpp
@@ -45,6 +45,26 @@ using namespace WebCore;
namespace WebKit {
#if USE(COORDINATED_GRAPHICS_MULTIPROCESS)
+
+#if ENABLE(TOUCH_ADJUSTMENT)
+void WebPage::findZoomableAreaForPoint(const IntPoint& point, const IntSize& area)
+{
+ Node* node = 0;
+ IntRect zoomableArea;
+ bool foundAreaForTouchPoint = m_mainFrame->coreFrame()->eventHandler().bestZoomableAreaForTouchPoint(point, IntSize(area.width() / 2, area.height() / 2), zoomableArea, node);
+
+ if (!foundAreaForTouchPoint)
+ return;
+
+ ASSERT(node);
+
+ if (node->document().view())
+ zoomableArea = node->document().view()->contentsToWindow(zoomableArea);
+
+ send(Messages::WebPageProxy::DidFindZoomableArea(point, zoomableArea));
+}
+
+#else
void WebPage::findZoomableAreaForPoint(const IntPoint& point, const IntSize& area)
{
UNUSED_PARAM(area);
@@ -85,6 +105,8 @@ void WebPage::findZoomableAreaForPoint(const IntPoint& point, const IntSize& are
send(Messages::WebPageProxy::DidFindZoomableArea(point, zoomableArea));
}
+#endif // ENABLE(TOUCH_ADJUSTMENT)
+
#endif
} // namespace WebKit
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
index b96398ed3..cac0abfbc 100644
--- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.cpp
@@ -144,7 +144,7 @@ void EventDispatcher::wheelEvent(uint64_t pageID, const WebWheelEvent& wheelEven
});
}
-#if ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS) || ENABLE(QT_GESTURE_EVENTS)
void EventDispatcher::gestureEvent(uint64_t pageID, const WebKit::WebGestureEvent& gestureEvent)
{
RefPtr<EventDispatcher> eventDispatcher = this;
@@ -224,7 +224,7 @@ void EventDispatcher::dispatchWheelEvent(uint64_t pageID, const WebWheelEvent& w
webPage->wheelEvent(wheelEvent);
}
-#if ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS) || ENABLE(QT_GESTURE_EVENTS)
void EventDispatcher::dispatchGestureEvent(uint64_t pageID, const WebGestureEvent& gestureEvent)
{
ASSERT(RunLoop::isMain());
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
index 8374a83fe..3b088e927 100644
--- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.h
@@ -81,7 +81,7 @@ private:
#if ENABLE(IOS_TOUCH_EVENTS)
void touchEvent(uint64_t pageID, const WebTouchEvent&);
#endif
-#if ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS) || ENABLE(QT_GESTURE_EVENTS)
void gestureEvent(uint64_t pageID, const WebGestureEvent&);
#endif
@@ -91,7 +91,7 @@ private:
#if ENABLE(IOS_TOUCH_EVENTS)
void dispatchTouchEvents();
#endif
-#if ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS) || ENABLE(QT_GESTURE_EVENTS)
void dispatchGestureEvent(uint64_t pageID, const WebGestureEvent&);
#endif
diff --git a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
index 5e1543c98..8044fc614 100644
--- a/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
+++ b/Source/WebKit2/WebProcess/WebPage/EventDispatcher.messages.in
@@ -25,7 +25,7 @@ messages -> EventDispatcher {
#if ENABLE(IOS_TOUCH_EVENTS)
TouchEvent(uint64_t pageID, WebKit::WebTouchEvent event)
#endif
-#if ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS) || ENABLE(QT_GESTURE_EVENTS)
GestureEvent(uint64_t pageID, WebKit::WebGestureEvent event)
#endif
}
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index 2cd709f22..6eafa5123 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -2368,7 +2368,7 @@ void WebPage::touchEvent(const WebTouchEvent& touchEvent)
}
#endif
-#if ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS) || ENABLE(QT_GESTURE_EVENTS)
static bool handleGestureEvent(const WebGestureEvent& event, Page* page)
{
if (!page->mainFrame().view())
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.h b/Source/WebKit2/WebProcess/WebPage/WebPage.h
index 8be9a42a9..a41239ac6 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.h
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.h
@@ -210,6 +210,10 @@ struct WebPreferencesStore;
class RemoteLayerTreeTransaction;
#endif
+#if ENABLE(QT_GESTURE_EVENTS)
+class WebGestureEvent;
+#endif
+
#if ENABLE(TOUCH_EVENTS)
class WebTouchEvent;
#endif
@@ -811,7 +815,7 @@ public:
void wheelEventHandlersChanged(bool);
void recomputeShortCircuitHorizontalWheelEventsState();
-#if ENABLE(MAC_GESTURE_EVENTS)
+#if ENABLE(MAC_GESTURE_EVENTS) || ENABLE(QT_GESTURE_EVENTS)
void gestureEvent(const WebGestureEvent&);
#endif
diff --git a/Source/cmake/OptionsCommon.cmake b/Source/cmake/OptionsCommon.cmake
index ddaa23327..6a32559a0 100644
--- a/Source/cmake/OptionsCommon.cmake
+++ b/Source/cmake/OptionsCommon.cmake
@@ -44,6 +44,33 @@ if (WIN32 AND COMPILER_IS_GCC_OR_CLANG)
add_definitions(-D__USE_MINGW_ANSI_STDIO=1)
endif ()
+# Ensure that the default include system directories are added to the list of CMake implicit includes.
+# This workarounds an issue that happens when using GCC 6 and using system includes (-isystem).
+# For more details check: https://bugs.webkit.org/show_bug.cgi?id=161697
+macro(DETERMINE_GCC_SYSTEM_INCLUDE_DIRS _lang _compiler _flags _result)
+ file(WRITE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy" "\n")
+ separate_arguments(_buildFlags UNIX_COMMAND "${_flags}")
+ execute_process(COMMAND ${_compiler} ${_buildFlags} -v -E -x ${_lang} -dD dummy
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/CMakeFiles OUTPUT_QUIET
+ ERROR_VARIABLE _gccOutput)
+ file(REMOVE "${CMAKE_BINARY_DIR}/CMakeFiles/dummy")
+ if ("${_gccOutput}" MATCHES "> search starts here[^\n]+\n *(.+) *\n *End of (search) list")
+ set(${_result} ${CMAKE_MATCH_1})
+ string(REPLACE "\n" " " ${_result} "${${_result}}")
+ separate_arguments(${_result})
+ endif ()
+endmacro()
+
+if (CMAKE_COMPILER_IS_GNUCC)
+ DETERMINE_GCC_SYSTEM_INCLUDE_DIRS("c" "${CMAKE_C_COMPILER}" "${CMAKE_C_FLAGS}" SYSTEM_INCLUDE_DIRS)
+ set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES} ${SYSTEM_INCLUDE_DIRS})
+endif ()
+
+if (CMAKE_COMPILER_IS_GNUCXX)
+ DETERMINE_GCC_SYSTEM_INCLUDE_DIRS("c++" "${CMAKE_CXX_COMPILER}" "${CMAKE_CXX_FLAGS}" SYSTEM_INCLUDE_DIRS)
+ set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES} ${SYSTEM_INCLUDE_DIRS})
+endif ()
+
# Detect Cortex-A53 core if CPU is ARM64 and OS is Linux.
# Query /proc/cpuinfo for each available core and check reported CPU part number: 0xd03 signals Cortex-A53.
# (see Main ID Register in ARM Cortex-A53 MPCore Processor Technical Reference Manual)
diff --git a/Source/cmake/OptionsQt.cmake b/Source/cmake/OptionsQt.cmake
index 8f06820c5..d57e9133c 100644
--- a/Source/cmake/OptionsQt.cmake
+++ b/Source/cmake/OptionsQt.cmake
@@ -110,6 +110,9 @@ else ()
set(ENABLE_NETSCAPE_PLUGIN_API_DEFAULT OFF)
endif ()
+# Public options specific to the Qt port. Do not add any options here unless
+# there is a strong reason we should support changing the value of the option,
+# and the option is not relevant to any other WebKit ports.
WEBKIT_OPTION_DEFINE(USE_GSTREAMER "Use GStreamer implementation of MediaPlayer" PUBLIC ${USE_GSTREAMER_DEFAULT})
WEBKIT_OPTION_DEFINE(USE_LIBHYPHEN "Use automatic hyphenation with LibHyphen" PUBLIC ${USE_LIBHYPHEN_DEFAULT})
WEBKIT_OPTION_DEFINE(USE_MEDIA_FOUNDATION "Use MediaFoundation implementation of MediaPlayer" PUBLIC OFF)
@@ -118,6 +121,7 @@ WEBKIT_OPTION_DEFINE(USE_WOFF2 "Include support of WOFF2 fonts format" PUBLIC ON
WEBKIT_OPTION_DEFINE(ENABLE_INSPECTOR_UI "Include Inspector UI into resources" PUBLIC ON)
WEBKIT_OPTION_DEFINE(ENABLE_OPENGL "Whether to use OpenGL." PUBLIC ON)
WEBKIT_OPTION_DEFINE(ENABLE_PRINT_SUPPORT "Enable support for printing web pages" PUBLIC ON)
+WEBKIT_OPTION_DEFINE(ENABLE_QT_GESTURE_EVENTS "Enable support for gesture events (required for mouse in WK2)" PUBLIC ON)
WEBKIT_OPTION_DEFINE(ENABLE_X11_TARGET "Whether to enable support for the X11 windowing target." PUBLIC ${ENABLE_X11_TARGET_DEFAULT})
option(GENERATE_DOCUMENTATION "Generate HTML and QCH documentation" OFF)
@@ -125,6 +129,11 @@ cmake_dependent_option(ENABLE_TEST_SUPPORT "Build tools for running layout tests
"DEVELOPER_MODE" OFF)
option(USE_STATIC_RUNTIME "Use static runtime (MSVC only)" OFF)
+# Private options specific to the Qt port. Changing these options is
+# completely unsupported. They are intended for use only by WebKit developers.
+WEBKIT_OPTION_DEFINE(ENABLE_TOUCH_ADJUSTMENT "Whether to use touch adjustment" PRIVATE ON)
+
+
# Public options shared with other WebKit ports. There must be strong reason
# to support changing the value of the option.
WEBKIT_OPTION_DEFAULT_PORT_VALUE(ENABLE_ACCELERATED_2D_CANVAS PUBLIC ON)
diff --git a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
index e9c39f9b2..e72ee703a 100644
--- a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
+++ b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp
@@ -64,6 +64,7 @@
#include <QPrinter>
#endif
#include <QProgressBar>
+#include <QRegExp>
#include <QUndoStack>
#include <QUrl>
#include <limits.h>
diff --git a/Tools/DumpRenderTree/qt/EventSenderQt.cpp b/Tools/DumpRenderTree/qt/EventSenderQt.cpp
index 666a2475e..563286526 100644
--- a/Tools/DumpRenderTree/qt/EventSenderQt.cpp
+++ b/Tools/DumpRenderTree/qt/EventSenderQt.cpp
@@ -576,7 +576,7 @@ void EventSender::gestureTap(int x, int y)
m_gestures.clear();
m_gestures.append(&m_tapGesture);
QGestureEvent event(m_gestures);
- sendEvent(m_page, &event);
+ sendEvent(m_page->view(), &event);
}
void EventSender::gestureLongPress(int x, int y)
@@ -585,7 +585,7 @@ void EventSender::gestureLongPress(int x, int y)
m_gestures.clear();
m_gestures.append(&m_tapAndHoldGesture);
QGestureEvent event(m_gestures);
- sendEvent(m_page, &event);
+ sendEvent(m_page->view(), &event);
}
#endif
diff --git a/Tools/MiniBrowser/qt/main.cpp b/Tools/MiniBrowser/qt/main.cpp
index 4c8cd92ab..b688aa7ef 100644
--- a/Tools/MiniBrowser/qt/main.cpp
+++ b/Tools/MiniBrowser/qt/main.cpp
@@ -35,7 +35,6 @@
#include <QDir>
#include <QLatin1String>
-#include <QRegExp>
int main(int argc, char** argv)
{
diff --git a/Tools/QtTestBrowser/CMakeLists.txt b/Tools/QtTestBrowser/CMakeLists.txt
index 485cd0ca1..ab625f6e5 100644
--- a/Tools/QtTestBrowser/CMakeLists.txt
+++ b/Tools/QtTestBrowser/CMakeLists.txt
@@ -67,3 +67,7 @@ include_directories(SYSTEM ${QtTestBrowser_SYSTEM_INCLUDE_DIRECTORIES})
add_executable(QtTestBrowser ${QtTestBrowser_SOURCES})
target_link_libraries(QtTestBrowser ${QtTestBrowser_LIBRARIES})
set_target_properties(QtTestBrowser PROPERTIES FOLDER "Tools")
+
+if (${CMAKE_BUILD_TYPE} MATCHES "Release")
+ set_target_properties(QtTestBrowser PROPERTIES WIN32_EXECUTABLE ON)
+endif ()
diff --git a/Tools/QtTestBrowser/qttestbrowser.cpp b/Tools/QtTestBrowser/qttestbrowser.cpp
index 4ec7425b1..24ca97a7a 100644
--- a/Tools/QtTestBrowser/qttestbrowser.cpp
+++ b/Tools/QtTestBrowser/qttestbrowser.cpp
@@ -47,6 +47,7 @@ WindowOptions windowOptions;
#include <QFile>
#include <QFileInfo>
#include <QFontDatabase>
+#include <QRegExp>
int launcherMain(const QApplication& app)
{
diff --git a/Tools/Scripts/update-qtwebkit-win-libs b/Tools/Scripts/update-qtwebkit-win-libs
index 8227ba933..da813f855 100644
--- a/Tools/Scripts/update-qtwebkit-win-libs
+++ b/Tools/Scripts/update-qtwebkit-win-libs
@@ -35,7 +35,7 @@ use FindBin;
my $file = "qtwebkit-libs-win";
my $zipFile = "$file.zip";
-my $winQtLibsURL = "https://dl.dropboxusercontent.com/u/30021413/$zipFile";
+my $winQtLibsURL = "https://github.com/Vitallium/qtwebkit-libs-win/releases/download/2015/$zipFile";
my $command = "$FindBin::Bin/update-webkit-dependency";
system("perl", $command, $winQtLibsURL, ".") == 0 or die;
diff --git a/Tools/qmake/mkspecs/features/functions.prf b/Tools/qmake/mkspecs/features/functions.prf
index 3a775dcfd..3e0d40610 100644
--- a/Tools/qmake/mkspecs/features/functions.prf
+++ b/Tools/qmake/mkspecs/features/functions.prf
@@ -51,6 +51,8 @@ defineReplace(appleSdkVersion) {
}
defineTest(isPlatformSupported) {
+ !qtHaveModule(widgets): skipBuild("QtWidgets module is required to build QtWebKit.")
+
cross_compile: skipBuild("cross-compilation of QtWebKit with qmake is not supported yet")
requiredPrograms = cmake gperf python perl bison ruby flex
diff --git a/Tools/qmake/projects/run_cmake.pro b/Tools/qmake/projects/run_cmake.pro
index 1b8742c4a..e0c615b0a 100644
--- a/Tools/qmake/projects/run_cmake.pro
+++ b/Tools/qmake/projects/run_cmake.pro
@@ -70,7 +70,7 @@ build_pass|!debug_and_release {
QMAKE_MAC_SDK_PATH = $$system("/usr/bin/xcodebuild -sdk $${QMAKE_MAC_SDK} -version Path 2>/dev/null")
}
exists($$QMAKE_MAC_SDK_PATH): CMAKE_CONFIG += CMAKE_OSX_SYSROOT=$$QMAKE_MAC_SDK_PATH
- !isEmpty($$QMAKE_MACOSX_DEPLOYMENT_TARGET): CMAKE_CONFIG += CMAKE_OSX_DEPLOYMENT_TARGET=$$QMAKE_MACOSX_DEPLOYMENT_TARGET
+ !isEmpty(QMAKE_MACOSX_DEPLOYMENT_TARGET): CMAKE_CONFIG += CMAKE_OSX_DEPLOYMENT_TARGET=$$QMAKE_MACOSX_DEPLOYMENT_TARGET
}
equals(QMAKE_HOST.os, Windows) {