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();
151 void setResizingFrameSet(HTMLFrameSetElement*);
153 void resizeLayerDestroyed();
155 IntPoint lastKnownMousePosition() const;
156 Cursor currentMouseCursor() const { return m_currentMouseCursor; }
158 static Frame* subframeForTargetNode(Node*);
159 static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
161 bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
162 bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
163 bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
165 bool tabsToLinks(KeyboardEvent*) const;
166 bool tabsToAllFormControls(KeyboardEvent*) const;
168 bool mouseMoved(const PlatformMouseEvent&);
169 bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
171 void lostMouseCapture();
173 bool handleMousePressEvent(const PlatformMouseEvent&);
174 bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
175 bool handleMouseReleaseEvent(const PlatformMouseEvent&);
176 bool handleWheelEvent(const PlatformWheelEvent&);
177 void defaultWheelEventHandler(Node*, WheelEvent*);
178 bool handlePasteGlobalSelection(const PlatformMouseEvent&);
180 #if ENABLE(GESTURE_EVENTS)
181 bool handleGestureEvent(const PlatformGestureEvent&);
182 bool handleGestureTap(const PlatformGestureEvent&);
183 bool handleGestureLongPress(const PlatformGestureEvent&);
184 bool handleGestureLongTap(const PlatformGestureEvent&);
185 bool handleGestureTwoFingerTap(const PlatformGestureEvent&);
186 bool handleGestureScrollUpdate(const PlatformGestureEvent&);
187 bool handleGestureScrollBegin(const PlatformGestureEvent&);
188 void clearGestureScrollNodes();
189 bool isScrollbarHandlingGestures() const;
192 #if ENABLE(TOUCH_ADJUSTMENT)
193 bool shouldApplyTouchAdjustment(const PlatformGestureEvent&) const;
195 bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
196 bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
197 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
199 bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
202 #if ENABLE(CONTEXT_MENUS)
203 bool sendContextMenuEvent(const PlatformMouseEvent&);
204 bool sendContextMenuEventForKey();
205 #if ENABLE(GESTURE_EVENTS)
206 bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
210 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
212 bool needsKeyboardEventDisambiguationQuirks() const;
214 static unsigned accessKeyModifiers();
215 bool handleAccessKey(const PlatformKeyboardEvent&);
216 bool keyEvent(const PlatformKeyboardEvent&);
217 void defaultKeyboardEventHandler(KeyboardEvent*);
219 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
220 void defaultTextInputEventHandler(TextEvent*);
222 #if ENABLE(DRAG_SUPPORT)
223 bool eventMayStartDrag(const PlatformMouseEvent&) const;
225 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
228 void focusDocumentView();
230 void capsLockStateMayHaveChanged(); // Only called by FrameSelection
232 void sendResizeEvent(); // Only called in FrameView
233 void sendScrollEvent(); // Ditto
235 #if PLATFORM(MAC) && defined(__OBJC__)
236 void mouseDown(NSEvent *);
237 void mouseDragged(NSEvent *);
238 void mouseUp(NSEvent *);
239 void mouseMoved(NSEvent *);
240 bool keyEvent(NSEvent *);
241 bool wheelEvent(NSEvent *);
243 void passMouseMovedEventToScrollbars(NSEvent *);
245 void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
247 void setActivationEventNumber(int num) { m_activationEventNumber = num; }
249 static NSEvent *currentNSEvent();
252 #if ENABLE(TOUCH_EVENTS)
253 bool handleTouchEvent(const PlatformTouchEvent&);
256 bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
259 #if ENABLE(DRAG_SUPPORT)
260 static DragState& dragState();
261 static const double TextDragDelay;
263 PassRefPtr<Clipboard> createDraggingClipboard() const;
264 #endif // ENABLE(DRAG_SUPPORT)
266 bool eventActivatedView(const PlatformMouseEvent&) const;
267 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
268 void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
269 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
270 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
272 bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
274 bool handleMousePressEvent(const MouseEventWithHitTestResults&);
275 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
276 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
277 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
278 #if ENABLE(DRAG_SUPPORT)
279 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
281 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
283 OptionalCursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
284 void hoverTimerFired(Timer<EventHandler>*);
286 bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
288 bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
289 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
291 static bool isKeyboardOptionTab(KeyboardEvent*);
292 static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
294 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
295 void cancelFakeMouseMoveEvent();
297 bool isInsideScrollbar(const IntPoint&) const;
299 #if ENABLE(TOUCH_EVENTS)
300 bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
301 HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::DisallowShadowContent);
304 void invalidateClick();
306 Node* nodeUnderMouse() const;
308 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
309 void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
311 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
313 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
314 #if ENABLE(DRAG_SUPPORT)
315 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
317 void freeClipboard();
319 bool handleDrag(const MouseEventWithHitTestResults&, CheckDragHysteresis);
321 bool handleMouseUp(const MouseEventWithHitTestResults&);
322 #if ENABLE(DRAG_SUPPORT)
323 void clearDragState();
325 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
327 bool dragHysteresisExceeded(const FloatPoint&) const;
328 bool dragHysteresisExceeded(const IntPoint&) const;
329 #endif // ENABLE(DRAG_SUPPORT)
331 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
332 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
333 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
335 bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
337 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
339 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
340 bool passWidgetMouseDownEventToWidget(RenderWidget*);
342 bool passMouseDownEventToWidget(Widget*);
343 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
345 void defaultSpaceEventHandler(KeyboardEvent*);
346 void defaultBackspaceEventHandler(KeyboardEvent*);
347 void defaultTabEventHandler(KeyboardEvent*);
348 void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
350 #if ENABLE(DRAG_SUPPORT)
351 DragSourceAction updateDragSourceActionsAllowed() const;
354 // The following are called at the beginning of handleMouseUp and handleDrag.
355 // If they return true it indicates that they have consumed the event.
356 bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
357 #if ENABLE(DRAG_SUPPORT)
358 bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
361 #if ENABLE(DRAG_SUPPORT)
362 void updateSelectionForMouseDrag(const HitTestResult&);
365 void updateLastScrollbarUnderMouse(Scrollbar*, bool);
367 void setFrameWasScrolledByUser();
369 bool capturesDragging() const { return m_capturesDragging; }
371 #if PLATFORM(MAC) && defined(__OBJC__)
372 NSView *mouseDownViewIfStillGood();
374 PlatformMouseEvent currentPlatformMouseEvent() const;
377 #if ENABLE(FULLSCREEN_API)
378 bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
381 #if ENABLE(GESTURE_EVENTS)
382 bool handleGestureTapDown();
383 bool handleGestureForTextSelectionOrContextMenu(const PlatformGestureEvent&);
384 bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
385 bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
386 bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
389 void setLastKnownMousePosition(const PlatformMouseEvent&);
391 #if ENABLE(CURSOR_VISIBILITY)
392 void startAutoHideCursorTimer();
393 void cancelAutoHideCursorTimer();
394 void autoHideCursorTimerFired(Timer<EventHandler>*);
400 bool m_capturesDragging;
401 RefPtr<Node> m_mousePressNode;
403 bool m_mouseDownMayStartSelect;
404 #if ENABLE(DRAG_SUPPORT)
405 bool m_mouseDownMayStartDrag;
406 bool m_dragMayStartSelectionInstead;
408 bool m_mouseDownWasSingleClickInSelection;
409 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
410 SelectionInitiationState m_selectionInitiationState;
412 #if ENABLE(DRAG_SUPPORT)
413 LayoutPoint m_dragStartPos;
416 bool m_panScrollButtonPressed;
418 Timer<EventHandler> m_hoverTimer;
420 OwnPtr<AutoscrollController> m_autoscrollController;
421 bool m_mouseDownMayStartAutoscroll;
422 bool m_mouseDownWasInSubframe;
424 Timer<EventHandler> m_fakeMouseMoveEventTimer;
428 RefPtr<SVGElementInstance> m_instanceUnderMouse;
429 RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
432 RenderLayer* m_resizeLayer;
434 RefPtr<Node> m_capturingMouseEventsNode;
435 bool m_eventHandlerWillResetCapturingMouseEventsNode;
437 RefPtr<Node> m_nodeUnderMouse;
438 RefPtr<Node> m_lastNodeUnderMouse;
439 RefPtr<Frame> m_lastMouseMoveEventSubframe;
440 RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
441 Cursor m_currentMouseCursor;
444 RefPtr<Node> m_clickNode;
446 #if ENABLE(DRAG_SUPPORT)
447 RefPtr<Node> m_dragTarget;
448 bool m_shouldOnlyFireDragOverEvent;
451 RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
453 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
455 bool m_mousePositionIsUnknown;
456 IntPoint m_lastKnownMousePosition;
457 IntPoint m_lastKnownMouseGlobalPosition;
458 IntPoint m_mouseDownPos; // In our view's coords.
459 double m_mouseDownTimestamp;
460 PlatformMouseEvent m_mouseDown;
461 RefPtr<UserGestureToken> m_lastMouseDownUserGestureToken;
463 RefPtr<Node> m_latchedWheelEventNode;
464 bool m_widgetIsLatched;
466 RefPtr<Node> m_previousWheelScrolledNode;
469 NSView *m_mouseDownView;
470 bool m_sendingEventToSubview;
471 int m_activationEventNumber;
473 #if ENABLE(TOUCH_EVENTS)
474 typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
475 TouchTargetMap m_originatingTouchPointTargets;
476 RefPtr<Document> m_originatingTouchPointDocument;
477 unsigned m_originatingTouchPointTargetKey;
481 #if ENABLE(GESTURE_EVENTS)
482 RefPtr<Node> m_scrollGestureHandlingNode;
483 bool m_lastHitTestResultOverWidget;
484 RefPtr<Node> m_previousGestureScrolledNode;
485 RefPtr<Scrollbar> m_scrollbarHandlingScrollGesture;
488 double m_maxMouseMovedDuration;
489 PlatformEvent::Type m_baseEventType;
491 bool m_didLongPressInvokeContextMenu;
493 #if ENABLE(CURSOR_VISIBILITY)
494 Timer<EventHandler> m_autoHideCursorTimer;
498 } // namespace WebCore
500 #endif // EventHandler_h