COMMIT_MESSAGE (1/3)

 12012-02-16 Antonio Gomes <agomes@rim.com>
 2
 3 [BlackBerry] Upstream touch handling related classes
 4 https://bugs.webkit.org/show_bug.cgi?id=78509
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Initial upstream of the Blackberry specific single touch event
 9 handler class.
 10
 11 * blackberry/WebKitSupport/TouchEventHandler.cpp: Added.
 12 (WebKit):
 13 (BlackBerry::WebKit::hasMouseMoveListener):
 14 (BlackBerry::WebKit::hasTouchListener):
 15 (BlackBerry::WebKit::elementExpectsMouseEvents):
 16 (BlackBerry::WebKit::shouldConvertTouchToMouse):
 17 (BlackBerry::WebKit::TouchEventHandler::TouchEventHandler):
 18 (BlackBerry::WebKit::TouchEventHandler::~TouchEventHandler):
 19 (BlackBerry::WebKit::TouchEventHandler::shouldSuppressMouseDownOnTouchDown):
 20 (BlackBerry::WebKit::TouchEventHandler::touchEventCancel):
 21 (BlackBerry::WebKit::TouchEventHandler::touchHoldEvent):
 22 (BlackBerry::WebKit::TouchEventHandler::handleTouchPoint):
 23 (BlackBerry::WebKit::TouchEventHandler::spellCheck):
 24 (BlackBerry::WebKit::TouchEventHandler::handleFatFingerPressed):
 25 (BlackBerry::WebKit::elementForTapHighlight):
 26 (BlackBerry::WebKit::TouchEventHandler::drawTapHighlight):
 27 * blackberry/WebKitSupport/TouchEventHandler.h: Added.
 28 (WebCore):
 29 (WebKit):
 30 (TouchEventHandler):
 31 (BlackBerry::WebKit::TouchEventHandler::lastFatFingersResult):
 32 (BlackBerry::WebKit::TouchEventHandler::resetLastFatFingersResult):

