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
29 #include "DragActions.h"
30 #include "DragState.h"
31 #include "FocusDirection.h"
32 #include "HitTestRequest.h"
33 #include "PlatformMouseEvent.h"
34 #include "PlatformWheelEvent.h"
35 #include "ScrollTypes.h"
36 #include "TextEventInputType.h"
37 #include "TextGranularity.h"
39 #include <wtf/Forward.h>
40 #include <wtf/OwnPtr.h>
41 #include <wtf/RefPtr.h>
43 #if PLATFORM(MAC) && !defined(__OBJC__)
47 #if ENABLE(TOUCH_EVENTS)
48 #include <wtf/HashMap.h>
59 class HTMLFrameSetElement;
63 class MouseEventWithHitTestResults;
66 class PlatformKeyboardEvent;
67 class PlatformTouchEvent;
68 class PlatformWheelEvent;
72 class SVGElementInstance;
76 class VisibleSelection;
80 #if ENABLE(GESTURE_EVENTS)
81 class PlatformGestureEvent;
84 #if ENABLE(DRAG_SUPPORT)
85 extern const int LinkDragHysteresis;
86 extern const int ImageDragHysteresis;
87 extern const int TextDragHysteresis;
88 extern const int GeneralDragHysteresis;
89 #endif // ENABLE(DRAG_SUPPORT)
91 enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };
94 WTF_MAKE_NONCOPYABLE(EventHandler);
96 explicit EventHandler(Frame*);
100 void nodeWillBeRemoved(Node*);
102 #if ENABLE(DRAG_SUPPORT)
103 void updateSelectionForMouseDrag();
106 Node* mousePressNode() const;
107 void setMousePressNode(PassRefPtr<Node>);
109 void startPanScrolling(RenderObject*);
111 void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
112 RenderObject* autoscrollRenderer() const;
113 void updateAutoscrollRenderer();
115 void dispatchFakeMouseMoveEventSoon();
116 void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);
118 HitTestResult hitTestResultAtPoint(const LayoutPoint&, bool allowShadowContent, bool ignoreClipping = false,
119 HitTestScrollbars scrollbars = DontHitTestScrollbars,
120 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active,
121 const LayoutSize& padding = LayoutSize());
123 bool mousePressed() const { return m_mousePressed; }
124 void setMousePressed(bool pressed) { m_mousePressed = pressed; }
126 void setCapturingMouseEventsNode(PassRefPtr<Node>); // A caller is responsible for resetting capturing node to 0.
128 #if ENABLE(DRAG_SUPPORT)
129 bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
130 void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
131 bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
132 void updateDragStateAfterEditDragIfNeeded(Element* rootEditableElement);
135 void scheduleHoverStateUpdate();
137 void setResizingFrameSet(HTMLFrameSetElement*);
139 void resizeLayerDestroyed();
141 IntPoint currentMousePosition() const;
143 static Frame* subframeForTargetNode(Node*);
144 static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults&);
146 bool scrollOverflow(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
147 #if ENABLE(TIZEN_CSS_OVERFLOW_SCROLL_ACCELERATION)
148 bool scrollOverflow(const FloatPoint&);
149 bool setMousePressNodeAtPoint(const IntPoint&, bool checkOverflowLayer, RenderObject*&);
151 bool scrollRecursively(ScrollDirection, ScrollGranularity, Node* startingNode = 0);
152 bool logicalScrollRecursively(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
154 bool tabsToLinks(KeyboardEvent*) const;
155 bool tabsToAllFormControls(KeyboardEvent*) const;
157 bool mouseMoved(const PlatformMouseEvent&);
158 bool passMouseMovedEventToScrollbars(const PlatformMouseEvent&);
160 void lostMouseCapture();
162 bool handleMousePressEvent(const PlatformMouseEvent&);
163 bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0, bool onlyUpdateScrollbars = false);
164 bool handleMouseReleaseEvent(const PlatformMouseEvent&);
165 bool handleWheelEvent(const PlatformWheelEvent&);
166 void defaultWheelEventHandler(Node*, WheelEvent*);
168 #if ENABLE(GESTURE_EVENTS)
169 bool handleGestureEvent(const PlatformGestureEvent&);
170 bool handleGestureTap(const PlatformGestureEvent&);
171 bool handleGestureScrollUpdate(const PlatformGestureEvent&);
174 #if ENABLE(TOUCH_ADJUSTMENT)
175 bool bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
176 bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
177 bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
179 bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
182 #if ENABLE(CONTEXT_MENUS)
183 bool sendContextMenuEvent(const PlatformMouseEvent&);
184 bool sendContextMenuEventForKey();
185 #if ENABLE(GESTURE_EVENTS)
186 bool sendContextMenuEventForGesture(const PlatformGestureEvent&);
190 void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
192 bool needsKeyboardEventDisambiguationQuirks() const;
194 static unsigned accessKeyModifiers();
195 bool handleAccessKey(const PlatformKeyboardEvent&);
196 bool keyEvent(const PlatformKeyboardEvent&);
197 void defaultKeyboardEventHandler(KeyboardEvent*);
199 bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0, TextEventInputType = TextEventInputKeyboard);
200 void defaultTextInputEventHandler(TextEvent*);
202 #if ENABLE(DRAG_SUPPORT)
203 bool eventMayStartDrag(const PlatformMouseEvent&) const;
205 void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
208 void focusDocumentView();
210 void capsLockStateMayHaveChanged(); // Only called by FrameSelection
212 void sendResizeEvent(); // Only called in FrameView
213 void sendScrollEvent(); // Ditto
215 #if PLATFORM(MAC) && defined(__OBJC__)
216 void mouseDown(NSEvent *);
217 void mouseDragged(NSEvent *);
218 void mouseUp(NSEvent *);
219 void mouseMoved(NSEvent *);
220 bool keyEvent(NSEvent *);
221 bool wheelEvent(NSEvent *);
223 void passMouseMovedEventToScrollbars(NSEvent *);
225 void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
227 void setActivationEventNumber(int num) { m_activationEventNumber = num; }
229 static NSEvent *currentNSEvent();
232 #if ENABLE(TOUCH_EVENTS)
233 bool handleTouchEvent(const PlatformTouchEvent&);
237 #if ENABLE(DRAG_SUPPORT)
238 static DragState& dragState();
239 static const double TextDragDelay;
241 PassRefPtr<Clipboard> createDraggingClipboard() const;
242 #endif // ENABLE(DRAG_SUPPORT)
244 bool eventActivatedView(const PlatformMouseEvent&) const;
245 bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
246 void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
247 void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
249 bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
251 static Node* targetNode(const MouseEventWithHitTestResults&);
252 static Node* targetNode(const HitTestResult&);
254 bool handleMousePressEvent(const MouseEventWithHitTestResults&);
255 bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
256 bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
257 bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
258 #if ENABLE(DRAG_SUPPORT)
259 bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
261 bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
263 OptionalCursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
264 #if ENABLE(PAN_SCROLLING)
265 void updatePanScrollState();
268 void hoverTimerFired(Timer<EventHandler>*);
270 void handleAutoscroll(RenderObject*);
271 void startAutoscrollTimer();
272 void setAutoscrollRenderer(RenderObject*);
273 void autoscrollTimerFired(Timer<EventHandler>*);
274 bool logicalScrollOverflow(ScrollLogicalDirection, ScrollGranularity, Node* startingNode = 0);
276 bool shouldTurnVerticalTicksIntoHorizontal(const HitTestResult&, const PlatformWheelEvent&) const;
277 bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
279 static bool isKeyboardOptionTab(KeyboardEvent*);
280 static bool eventInvertsTabsToLinksClientCallResult(KeyboardEvent*);
282 void fakeMouseMoveEventTimerFired(Timer<EventHandler>*);
283 void cancelFakeMouseMoveEvent();
285 #if ENABLE(TOUCH_EVENTS)
286 bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
289 void invalidateClick();
291 Node* nodeUnderMouse() const;
293 void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
294 void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
296 MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
298 bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
299 #if ENABLE(DRAG_SUPPORT)
300 bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
302 void freeClipboard();
304 bool handleDrag(const MouseEventWithHitTestResults&);
306 bool handleMouseUp(const MouseEventWithHitTestResults&);
307 #if ENABLE(DRAG_SUPPORT)
308 void clearDragState();
310 bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
312 bool dragHysteresisExceeded(const FloatPoint&) const;
313 bool dragHysteresisExceeded(const IntPoint&) const;
314 #endif // ENABLE(DRAG_SUPPORT)
316 bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
317 bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
318 bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
320 bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
322 bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
324 bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
325 bool passWidgetMouseDownEventToWidget(RenderWidget*);
327 bool passMouseDownEventToWidget(Widget*);
328 bool passWheelEventToWidget(const PlatformWheelEvent&, Widget*);
330 void defaultSpaceEventHandler(KeyboardEvent*);
331 void defaultBackspaceEventHandler(KeyboardEvent*);
332 void defaultTabEventHandler(KeyboardEvent*);
333 void defaultArrowEventHandler(FocusDirection, KeyboardEvent*);
335 #if ENABLE(DRAG_SUPPORT)
336 DragSourceAction updateDragSourceActionsAllowed() const;
339 // The following are called at the beginning of handleMouseUp and handleDrag.
340 // If they return true it indicates that they have consumed the event.
341 bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
342 #if ENABLE(DRAG_SUPPORT)
343 bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
346 #if ENABLE(DRAG_SUPPORT)
347 void updateSelectionForMouseDrag(const HitTestResult&);
350 void updateLastScrollbarUnderMouse(Scrollbar*, bool);
352 void setFrameWasScrolledByUser();
354 bool capturesDragging() const { return m_capturesDragging; }
356 #if PLATFORM(MAC) && defined(__OBJC__)
357 NSView *mouseDownViewIfStillGood();
359 PlatformMouseEvent currentPlatformMouseEvent() const;
362 #if ENABLE(FULLSCREEN_API)
363 bool isKeyEventAllowedInFullScreen(const PlatformKeyboardEvent&) const;
366 #if ENABLE(GESTURE_EVENTS)
367 bool handleGestureScrollCore(const PlatformGestureEvent&, PlatformWheelEventGranularity, bool latchedWheel);
368 bool handleGestureTapDown();
374 bool m_capturesDragging;
375 RefPtr<Node> m_mousePressNode;
377 bool m_mouseDownMayStartSelect;
378 #if ENABLE(DRAG_SUPPORT)
379 bool m_mouseDownMayStartDrag;
380 bool m_dragMayStartSelectionInstead;
382 bool m_mouseDownWasSingleClickInSelection;
383 enum SelectionInitiationState { HaveNotStartedSelection, PlacedCaret, ExtendedSelection };
384 SelectionInitiationState m_selectionInitiationState;
386 #if ENABLE(DRAG_SUPPORT)
387 LayoutPoint m_dragStartPos;
390 IntPoint m_panScrollStartPos;
391 bool m_panScrollInProgress;
393 bool m_panScrollButtonPressed;
394 bool m_springLoadedPanScrollInProgress;
396 Timer<EventHandler> m_hoverTimer;
398 Timer<EventHandler> m_autoscrollTimer;
399 RenderObject* m_autoscrollRenderer;
400 bool m_autoscrollInProgress;
401 bool m_mouseDownMayStartAutoscroll;
402 bool m_mouseDownWasInSubframe;
404 Timer<EventHandler> m_fakeMouseMoveEventTimer;
408 RefPtr<SVGElementInstance> m_instanceUnderMouse;
409 RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
412 RenderLayer* m_resizeLayer;
414 RefPtr<Node> m_capturingMouseEventsNode;
415 bool m_eventHandlerWillResetCapturingMouseEventsNode;
417 RefPtr<Node> m_nodeUnderMouse;
418 RefPtr<Node> m_lastNodeUnderMouse;
419 RefPtr<Frame> m_lastMouseMoveEventSubframe;
420 RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
423 RefPtr<Node> m_clickNode;
425 #if ENABLE(DRAG_SUPPORT)
426 RefPtr<Node> m_dragTarget;
427 bool m_shouldOnlyFireDragOverEvent;
430 RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
432 LayoutSize m_offsetFromResizeCorner; // In the coords of m_resizeLayer.
434 IntPoint m_currentMousePosition;
435 IntPoint m_currentMouseGlobalPosition;
436 IntPoint m_mouseDownPos; // In our view's coords.
437 double m_mouseDownTimestamp;
438 PlatformMouseEvent m_mouseDown;
440 bool m_useLatchedWheelEventNode;
441 RefPtr<Node> m_latchedWheelEventNode;
442 bool m_widgetIsLatched;
444 RefPtr<Node> m_previousWheelScrolledNode;
447 NSView *m_mouseDownView;
448 bool m_sendingEventToSubview;
449 int m_activationEventNumber;
451 #if ENABLE(TOUCH_EVENTS)
452 typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
453 TouchTargetMap m_originatingTouchPointTargets;
456 double m_maxMouseMovedDuration;
457 PlatformEvent::Type m_baseEventType;
460 } // namespace WebCore
462 #endif // EventHandler_h