2 * Copyright (C) 2006, 2007, 2009, 2010, 2011 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef EventHandler_h
27 #define EventHandler_h
30 #include "DragActions.h"
31 #include "FocusDirection.h"
32 #include "HitTestRequest.h"
33 #include "LayoutPoint.h"
34 #include "PlatformMouseEvent.h"
35 #include "PlatformWheelEvent.h"
36 #include "ScrollTypes.h"
37 #include "TextEventInputType.h"
38 #include "TextGranularity.h"
40 #include "UserGestureIndicator.h"
41 #include <wtf/Forward.h>
42 #include <wtf/OwnPtr.h>
43 #include <wtf/RefPtr.h>
45 #if PLATFORM(MAC) && !defined(__OBJC__)
49 #if ENABLE(TOUCH_EVENTS)
50 #include <wtf/HashMap.h>
55 class AutoscrollController;
64 class HTMLFrameSetElement;
68 class MouseEventWithHitTestResults;
71 class PlatformKeyboardEvent;
72 class PlatformTouchEvent;
73 class PlatformWheelEvent;
77 class SVGElementInstance;
81 class VisibleSelection;
87 #if ENABLE(GESTURE_EVENTS)
88 class PlatformGestureEvent;
91 #if ENABLE(DRAG_SUPPORT)
92 extern const int LinkDragHysteresis;
93 extern const int ImageDragHysteresis;
94 extern const int TextDragHysteresis;
95 extern const int GeneralDragHysteresis;
96 #endif // ENABLE(DRAG_SUPPORT)
98 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
99 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
102 WTF_MAKE_NONCOPYABLE(EventHandler);
104 explicit EventHandler(Frame*);
108 void nodeWillBeRemoved(Node*);
110 #if ENABLE(DRAG_SUPPORT)
111 void updateSelectionForMouseDrag();
114 Node* mousePressNode() const;
115 void setMousePressNode(PassRefPtr<Node>);
117 #if ENABLE(PAN_SCROLLING)
118 void didPanScrollStart();
119 void didPanScrollStop();
120 void startPanScrolling(RenderObject*);
123 void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
124 RenderObject* autoscrollRenderer() const;
125 void updateAutoscrollRenderer();
126 bool autoscrollInProgress() const;
127 bool mouseDownWasInSubframe() const { return m_mouseDownWasInSubframe; }
128 bool panScrollInProgress() const;
130 void dispatchFakeMouseMoveEventSoon();
131 void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
133 HitTestResult hitTestResultAtPoint(const LayoutPoint&,
134 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent,
135 const LayoutSize& padding = LayoutSize());
137 bool mousePressed() const { return m_mousePressed; }
138 void setMousePressed(bool pressed) { m_mousePressed = pressed; }
140 void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
142 #if ENABLE(DRAG_SUPPORT)
143 bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
144 void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
145 bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
146 void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
149 void scheduleHoverStateUpdate();
150 void scheduleCursorUpdate();
152 void setResizingFrameSet(HTMLFrameSetElement*);
154 void resizeLayerDestroyed();
156 IntPoint lastKnownMousePosition() const;
157 Cursor currentMouseCursor() const { return m_currentMouseCursor; }
159 static Frame* subframeForTargetNode(Node*);
160 static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
162 bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
163 bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
164 bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
166 bool tabsToLinks(KeyboardEvent*) const;
167 bool tabsToAllFormControls(KeyboardEvent*) const;
169 bool mouseMoved(const PlatformMouseEvent&);
170 bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
172 void lostMouseCapture();
174 bool handleMousePressEvent(const PlatformMouseEvent&);
175 bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
176 bool handleMouseReleaseEvent(const PlatformMouseEvent&);
177 bool handleWheelEvent(const PlatformWheelEvent&);
178 void defaultWheelEventHandler(Node*, WheelEvent*);
179 bool handlePasteGlobalSelection(const PlatformMouseEvent&);
181 #if ENABLE(GESTURE_EVENTS)
182 bool handleGestureEvent(const PlatformGestureEvent&);
183 bool handleGestureTap(const PlatformGestureEvent&);
184 bool handleGestureLongPress(const PlatformGestureEvent&);
185 bool handleGestureLongTap(const PlatformGestureEvent&);
186 bool handleGestureTwoFingerTap(const PlatformGestureEvent&);
187 bool handleGestureScrollUpdate(const PlatformGestureEvent&);
188 bool handleGestureScrollBegin(const PlatformGestureEvent&);
189 void clearGestureScrollNodes();
190 bool isScrollbarHandlingGestures() const;
193 #if ENABLE(TOUCH_ADJUSTMENT)
194 bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
196 bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
197 bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
198 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
200 bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
203 #if ENABLE(CONTEXT_MENUS)
204 bool sendContextMenuEvent(const PlatformMouseEvent&);
205 bool sendContextMenuEventForKey();
206 #if ENABLE(GESTURE_EVENTS)
207 bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
211 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
213 bool needsKeyboardEventDisambiguationQuirks() const;
215 static unsigned accessKeyModifiers();
216 bool handleAccessKey(const PlatformKeyboardEvent&);
217 bool keyEvent(const PlatformKeyboardEvent&);
218 void defaultKeyboardEventHandler(KeyboardEvent*);
220 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
221 void defaultTextInputEventHandler(TextEvent*);
223 #if ENABLE(DRAG_SUPPORT)
224 bool eventMayStartDrag(const PlatformMouseEvent&) const;
226 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
229 void focusDocumentView();
231 void capsLockStateMayHaveChanged(); // Only called by FrameSelection
233 void sendResizeEvent(); // Only called in FrameView
234 void sendScrollEvent(); // Ditto
236 #if PLATFORM(MAC) && defined(__OBJC__)
237 void mouseDown(NSEvent *);
238 void mouseDragged(NSEvent *);
239 void mouseUp(NSEvent *);
240 void mouseMoved(NSEvent *);
241 bool keyEvent(NSEvent *);
242 bool wheelEvent(NSEvent *);
244 void passMouseMovedEventToScrollbars(NSEvent *);
246 void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
248 void setActivationEventNumber(int num) { m_activationEventNumber = num; }
250 static NSEvent *currentNSEvent();
253 #if ENABLE(TOUCH_EVENTS)
254 bool handleTouchEvent(const PlatformTouchEvent&);
257 bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
261 #if ENABLE(DRAG_SUPPORT)
262 static DragState& dragState();
263 static const double TextDragDelay;
265 PassRefPtr<Clipboard> createDraggingClipboard() const;
266 #endif // ENABLE(DRAG_SUPPORT)
268 bool eventActivatedView(const PlatformMouseEvent&) const;
269 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
270 void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
271 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
272 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
274 bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
276 bool handleMousePressEvent(const MouseEventWithHitTestResults&);
277 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
278 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
279 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
280 #if ENABLE(DRAG_SUPPORT)
281 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
283 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
285 OptionalCursor selectCursor(const HitTestResult&, bool shiftKey);
287 void hoverTimerFired(Timer<EventHandler>*);
288 void cursorUpdateTimerFired(Timer<EventHandler>*);
290 bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
292 bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
293 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
295 static bool isKeyboardOptionTab(KeyboardEvent*);
296 static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
298 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
299 void cancelFakeMouseMoveEvent();
301 bool isInsideScrollbar(const IntPoint&) const;
303 #if ENABLE(TOUCH_EVENTS)
304 bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
305 HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
308 void invalidateClick();
310 Node* nodeUnderMouse() const;
312 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
313 void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
315 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
317 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
318 #if ENABLE(DRAG_SUPPORT)
319 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
321 void freeClipboard();
323 bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
325 bool handleMouseUp(const MouseEventWithHitTestResults&);
326 #if ENABLE(DRAG_SUPPORT)
327 void clearDragState();
329 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
331 bool dragHysteresisExceeded(const FloatPoint&) const;
332 bool dragHysteresisExceeded(const IntPoint&) const;
333 #endif // ENABLE(DRAG_SUPPORT)
335 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
336 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
337 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
339 bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
341 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
343 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
344 bool passWidgetMouseDownEventToWidget(RenderWidget*);
346 bool passMouseDownEventToWidget(Widget*);
347 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
349 void defaultSpaceEventHandler(KeyboardEvent*);
350 void defaultBackspaceEventHandler(KeyboardEvent*);
351 void defaultTabEventHandler(KeyboardEvent*);
352 void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
354 #if ENABLE(DRAG_SUPPORT)
355 DragSourceAction updateDragSourceActionsAllowed() const;
358 // The following are called at the beginning of handleMouseUp and handleDrag.
359 // If they return true it indicates that they have consumed the event.
360 bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
361 #if ENABLE(DRAG_SUPPORT)
362 bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
365 #if ENABLE(DRAG_SUPPORT)
366 void updateSelectionForMouseDrag(const HitTestResult&);
369 void updateLastScrollbarUnderMouse(Scrollbar*, bool);
371 void setFrameWasScrolledByUser();
373 bool capturesDragging() const { return m_capturesDragging; }
375 #if PLATFORM(MAC) && defined(__OBJC__)
376 NSView *mouseDownViewIfStillGood();
378 PlatformMouseEvent currentPlatformMouseEvent() const;
381 #if ENABLE(FULLSCREEN_API)
382 bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
385 #if ENABLE(GESTURE_EVENTS)
386 bool handleGestureTapDown();
387 bool handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent&);
388 bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
389 bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
390 bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
393 void setLastKnownMousePosition(const PlatformMouseEvent&);
395 #if ENABLE(CURSOR_VISIBILITY)
396 void startAutoHideCursorTimer();
397 void cancelAutoHideCursorTimer();
398 void autoHideCursorTimerFired(Timer<EventHandler>*);
404 bool m_capturesDragging;
405 RefPtr<Node> m_mousePressNode;
407 bool m_mouseDownMayStartSelect;
408 #if ENABLE(DRAG_SUPPORT)
409 bool m_mouseDownMayStartDrag;
410 bool m_dragMayStartSelectionInstead;
412 bool m_mouseDownWasSingleClickInSelection;
413 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
414 SelectionInitiationState m_selectionInitiationState;
416 #if ENABLE(DRAG_SUPPORT)
417 LayoutPoint m_dragStartPos;
420 bool m_panScrollButtonPressed;
422 Timer<EventHandler> m_hoverTimer;
423 Timer<EventHandler> m_cursorUpdateTimer;
425 OwnPtr<AutoscrollController> m_autoscrollController;
426 bool m_mouseDownMayStartAutoscroll;
427 bool m_mouseDownWasInSubframe;
429 Timer<EventHandler> m_fakeMouseMoveEventTimer;
433 RefPtr<SVGElementInstance> m_instanceUnderMouse;
434 RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
437 RenderLayer* m_resizeLayer;
439 RefPtr<Node> m_capturingMouseEventsNode;
440 bool m_eventHandlerWillResetCapturingMouseEventsNode;
442 RefPtr<Node> m_nodeUnderMouse;
443 RefPtr<Node> m_lastNodeUnderMouse;
444 RefPtr<Frame> m_lastMouseMoveEventSubframe;
445 RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
446 Cursor m_currentMouseCursor;
449 RefPtr<Node> m_clickNode;
451 #if ENABLE(DRAG_SUPPORT)
452 RefPtr<Node> m_dragTarget;
453 bool m_shouldOnlyFireDragOverEvent;
456 RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
458 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
460 bool m_mousePositionIsUnknown;
461 IntPoint m_lastKnownMousePosition;
462 IntPoint m_lastKnownMouseGlobalPosition;
463 IntPoint m_mouseDownPos; // In our view's coords.
464 double m_mouseDownTimestamp;
465 PlatformMouseEvent m_mouseDown;
466 RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
468 RefPtr<Node> m_latchedWheelEventNode;
469 bool m_widgetIsLatched;
471 RefPtr<Node> m_previousWheelScrolledNode;
474 NSView *m_mouseDownView;
475 bool m_sendingEventToSubview;
476 int m_activationEventNumber;
478 #if ENABLE(TOUCH_EVENTS)
479 typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
480 TouchTargetMap m_originatingTouchPointTargets;
481 RefPtr<Document> m_originatingTouchPointDocument;
482 unsigned m_originatingTouchPointTargetKey;
486 #if ENABLE(GESTURE_EVENTS)
487 RefPtr<Node> m_scrollGestureHandlingNode;
488 bool m_lastHitTestResultOverWidget;
489 RefPtr<Node> m_previousGestureScrolledNode;
490 RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
493 double m_maxMouseMovedDuration;
494 PlatformEvent::Type m_baseEventType;
496 bool m_didLongPressInvokeContextMenu;
498 #if ENABLE(CURSOR_VISIBILITY)
499 Timer<EventHandler> m_autoHideCursorTimer;
503 } // namespace WebCore
505 #endif // EventHandler_h