Source/WebKit/blackberry/ChangeLog

 12012-02-16 Antonio Gomes <agomes@rim.com>
 2
 3 [BlackBerry] Upstream touch handling related classes
 4 https://bugs.webkit.org/show_bug.cgi?id=78509
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Initial upstream of the Blackberry specific single touch event
 9 handler class.
 10
 11 * blackberry/WebKitSupport/TouchEventHandler.cpp: Added.
 12 (WebKit):
 13 (BlackBerry::WebKit::hasMouseMoveListener):
 14 (BlackBerry::WebKit::hasTouchListener):
 15 (BlackBerry::WebKit::elementExpectsMouseEvents):
 16 (BlackBerry::WebKit::shouldConvertTouchToMouse):
 17 (BlackBerry::WebKit::TouchEventHandler::TouchEventHandler):
 18 (BlackBerry::WebKit::TouchEventHandler::~TouchEventHandler):
 19 (BlackBerry::WebKit::TouchEventHandler::shouldSuppressMouseDownOnTouchDown):
 20 (BlackBerry::WebKit::TouchEventHandler::touchEventCancel):
 21 (BlackBerry::WebKit::TouchEventHandler::touchHoldEvent):
 22 (BlackBerry::WebKit::TouchEventHandler::handleTouchPoint):
 23 (BlackBerry::WebKit::TouchEventHandler::spellCheck):
 24 (BlackBerry::WebKit::TouchEventHandler::handleFatFingerPressed):
 25 (BlackBerry::WebKit::elementForTapHighlight):
 26 (BlackBerry::WebKit::TouchEventHandler::drawTapHighlight):
 27 * blackberry/WebKitSupport/TouchEventHandler.h: Added.
 28 (WebCore):
 29 (WebKit):
 30 (TouchEventHandler):
 31 (BlackBerry::WebKit::TouchEventHandler::lastFatFingersResult):
 32 (BlackBerry::WebKit::TouchEventHandler::resetLastFatFingersResult):
 33

Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.cpp

 1/*
 2 * Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Lesser General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Lesser General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Lesser General Public
 15 * License along with this library; if not, write to the Free Software
 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 17 */
 18
 19#include "config.h"
 20#include "TouchEventHandler.h"
 21
 22#include "DOMSupport.h"
 23#include "Document.h"
 24#include "DocumentMarkerController.h"
 25#include "FatFingers.h"
 26#include "FocusController.h"
 27#include "Frame.h"
 28#include "FrameView.h"
 29#include "HTMLAnchorElement.h"
 30#include "HTMLAreaElement.h"
 31#include "HTMLImageElement.h"
 32#include "HTMLInputElement.h"
 33#include "HTMLNames.h"
 34#include "HTMLPlugInElement.h"
 35#include "InputHandler.h"
 36#include "IntRect.h"
 37#include "IntSize.h"
 38#include "Node.h"
 39#include "Page.h"
 40#include "PlatformMouseEvent.h"
 41#include "PlatformTouchEvent.h"
 42#include "RenderLayer.h"
 43#include "RenderTheme.h"
 44#include "RenderView.h"
 45#include "RenderedDocumentMarker.h"
 46#include "SelectionHandler.h"
 47#include "WebPage_p.h"
 48#include "WebSettings.h"
 49
 50#include <wtf/MathExtras.h>
 51
 52using namespace WebCore;
 53using namespace WTF;
 54
 55namespace BlackBerry {
 56namespace WebKit {
 57
 58static bool hasMouseMoveListener(Element* element)
 59{
 60 ASSERT(element);
 61 return element->hasEventListeners(eventNames().mousemoveEvent) || element->document()->hasEventListeners(eventNames().mousemoveEvent);
 62}
 63
 64static bool hasTouchListener(Element* element)
 65{
 66 ASSERT(element);
 67 return element->hasEventListeners(eventNames().touchstartEvent)
 68 || element->hasEventListeners(eventNames().touchmoveEvent)
 69 || element->hasEventListeners(eventNames().touchcancelEvent)
 70 || element->hasEventListeners(eventNames().touchendEvent);
 71}
 72
 73static bool elementExpectsMouseEvents(Element* element)
 74{
 75 // Make sure we are not operating a shadow node here, since the webpages
 76 // aren't able to attach event listeners to shadow content.
 77 while (element->isInShadowTree())
 78 element = toElement(element->shadowAncestorNode());
 79
 80 return hasMouseMoveListener(element) && !hasTouchListener(element);
 81}
 82
 83static bool shouldConvertTouchToMouse(Element* element)
 84{
 85 if (!element)
 86 return false;
 87
 88 // Range element are a special case that require natural mouse events in order to allow
 89 // dragging of the slider handle.
 90 if (element->hasTagName(HTMLNames::inputTag)) {
 91 HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(element);
 92 if (inputElement->isRangeControl())
 93 return true;
 94 }
 95
 96 // Check for plugin
 97 if ((element->hasTagName(HTMLNames::objectTag) || element->hasTagName(HTMLNames::embedTag)) && static_cast<HTMLPlugInElement*>(element))
 98 return true;
 99
 100 // Check if the element has a mouse listener and no touch listener. If so,
 101 // the field will require touch events be converted to mouse events to function properly.
 102 if (elementExpectsMouseEvents(element))
 103 return true;
 104
 105 return false;
 106}
 107
 108TouchEventHandler::TouchEventHandler(WebPagePrivate* webpage)
 109 : m_webPage(webpage)
 110 , m_didCancelTouch(false)
 111 , m_convertTouchToMouse(false)
 112 , m_existingTouchMode(ProcessedTouchEvents)
 113{
 114}
 115
 116TouchEventHandler::~TouchEventHandler()
 117{
 118}
 119
 120bool TouchEventHandler::shouldSuppressMouseDownOnTouchDown() const
 121{
 122 return m_lastFatFingersResult.isTextInput() || m_webPage->m_inputHandler->isInputMode() || m_webPage->m_selectionHandler->isSelectionActive();
 123}
 124
 125void TouchEventHandler::touchEventCancel()
 126{
 127 m_webPage->m_inputHandler->processPendingClientNavigationModeChangeNotification();
 128
 129 if (!shouldSuppressMouseDownOnTouchDown()) {
 130 // Input elements delay mouse down and do not need to be released on touch cancel.
 131 m_webPage->m_page->focusController()->focusedOrMainFrame()->eventHandler()->setMousePressed(false);
 132 }
 133 m_convertTouchToMouse = false;
 134 m_didCancelTouch = true;
 135
 136 // If we cancel a single touch event, we need to also clean up any hover
 137 // state we get into by synthetically moving the mouse to the m_fingerPoint.
 138 Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable();
 139 if (elementUnderFatFinger && elementUnderFatFinger->renderer()) {
 140
 141 HitTestRequest request(HitTestRequest::FingerUp);
 142 // The HitTestResult point is not actually needed.
 143 HitTestResult result(IntPoint::zero());
 144 result.setInnerNode(elementUnderFatFinger);
 145
 146 Document* document = elementUnderFatFinger->document();
 147 ASSERT(document);
 148 document->renderView()->layer()->updateHoverActiveState(request, result);
 149 document->updateStyleIfNeeded();
 150 // Updating the document style may destroy the renderer.
 151 if (elementUnderFatFinger->renderer())
 152 elementUnderFatFinger->renderer()->repaint();
 153 ASSERT(!elementUnderFatFinger->hovered());
 154 }
 155
 156 m_lastFatFingersResult.reset();
 157}
 158
 159void TouchEventHandler::touchEventCancelAndClearFocusedNode()
 160{
 161 touchEventCancel();
 162 m_webPage->clearFocusNode();
 163}
 164
 165void TouchEventHandler::touchHoldEvent()
 166{
 167 // This is a hack for our hack that converts the touch pressed event that we've delayed because the user has focused a input field
 168 // to the page as a mouse pressed event.
 169 if (shouldSuppressMouseDownOnTouchDown())
 170 handleFatFingerPressed();
 171
 172 // Clear the focus ring indication if tap-and-hold'ing on a link.
 173 if (m_lastFatFingersResult.validNode() && m_lastFatFingersResult.validNode()->isLink())
 174 m_webPage->clearFocusNode();
 175}
 176
 177bool TouchEventHandler::handleTouchPoint(BlackBerry::Platform::TouchPoint& point)
 178{
 179 switch (point.m_state) {
 180 case BlackBerry::Platform::TouchPoint::TouchPressed:
 181 {
 182 m_lastFatFingersResult.reset(); // Theoretically this shouldn't be required. Keep it just in case states get mangled.
 183 m_didCancelTouch = false;
 184 m_lastScreenPoint = point.m_screenPos;
 185
 186 IntPoint contentPos(m_webPage->mapFromViewportToContents(point.m_pos));
 187
 188 m_lastFatFingersResult = FatFingers(m_webPage, contentPos, FatFingers::ClickableElement).findBestPoint();
 189
 190 Element* elementUnderFatFinger = 0;
 191 if (m_lastFatFingersResult.positionWasAdjusted() && m_lastFatFingersResult.validNode()) {
 192 ASSERT(m_lastFatFingersResult.validNode()->isElementNode());
 193 elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable();
 194 }
 195
 196 // Set or reset the touch mode.
 197 Element* possibleTargetNodeForMouseMoveEvents = static_cast<Element*>(m_lastFatFingersResult.positionWasAdjusted() ? elementUnderFatFinger : m_lastFatFingersResult.validNode());
 198 m_convertTouchToMouse = shouldConvertTouchToMouse(possibleTargetNodeForMouseMoveEvents);
 199
 200 if (elementUnderFatFinger)
 201 drawTapHighlight();
 202
 203 // Lets be conservative here: since we have problems on major website having
 204 // mousemove listener for no good reason (e.g. google.com, desktop edition),
 205 // let only delay client notifications when there is not input text node involved.
 206 if (m_convertTouchToMouse
 207 && (m_webPage->m_inputHandler->isInputMode() && !m_lastFatFingersResult.isTextInput())) {
 208 m_webPage->m_inputHandler->setDelayClientNotificationOfNavigationModeChange(true);
 209 handleFatFingerPressed();
 210 } else if (!shouldSuppressMouseDownOnTouchDown())
 211 handleFatFingerPressed();
 212
 213 return true;
 214 }
 215 case BlackBerry::Platform::TouchPoint::TouchReleased:
 216 {
 217 m_webPage->m_inputHandler->processPendingClientNavigationModeChangeNotification();
 218
 219 if (shouldSuppressMouseDownOnTouchDown())
 220 handleFatFingerPressed();
 221
 222 // The rebase has eliminated a necessary event when the mouse does not
 223 // trigger an actual selection change preventing re-showing of the
 224 // keyboard. If input mode is active, call setNavigationMode which
 225 // will update the state and display keyboard if needed.
 226 if (m_webPage->m_inputHandler->isInputMode())
 227 m_webPage->m_inputHandler->setNavigationMode(true);
 228
 229 IntPoint adjustedPoint;
 230 if (m_convertTouchToMouse) {
 231 adjustedPoint = point.m_pos;
 232 m_convertTouchToMouse = false;
 233 } else // Fat finger point in viewport coordinates.
 234 adjustedPoint = m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition());
 235
 236 // Create MouseReleased Event.
 237 PlatformMouseEvent mouseEvent(adjustedPoint, m_lastScreenPoint, MouseEventReleased, 1, LeftButton, TouchScreen);
 238 m_webPage->handleMouseEvent(mouseEvent);
 239 m_lastFatFingersResult.reset(); // reset the fat finger result as its no longer valid when a user's finger is not on the screen.
 240
 241 unsigned int spellLength = spellCheck(point);
 242 if (spellLength) {
 243 unsigned int end = m_webPage->m_inputHandler->caretPosition();
 244 unsigned int start = end - spellLength;
 245 m_webPage->m_client->requestSpellingSuggestionsForString(start, end);
 246 }
 247 return true;
 248 }
 249 case BlackBerry::Platform::TouchPoint::TouchMoved:
 250 if (m_convertTouchToMouse) {
 251 PlatformMouseEvent mouseEvent(point.m_pos, m_lastScreenPoint, MouseEventMoved, 1, LeftButton, TouchScreen);
 252 m_lastScreenPoint = point.m_screenPos;
 253 if (!m_webPage->handleMouseEvent(mouseEvent)) {
 254 m_convertTouchToMouse = false;
 255 return false;
 256 }
 257 return true;
 258 }
 259 break;
 260 default:
 261 break;
 262 }
 263 return false;
 264}
 265
 266unsigned TouchEventHandler::spellCheck(BlackBerry::Platform::TouchPoint& touchPoint)
 267{
 268 Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable();
 269 if (!m_lastFatFingersResult.isTextInput() || !elementUnderFatFinger)
 270 return 0;
 271
 272 IntPoint contentPos(m_webPage->mapFromViewportToContents(touchPoint.m_pos));
 273 contentPos = DOMSupport::convertPointToFrame(m_webPage->mainFrame(), m_webPage->focusedOrMainFrame(), contentPos);
 274
 275 Document* document = elementUnderFatFinger->document();
 276 ASSERT(document);
 277 RenderedDocumentMarker* marker = document->markers()->renderedMarkerContainingPoint(contentPos, DocumentMarker::Spelling);
 278 if (!marker)
 279 return 0;
 280
 281 IntRect rect = marker->renderedRect();
 282 IntPoint newContentPos = IntPoint(rect.x() + rect.width(), rect.y() + rect.height() / 2); // midway of right edge
 283 Frame* frame = m_webPage->focusedOrMainFrame();
 284 if (frame != m_webPage->mainFrame())
 285 newContentPos = m_webPage->mainFrame()->view()->windowToContents(frame->view()->contentsToWindow(newContentPos));
 286 m_lastFatFingersResult.m_adjustedPosition = newContentPos;
 287 m_lastFatFingersResult.m_positionWasAdjusted = true;
 288 return marker->endOffset() - marker->startOffset();
 289}
 290
 291void TouchEventHandler::handleFatFingerPressed()
 292{
 293 if (!m_didCancelTouch) {
 294
 295 // Convert touch event to a mouse event
 296 // First update the mouse position with a MouseMoved event
 297 // Send the mouse move event
 298 PlatformMouseEvent mouseMoveEvent(m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()), m_lastScreenPoint, MouseEventMoved, 0, LeftButton, TouchScreen);
 299 m_webPage->handleMouseEvent(mouseMoveEvent);
 300
 301 // Then send the MousePressed event
 302 PlatformMouseEvent mousePressedEvent(m_webPage->mapFromContentsToViewport(m_lastFatFingersResult.adjustedPosition()), m_lastScreenPoint, MouseEventPressed, 1, LeftButton, TouchScreen);
 303 m_webPage->handleMouseEvent(mousePressedEvent);
 304 }
 305}
 306
 307// This method filters what element will get tap-highlight'ed or not. To start with,
 308// we are going to highlight links (anchors with a valid href element), and elements
 309// whose tap highlight color value is different than the default value.
 310static Element* elementForTapHighlight(Element* elementUnderFatFinger)
 311{
 312 bool isArea = elementUnderFatFinger->hasTagName(HTMLNames::areaTag);
 313
 314 // Do not bail out right way here if there element does not have a renderer. It is the case
 315 // for <map> (descendent of <area>) elements. The associated <image> element actually has the
 316 // renderer.
 317 if (elementUnderFatFinger->renderer()) {
 318 Color tapHighlightColor = elementUnderFatFinger->renderStyle()->tapHighlightColor();
 319 if (tapHighlightColor != RenderTheme::defaultTheme()->platformTapHighlightColor())
 320 return elementUnderFatFinger;
 321 }
 322
 323 Node* linkNode = elementUnderFatFinger->enclosingLinkEventParentOrSelf();
 324 if (!linkNode || !linkNode->isHTMLElement() || (!linkNode->renderer() && !isArea))
 325 return 0;
 326
 327 ASSERT(linkNode->isLink());
 328
 329 // FatFingers class selector ensure only anchor with valid href attr value get here.
 330 // It includes empty hrefs.
 331 Element* highlightCandidateElement = static_cast<Element*>(linkNode);
 332
 333 if (!isArea)
 334 return highlightCandidateElement;
 335
 336 HTMLAreaElement* area = static_cast<HTMLAreaElement*>(highlightCandidateElement);
 337 HTMLImageElement* image = area->imageElement();
 338 if (image && image->renderer())
 339 return image;
 340
 341 return 0;
 342}
 343
 344void TouchEventHandler::drawTapHighlight()
 345{
 346 Element* elementUnderFatFinger = m_lastFatFingersResult.nodeAsElementIfApplicable();
 347 if (!elementUnderFatFinger)
 348 return;
 349
 350 Element* element = elementForTapHighlight(elementUnderFatFinger);
 351 if (!element)
 352 return;
 353
 354 // Get the element bounding rect in transformed coordinates so we can extract
 355 // the focus ring relative position each rect.
 356 RenderObject* renderer = element->renderer();
 357 ASSERT(renderer);
 358
 359 Frame* elementFrame = element->document()->frame();
 360 ASSERT(elementFrame);
 361
 362 FrameView* elementFrameView = elementFrame->view();
 363 if (!elementFrameView)
 364 return;
 365
 366 // Tell the client if the element is either in a scrollable container or in a fixed positioned container.
 367 // On the client side, this info is being used to hide the tap highlight window on scroll.
 368 RenderLayer* layer = m_webPage->enclosingFixedPositionedAncestorOrSelfIfFixedPositioned(renderer->enclosingLayer());
 369 bool shouldHideTapHighlightRightAfterScrolling = !layer->renderer()->isRenderView();
 370 shouldHideTapHighlightRightAfterScrolling |= !!m_webPage->m_inRegionScrollStartingNode.get();
 371
 372 IntPoint framePos(m_webPage->frameOffset(elementFrame));
 373
 374 // FIXME: We can get more precise on the MAP case by calculating the rect with HTMLAreaElement::computeRect().
 375 IntRect absoluteRect = renderer->absoluteClippedOverflowRect();
 376 absoluteRect.move(framePos.x(), framePos.y());
 377
 378 IntRect clippingRect;
 379 if (elementFrame == m_webPage->mainFrame())
 380 clippingRect = IntRect(IntPoint(0, 0), elementFrameView->contentsSize());
 381 else
 382 clippingRect = m_webPage->mainFrame()->view()->windowToContents(m_webPage->getRecursiveVisibleWindowRect(elementFrameView, true /*noClipToMainFrame*/));
 383 clippingRect = intersection(absoluteRect, clippingRect);
 384
 385 Vector<FloatQuad> focusRingQuads;
 386 renderer->absoluteFocusRingQuads(focusRingQuads);
 387
 388 Platform::IntRectRegion region;
 389 for (size_t i = 0; i < focusRingQuads.size(); ++i) {
 390 IntRect rect = focusRingQuads[i].enclosingBoundingBox();
 391 rect.move(framePos.x(), framePos.y());
 392 IntRect clippedRect = intersection(clippingRect, rect);
 393 clippedRect.inflate(2);
 394 region = unionRegions(region, Platform::IntRect(clippedRect));
 395 }
 396
 397 Color highlightColor = element->renderStyle()->tapHighlightColor();
 398
 399 m_webPage->m_client->drawTapHighlight(region,
 400 highlightColor.red(),
 401 highlightColor.green(),
 402 highlightColor.blue(),
 403 highlightColor.alpha(),
 404 shouldHideTapHighlightRightAfterScrolling);
 405}
 406
 407}
 408}

