Fix for bug 13274. Rework mouse events so that subframe capturing works...
[WebKit-https.git] / WebCore / page / EventHandler.h
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 EventTargetNode;
52 class Event;
53 class FloatPoint;
54 class FloatRect;
55 class Frame;
56 class HitTestResult;
57 class HTMLFrameSetElement;
58 class KeyboardEvent;
59 class MouseEventWithHitTestResults;
60 class Node;
61 class PlatformKeyboardEvent;
62 class PlatformScrollbar;
63 class PlatformWheelEvent;
64 class RenderLayer;
65 class RenderObject;
66 class RenderWidget;
67 class String;
68 class TextEvent;
69 class VisiblePosition;
70 class Widget;
71     
72 struct HitTestRequest;
73
74 extern const int LinkDragHysteresis;
75 extern const int ImageDragHysteresis;
76 extern const int TextDragHysteresis;
77 extern const int GeneralDragHysteresis;
78 extern const double TextDragDelay;
79
80 class EventHandler : Noncopyable {
81 public:
82     EventHandler(Frame*);
83     ~EventHandler();
84
85     void clear();
86
87     void updateSelectionForMouseDragOverPosition(const VisiblePosition&);
88
89     Node* mousePressNode() const;
90     void setMousePressNode(PassRefPtr<Node>);
91
92     void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
93     RenderObject* autoscrollRenderer() const;
94
95     HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent);
96
97     bool mousePressed() const { return m_mousePressed; }
98     void setMousePressed(bool pressed) { m_mousePressed = pressed; }
99
100     void setCapturingMouseEventsNode(PassRefPtr<Node>);
101
102     bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
103     void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
104     bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);
105
106     void scheduleHoverStateUpdate();
107
108     void setResizingFrameSet(HTMLFrameSetElement*);
109
110     IntPoint currentMousePosition() const;
111
112     void setIgnoreWheelEvents(bool);
113
114     bool scrollOverflow(ScrollDirection, ScrollGranularity);
115
116     bool shouldDragAutoNode(Node*, const IntPoint&) const; // -webkit-user-drag == auto
117
118     bool tabsToLinks(KeyboardEvent*) const;
119     bool tabsToAllControls(KeyboardEvent*) const;
120
121     bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }
122
123     bool handleMousePressEvent(const PlatformMouseEvent&);
124     bool handleMouseMoveEvent(const PlatformMouseEvent&);
125     bool handleMouseReleaseEvent(const PlatformMouseEvent&);
126     bool handleWheelEvent(PlatformWheelEvent&);
127
128     bool sendContextMenuEvent(const PlatformMouseEvent&);
129
130     void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }
131
132     bool keyEvent(const PlatformKeyboardEvent&);
133     void defaultKeyboardEventHandler(KeyboardEvent*);
134
135     bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0,
136         bool isLineBreak = false, bool isBackTab = false);
137     void defaultTextInputEventHandler(TextEvent*);
138
139     bool eventMayStartDrag(const PlatformMouseEvent&) const;
140     
141     void dragSourceMovedTo(const PlatformMouseEvent&);
142     void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
143
144     void focusDocumentView();
145
146 #if PLATFORM(MAC)
147     PassRefPtr<KeyboardEvent> currentKeyboardEvent() const;
148
149     void mouseDown(NSEvent*);
150     void mouseDragged(NSEvent*);
151     void mouseUp(NSEvent*);
152     void mouseMoved(NSEvent*);
153     bool keyEvent(NSEvent*);
154     bool wheelEvent(NSEvent*);
155
156     void sendFakeEventsAfterWidgetTracking(NSEvent* initiatingEvent);
157
158     void setActivationEventNumber(int num) { m_activationEventNumber = num; }
159
160     NSEvent *currentNSEvent();
161 #endif
162
163 private:
164     struct EventHandlerDragState {
165         RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
166         bool m_dragSrcIsLink;
167         bool m_dragSrcIsImage;
168         bool m_dragSrcInSelection;
169         bool m_dragSrcMayBeDHTML;
170         bool m_dragSrcMayBeUA; // Are DHTML and/or the UserAgent allowed to drag out?
171         bool m_dragSrcIsDHTML;
172         RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
173     };
174     static EventHandlerDragState& dragState();
175     
176     Clipboard* createDraggingClipboard() const;
177     
178     bool eventActivatedView(const PlatformMouseEvent&) const;
179     void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults& event);
180
181     bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
182
183     bool handleMousePressEvent(const MouseEventWithHitTestResults&);
184     bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
185     bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
186     bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
187     bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
188     bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
189
190     void hoverTimerFired(Timer<EventHandler>*);
191
192     static bool canMouseDownStartSelect(Node*);
193
194     void handleAutoscroll(RenderObject*);
195     void startAutoscrollTimer();
196     void setAutoscrollRenderer(RenderObject*);
197
198     void autoscrollTimerFired(Timer<EventHandler>*);
199
200     void invalidateClick();
201
202     Node* nodeUnderMouse() const;
203
204     MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
205
206     bool dispatchMouseEvent(const AtomicString& eventType, Node* target,
207         bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
208     bool dispatchDragEvent(const AtomicString& eventType, Node* target,
209         const PlatformMouseEvent&, Clipboard*);
210
211     void freeClipboard();
212
213     bool handleDrag(const MouseEventWithHitTestResults&);
214     bool handleMouseUp(const MouseEventWithHitTestResults&);
215
216     bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);
217
218     bool dragHysteresisExceeded(const FloatPoint&) const;
219     bool dragHysteresisExceeded(const IntPoint&) const;
220
221     bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
222     bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
223     bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
224     bool passWheelEventToSubframe(PlatformWheelEvent&, Frame* subframe);
225
226     bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
227
228     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, PlatformScrollbar*);
229
230     bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
231     bool passWidgetMouseDownEventToWidget(RenderWidget*);
232
233     bool passMouseDownEventToWidget(Widget*);
234     bool passWheelEventToWidget(Widget*);
235
236     void defaultTabEventHandler(Event*, bool isBackTab);
237
238     void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
239
240     // The following are called at the beginning of handleMouseUp and handleDrag.  
241     // If they return true it indicates that they have consumed the event.
242 #if PLATFORM(MAC)
243     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
244     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
245     NSView *mouseDownViewIfStillGood();
246 #else
247     bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&) { return false; }
248     bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&) { return false; }
249 #endif
250
251     bool invertSenseOfTabsToLinks(KeyboardEvent*) const;
252
253     Frame* m_frame;
254
255     bool m_mousePressed;
256     RefPtr<Node> m_mousePressNode;
257
258     bool m_mouseDownMayStartSelect;
259     bool m_mouseDownMayStartDrag;
260     bool m_mouseDownWasSingleClickInSelection;
261     bool m_beganSelectingText;
262
263     IntPoint m_dragStartPos;
264
265     Timer<EventHandler> m_hoverTimer;
266     
267     Timer<EventHandler> m_autoscrollTimer;
268     RenderObject* m_autoscrollRenderer;
269     bool m_mouseDownMayStartAutoscroll;
270     bool m_mouseDownWasInSubframe;
271
272     RenderLayer* m_resizeLayer;
273
274     RefPtr<Node> m_capturingMouseEventsNode;
275     
276     RefPtr<Node> m_nodeUnderMouse;
277     RefPtr<Node> m_lastNodeUnderMouse;
278     RefPtr<Frame> m_lastMouseMoveEventSubframe;
279     RefPtr<PlatformScrollbar> m_lastScrollbarUnderMouse;
280
281     int m_clickCount;
282     RefPtr<Node> m_clickNode;
283
284     RefPtr<Node> m_dragTarget;
285     
286     RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;
287
288     IntSize m_offsetFromResizeCorner;    
289     
290     IntPoint m_currentMousePosition;
291     IntPoint m_mouseDownPos; // in our view's coords
292     double m_mouseDownTimestamp;
293     PlatformMouseEvent m_mouseDown;
294
295 #if PLATFORM(MAC)
296     NSView *m_mouseDownView;
297     bool m_sendingEventToSubview;
298     int m_activationEventNumber;
299 #endif
300
301 };
302
303 } // namespace WebCore
304
305 #endif // EventHandler_h