1 /* 2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #ifndef EventHandler_h 27 #define EventHandler_h 28 29 #include "DragActions.h" 30 #include "FocusDirection.h" 31 #include "PlatformMouseEvent.h" 32 #include "ScrollTypes.h" 33 #include "Timer.h" 34 #include <wtf/Forward.h> 35 #include <wtf/Noncopyable.h> 36 #include <wtf/Platform.h> 37 #include <wtf/RefPtr.h> 38 39 #if PLATFORM(MAC) 40 #include "WebCoreKeyboardUIMode.h" 41 #ifndef __OBJC__ 42 class NSEvent; 43 class NSView; 44 #endif 45 #endif 46 47 namespace WebCore { 48 49 class AtomicString; 50 class Clipboard; 51 class Cursor; 52 class EventTargetNode; 53 class Event; 54 class FloatPoint; 55 class FloatRect; 56 class Frame; 57 class HitTestResult; 58 class HTMLFrameSetElement; 59 class KeyboardEvent; 60 class MouseEventWithHitTestResults; 61 class Node; 62 class PlatformKeyboardEvent; 63 class PlatformWheelEvent; 64 class RenderLayer; 65 class RenderObject; 66 class RenderWidget; 67 class Scrollbar; 68 class String; 69 class SVGElementInstance; 70 class TextEvent; 71 class VisiblePosition; 72 class Widget; 73 #if ENABLE(TOUCH_EVENTS) // Android 74 class PlatformTouchEvent; 75 class Touch; 76 #endif 77 78 struct HitTestRequest; 79 80 extern const int LinkDragHysteresis; 81 extern const int ImageDragHysteresis; 82 extern const int TextDragHysteresis; 83 extern const int GeneralDragHysteresis; 84 85 class EventHandler : Noncopyable { 86 public: 87 EventHandler(Frame*); 88 ~EventHandler(); 89 90 void clear(); 91 92 void updateSelectionForMouseDrag(); 93 94 Node* mousePressNode() const; 95 void setMousePressNode(PassRefPtr<Node>); 96 panScrollInProgress()97 bool panScrollInProgress() { return m_panScrollInProgress; } setPanScrollInProgress(bool inProgress)98 void setPanScrollInProgress(bool inProgress) { m_panScrollInProgress = inProgress; } 99 100 void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false); 101 RenderObject* autoscrollRenderer() const; 102 void updateAutoscrollRenderer(); 103 104 HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent); 105 mousePressed()106 bool mousePressed() const { return m_mousePressed; } setMousePressed(bool pressed)107 void setMousePressed(bool pressed) { m_mousePressed = pressed; } 108 109 void setCapturingMouseEventsNode(PassRefPtr<Node>); 110 111 bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*); 112 void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*); 113 bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*); 114 115 void scheduleHoverStateUpdate(); 116 117 void setResizingFrameSet(HTMLFrameSetElement*); 118 119 void resizeLayerDestroyed(); 120 121 IntPoint currentMousePosition() const; 122 123 void setIgnoreWheelEvents(bool); 124 125 bool scrollOverflow(ScrollDirection, ScrollGranularity); 126 127 bool shouldDragAutoNode(Node*, const IntPoint&) const; // -webkit-user-drag == auto 128 129 bool tabsToLinks(KeyboardEvent*) const; 130 bool tabsToAllControls(KeyboardEvent*) const; 131 mouseDownMayStartSelect()132 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; } 133 134 bool mouseMoved(const PlatformMouseEvent&); 135 136 bool handleMousePressEvent(const PlatformMouseEvent&); 137 bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0); 138 bool handleMouseReleaseEvent(const PlatformMouseEvent&); 139 bool handleWheelEvent(PlatformWheelEvent&); 140 141 #if ENABLE(TOUCH_EVENTS) // Android 142 bool handleTouchEvent(const PlatformTouchEvent&); 143 #endif 144 145 bool sendContextMenuEvent(const PlatformMouseEvent&); 146 setMouseDownMayStartAutoscroll()147 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; } 148 149 bool needsKeyboardEventDisambiguationQuirks() const; 150 151 static unsigned accessKeyModifiers(); 152 bool handleAccessKey(const PlatformKeyboardEvent&); 153 bool keyEvent(const PlatformKeyboardEvent&); 154 void defaultKeyboardEventHandler(KeyboardEvent*); 155 156 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, 157 bool isLineBreak = false, bool isBackTab = false); 158 void defaultTextInputEventHandler(TextEvent*); 159 160 bool eventMayStartDrag(const PlatformMouseEvent&) const; 161 162 void dragSourceMovedTo(const PlatformMouseEvent&); 163 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation); 164 165 void focusDocumentView(); 166 167 void capsLockStateMayHaveChanged(); 168 169 unsigned pendingFrameUnloadEventCount(); 170 void addPendingFrameUnloadEventCount(); 171 void removePendingFrameUnloadEventCount(); 172 void clearPendingFrameUnloadEventCount(); 173 unsigned pendingFrameBeforeUnloadEventCount(); 174 void addPendingFrameBeforeUnloadEventCount(); 175 void removePendingFrameBeforeUnloadEventCount(); 176 void clearPendingFrameBeforeUnloadEventCount(); 177 178 #if PLATFORM(MAC) 179 PassRefPtr<KeyboardEvent> currentKeyboardEvent() const; 180 181 void mouseDown(NSEvent*); 182 void mouseDragged(NSEvent*); 183 void mouseUp(NSEvent*); 184 void mouseMoved(NSEvent*); 185 bool keyEvent(NSEvent*); 186 bool wheelEvent(NSEvent*); 187 188 void sendFakeEventsAfterWidgetTracking(NSEvent* initiatingEvent); 189 setActivationEventNumber(int num)190 void setActivationEventNumber(int num) { m_activationEventNumber = num; } 191 192 NSEvent *currentNSEvent(); 193 #endif 194 195 private: 196 struct EventHandlerDragState { 197 RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture 198 bool m_dragSrcIsLink; 199 bool m_dragSrcIsImage; 200 bool m_dragSrcInSelection; 201 bool m_dragSrcMayBeDHTML; 202 bool m_dragSrcMayBeUA; // Are DHTML and/or the UserAgent allowed to drag out? 203 bool m_dragSrcIsDHTML; 204 RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging 205 }; 206 static EventHandlerDragState& dragState(); 207 static const double TextDragDelay; 208 209 PassRefPtr<Clipboard> createDraggingClipboard() const; 210 211 bool eventActivatedView(const PlatformMouseEvent&) const; 212 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& event); 213 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults& event); 214 215 bool handleMouseDoubleClickEvent(const PlatformMouseEvent&); 216 217 bool handleMousePressEvent(const MouseEventWithHitTestResults&); 218 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&); 219 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&); 220 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&); 221 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&); 222 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&); 223 224 void handleKeyboardSelectionMovement(KeyboardEvent*); 225 226 Cursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*); 227 void setPanScrollCursor(); 228 229 void hoverTimerFired(Timer<EventHandler>*); 230 231 static bool canMouseDownStartSelect(Node*); 232 static bool canMouseDragExtendSelect(Node*); 233 234 void handleAutoscroll(RenderObject*); 235 void startAutoscrollTimer(); 236 void setAutoscrollRenderer(RenderObject*); 237 void autoscrollTimerFired(Timer<EventHandler>*); 238 239 void invalidateClick(); 240 241 Node* nodeUnderMouse() const; 242 243 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut); 244 void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true); 245 246 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&); 247 248 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder); 249 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*); 250 251 void freeClipboard(); 252 253 bool handleDrag(const MouseEventWithHitTestResults&); 254 bool handleMouseUp(const MouseEventWithHitTestResults&); 255 void clearDragState(); 256 257 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&); 258 259 bool dragHysteresisExceeded(const FloatPoint&) const; 260 bool dragHysteresisExceeded(const IntPoint&) const; 261 262 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe); 263 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0); 264 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe); 265 266 bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0); 267 268 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*); 269 270 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&); 271 bool passWidgetMouseDownEventToWidget(RenderWidget*); 272 273 bool passMouseDownEventToWidget(Widget*); 274 bool passWheelEventToWidget(PlatformWheelEvent&, Widget*); 275 276 void defaultSpaceEventHandler(KeyboardEvent*); 277 void defaultTabEventHandler(KeyboardEvent*); 278 279 void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const; 280 281 // The following are called at the beginning of handleMouseUp and handleDrag. 282 // If they return true it indicates that they have consumed the event. 283 #if PLATFORM(MAC) 284 bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&); 285 bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&); 286 NSView *mouseDownViewIfStillGood(); 287 #else eventLoopHandleMouseUp(const MouseEventWithHitTestResults &)288 bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&) { return false; } eventLoopHandleMouseDragged(const MouseEventWithHitTestResults &)289 bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&) { return false; } 290 #endif 291 292 bool invertSenseOfTabsToLinks(KeyboardEvent*) const; 293 294 void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint); 295 296 Frame* m_frame; 297 298 bool m_mousePressed; 299 RefPtr<Node> m_mousePressNode; 300 301 bool m_mouseDownMayStartSelect; 302 bool m_mouseDownMayStartDrag; 303 bool m_mouseDownWasSingleClickInSelection; 304 bool m_beganSelectingText; 305 306 IntPoint m_dragStartPos; 307 308 IntPoint m_panScrollStartPos; 309 bool m_panScrollInProgress; 310 311 Timer<EventHandler> m_hoverTimer; 312 313 Timer<EventHandler> m_autoscrollTimer; 314 RenderObject* m_autoscrollRenderer; 315 bool m_autoscrollInProgress; 316 bool m_mouseDownMayStartAutoscroll; 317 bool m_mouseDownWasInSubframe; 318 #if ENABLE(SVG) 319 bool m_svgPan; 320 RefPtr<SVGElementInstance> m_instanceUnderMouse; 321 RefPtr<SVGElementInstance> m_lastInstanceUnderMouse; 322 #endif 323 324 RenderLayer* m_resizeLayer; 325 326 RefPtr<Node> m_capturingMouseEventsNode; 327 328 RefPtr<Node> m_nodeUnderMouse; 329 RefPtr<Node> m_lastNodeUnderMouse; 330 RefPtr<Frame> m_lastMouseMoveEventSubframe; 331 RefPtr<Scrollbar> m_lastScrollbarUnderMouse; 332 333 int m_clickCount; 334 RefPtr<Node> m_clickNode; 335 #if ENABLE(TOUCH_EVENTS) // Android 336 RefPtr<Touch> m_touch; 337 #endif 338 339 RefPtr<Node> m_dragTarget; 340 341 RefPtr<HTMLFrameSetElement> m_frameSetBeingResized; 342 343 IntSize m_offsetFromResizeCorner; // in the coords of m_resizeLayer 344 345 IntPoint m_currentMousePosition; 346 IntPoint m_mouseDownPos; // in our view's coords 347 double m_mouseDownTimestamp; 348 PlatformMouseEvent m_mouseDown; 349 350 unsigned m_pendingFrameUnloadEventCount; 351 unsigned m_pendingFrameBeforeUnloadEventCount; 352 353 #if PLATFORM(MAC) 354 NSView *m_mouseDownView; 355 bool m_sendingEventToSubview; 356 int m_activationEventNumber; 357 #endif 358 359 }; 360 361 } // namespace WebCore 362 363 #endif // EventHandler_h 364