Source/WebKit/blackberry/WebKitSupport/TouchEventHandler.h

 1/*
 2 * Copyright (C) 2010, 2011 Research In Motion Limited. All rights reserved.
 3 *
 4 * This library is free software; you can redistribute it and/or
 5 * modify it under the terms of the GNU Lesser General Public
 6 * License as published by the Free Software Foundation; either
 7 * version 2 of the License, or (at your option) any later version.
 8 *
 9 * This library is distributed in the hope that it will be useful,
 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 12 * Lesser General Public License for more details.
 13 *
 14 * You should have received a copy of the GNU Lesser General Public
 15 * License along with this library; if not, write to the Free Software
 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 17 */
 18
 19#ifndef TouchEventHandler_h
 20#define TouchEventHandler_h
 21
 22#include "ChromeClient.h"
 23#include "FatFingers.h"
 24#include "IntPoint.h"
 25
 26#include <BlackBerryPlatformTouchEvent.h>
 27#include <BlackBerryPlatformWindow.h>
 28
 29namespace WebCore {
 30class IntPoint;
 31class Element;
 32}
 33
 34namespace BlackBerry {
 35namespace WebKit {
 36
 37class WebPagePrivate;
 38
 39class TouchEventHandler {
 40public:
 41 TouchEventHandler(WebPagePrivate* webpage);
 42 ~TouchEventHandler();
 43
 44 bool handleTouchPoint(BlackBerry::Platform::TouchPoint&);
 45 void touchEventCancel();
 46 void touchEventCancelAndClearFocusedNode();
 47 void touchHoldEvent();
 48
 49 bool shouldSuppressMouseDownOnTouchDown() const;
 50
 51 const FatFingersResult& lastFatFingersResult() const { return m_lastFatFingersResult; }
 52 void resetLastFatFingersResult() { m_lastFatFingersResult.reset(); }
 53
 54private:
 55 unsigned spellCheck(BlackBerry::Platform::TouchPoint&);
 56 void handleFatFingerPressed();
 57
 58 void drawTapHighlight();
 59
 60private:
 61 WebPagePrivate* m_webPage;
 62
 63 bool m_didCancelTouch;
 64 bool m_convertTouchToMouse;
 65
 66 WebCore::TouchEventMode m_existingTouchMode;
 67
 68 WebCore::IntPoint m_lastScreenPoint; // Screen Position
 69
 70 FatFingersResult m_lastFatFingersResult;
 71};
 72
 73}
 74}
 75
 76#endif // TouchEventHandler_h