EventHandler.h 11.8 KB
Newer Older
darin's avatar
darin committed
1
/*
darin@apple.com's avatar
darin@apple.com committed
2
 * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
darin's avatar
darin committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#ifndef EventHandler_h
#define EventHandler_h

29
#include "DragActions.h"
darin's avatar
darin committed
30 31 32 33 34 35
#include "PlatformMouseEvent.h"
#include "ScrollTypes.h"
#include "Timer.h"
#include <wtf/Forward.h>
#include <wtf/RefPtr.h>

darin@apple.com's avatar
darin@apple.com committed
36
#if PLATFORM(MAC) && !defined(__OBJC__)
darin's avatar
darin committed
37 38 39 40 41 42 43
class NSView;
#endif

namespace WebCore {

class AtomicString;
class Clipboard;
44
class Cursor;
darin's avatar
darin committed
45 46 47
class Event;
class FloatPoint;
class Frame;
48
class HitTestRequest;
darin's avatar
darin committed
49 50 51 52 53
class HitTestResult;
class HTMLFrameSetElement;
class KeyboardEvent;
class MouseEventWithHitTestResults;
class Node;
adele's avatar
adele committed
54
class PlatformKeyboardEvent;
darin's avatar
darin committed
55 56 57 58
class PlatformWheelEvent;
class RenderLayer;
class RenderObject;
class RenderWidget;
hyatt@apple.com's avatar
hyatt@apple.com committed
59
class Scrollbar;
darin's avatar
darin committed
60
class String;
61
class SVGElementInstance;
darin's avatar
darin committed
62
class TextEvent;
darin's avatar
darin committed
63
class Widget;
64
    
oliver's avatar
 
oliver committed
65 66 67 68
extern const int LinkDragHysteresis;
extern const int ImageDragHysteresis;
extern const int TextDragHysteresis;
extern const int GeneralDragHysteresis;
aliceli1's avatar
aliceli1 committed
69

70 71
enum HitTestScrollbars { ShouldHitTestScrollbars, DontHitTestScrollbars };

bfulgham@webkit.org's avatar
bfulgham@webkit.org committed
72
class EventHandler : public Noncopyable {
darin's avatar
darin committed
73 74 75 76 77 78
public:
    EventHandler(Frame*);
    ~EventHandler();

    void clear();

darin's avatar
darin committed
79
    void updateSelectionForMouseDrag();
darin's avatar
darin committed
80 81 82 83

    Node* mousePressNode() const;
    void setMousePressNode(PassRefPtr<Node>);

84 85 86
    bool panScrollInProgress() { return m_panScrollInProgress; }
    void setPanScrollInProgress(bool inProgress) { m_panScrollInProgress = inProgress; }

darin's avatar
darin committed
87 88
    void stopAutoscrollTimer(bool rendererIsBeingDestroyed = false);
    RenderObject* autoscrollRenderer() const;
89
    void updateAutoscrollRenderer();
darin's avatar
darin committed
90

91
    HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars);
darin's avatar
darin committed
92 93 94 95

    bool mousePressed() const { return m_mousePressed; }
    void setMousePressed(bool pressed) { m_mousePressed = pressed; }

adele's avatar
adele committed
96 97
    void setCapturingMouseEventsNode(PassRefPtr<Node>);

darin's avatar
darin committed
98 99 100 101 102 103 104 105
    bool updateDragAndDrop(const PlatformMouseEvent&, Clipboard*);
    void cancelDragAndDrop(const PlatformMouseEvent&, Clipboard*);
    bool performDragAndDrop(const PlatformMouseEvent&, Clipboard*);

    void scheduleHoverStateUpdate();

    void setResizingFrameSet(HTMLFrameSetElement*);

mitz@apple.com's avatar
mitz@apple.com committed
106 107
    void resizeLayerDestroyed();

darin's avatar
darin committed
108 109 110 111 112 113
    IntPoint currentMousePosition() const;

    void setIgnoreWheelEvents(bool);

    bool scrollOverflow(ScrollDirection, ScrollGranularity);

114 115
    bool scrollRecursively(ScrollDirection, ScrollGranularity);

darin's avatar
darin committed
116 117 118 119 120 121 122
    bool shouldDragAutoNode(Node*, const IntPoint&) const; // -webkit-user-drag == auto

    bool tabsToLinks(KeyboardEvent*) const;
    bool tabsToAllControls(KeyboardEvent*) const;

    bool mouseDownMayStartSelect() const { return m_mouseDownMayStartSelect; }

123 124
    bool mouseMoved(const PlatformMouseEvent&);

aroben's avatar
aroben committed
125
    bool handleMousePressEvent(const PlatformMouseEvent&);
126
    bool handleMouseMoveEvent(const PlatformMouseEvent&, HitTestResult* hoveredNode = 0);
aroben's avatar
aroben committed
127 128
    bool handleMouseReleaseEvent(const PlatformMouseEvent&);
    bool handleWheelEvent(PlatformWheelEvent&);
darin's avatar
darin committed
129

darin's avatar
darin committed
130
    bool sendContextMenuEvent(const PlatformMouseEvent&);
aroben's avatar
aroben committed
131

darin's avatar
darin committed
132 133
    void setMouseDownMayStartAutoscroll() { m_mouseDownMayStartAutoscroll = true; }

ap@webkit.org's avatar
ap@webkit.org committed
134 135
    bool needsKeyboardEventDisambiguationQuirks() const;

ap@webkit.org's avatar
ap@webkit.org committed
136
    static unsigned accessKeyModifiers();
ap@webkit.org's avatar
ap@webkit.org committed
137
    bool handleAccessKey(const PlatformKeyboardEvent&);
adele's avatar
adele committed
138
    bool keyEvent(const PlatformKeyboardEvent&);
adele's avatar
adele committed
139
    void defaultKeyboardEventHandler(KeyboardEvent*);
darin's avatar
darin committed
140 141 142 143 144

    bool handleTextInputEvent(const String& text, Event* underlyingEvent = 0,
        bool isLineBreak = false, bool isBackTab = false);
    void defaultTextInputEventHandler(TextEvent*);

oliver's avatar
 
oliver committed
145
    bool eventMayStartDrag(const PlatformMouseEvent&) const;
146 147 148
    
    void dragSourceMovedTo(const PlatformMouseEvent&);
    void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);
darin's avatar
darin committed
149

adele's avatar
adele committed
150 151
    void focusDocumentView();

adele's avatar
adele committed
152 153
    void capsLockStateMayHaveChanged();
    
154 155
    void sendResizeEvent();
    void sendScrollEvent();
156
    
darin@apple.com's avatar
darin@apple.com committed
157
#if PLATFORM(MAC) && defined(__OBJC__)
darin's avatar
darin committed
158 159
    PassRefPtr<KeyboardEvent> currentKeyboardEvent() const;

darin@apple.com's avatar
darin@apple.com committed
160 161 162 163 164 165 166 167 168
    void mouseDown(NSEvent *);
    void mouseDragged(NSEvent *);
    void mouseUp(NSEvent *);
    void mouseMoved(NSEvent *);
    bool keyEvent(NSEvent *);
    bool wheelEvent(NSEvent *);

    bool sendContextMenuEvent(NSEvent *);
    bool eventMayStartDrag(NSEvent *);
darin's avatar
darin committed
169

darin@apple.com's avatar
darin@apple.com committed
170
    void sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent);
darin's avatar
darin committed
171 172 173

    void setActivationEventNumber(int num) { m_activationEventNumber = num; }

darin@apple.com's avatar
darin@apple.com committed
174
    static NSEvent *currentNSEvent();
darin's avatar
darin committed
175 176 177
#endif

private:
darin's avatar
darin committed
178 179 180 181 182 183 184 185 186 187 188
    struct EventHandlerDragState {
        RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
        bool m_dragSrcIsLink;
        bool m_dragSrcIsImage;
        bool m_dragSrcInSelection;
        bool m_dragSrcMayBeDHTML;
        bool m_dragSrcMayBeUA; // Are DHTML and/or the UserAgent allowed to drag out?
        bool m_dragSrcIsDHTML;
        RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
    };
    static EventHandlerDragState& dragState();
darin@apple.com's avatar
darin@apple.com committed
189
    static const double TextDragDelay;
190
    
darin@apple.com's avatar
darin@apple.com committed
191
    PassRefPtr<Clipboard> createDraggingClipboard() const;
192
    
oliver's avatar
 
oliver committed
193
    bool eventActivatedView(const PlatformMouseEvent&) const;
darin@apple.com's avatar
darin@apple.com committed
194 195
    void selectClosestWordFromMouseEvent(const MouseEventWithHitTestResults&);
    void selectClosestWordOrLinkFromMouseEvent(const MouseEventWithHitTestResults&);
darin's avatar
darin committed
196

aroben's avatar
aroben committed
197
    bool handleMouseDoubleClickEvent(const PlatformMouseEvent&);
darin's avatar
darin committed
198

aroben's avatar
aroben committed
199 200 201 202
    bool handleMousePressEvent(const MouseEventWithHitTestResults&);
    bool handleMousePressEventSingleClick(const MouseEventWithHitTestResults&);
    bool handleMousePressEventDoubleClick(const MouseEventWithHitTestResults&);
    bool handleMousePressEventTripleClick(const MouseEventWithHitTestResults&);
203
    bool handleMouseDraggedEvent(const MouseEventWithHitTestResults&);
aroben's avatar
aroben committed
204
    bool handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
darin's avatar
darin committed
205

206 207
    void handleKeyboardSelectionMovement(KeyboardEvent*);
    
hyatt@apple.com's avatar
hyatt@apple.com committed
208
    Cursor selectCursor(const MouseEventWithHitTestResults&, Scrollbar*);
209
#if ENABLE(PAN_SCROLLING)
210
    void setPanScrollCursor();
211
#endif
212

darin's avatar
darin committed
213 214 215
    void hoverTimerFired(Timer<EventHandler>*);

    static bool canMouseDownStartSelect(Node*);
adele's avatar
adele committed
216
    static bool canMouseDragExtendSelect(Node*);
darin's avatar
darin committed
217 218 219 220 221 222 223 224 225

    void handleAutoscroll(RenderObject*);
    void startAutoscrollTimer();
    void setAutoscrollRenderer(RenderObject*);
    void autoscrollTimerFired(Timer<EventHandler>*);

    void invalidateClick();

    Node* nodeUnderMouse() const;
226 227 228 229
    
    void updateMouseEventTargetNode(Node*, const PlatformMouseEvent&, bool fireMouseOverOut);
    void fireMouseOverOut(bool fireMouseOver = true, bool fireMouseOut = true, bool updateLastNodeUnderMouse = true);
    
darin's avatar
darin committed
230
    MouseEventWithHitTestResults prepareMouseEvent(const HitTestRequest&, const PlatformMouseEvent&);
darin's avatar
darin committed
231

232 233
    bool dispatchMouseEvent(const AtomicString& eventType, Node* target, bool cancelable, int clickCount, const PlatformMouseEvent&, bool setUnder);
    bool dispatchDragEvent(const AtomicString& eventType, Node* target, const PlatformMouseEvent&, Clipboard*);
darin's avatar
darin committed
234 235 236 237 238

    void freeClipboard();

    bool handleDrag(const MouseEventWithHitTestResults&);
    bool handleMouseUp(const MouseEventWithHitTestResults&);
239
    void clearDragState();
darin's avatar
darin committed
240 241 242 243

    bool dispatchDragSrcEvent(const AtomicString& eventType, const PlatformMouseEvent&);

    bool dragHysteresisExceeded(const FloatPoint&) const;
aliceli1's avatar
aliceli1 committed
244
    bool dragHysteresisExceeded(const IntPoint&) const;
darin's avatar
darin committed
245 246

    bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
247
    bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
darin's avatar
darin committed
248 249
    bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);

aroben's avatar
aroben committed
250
    bool passSubframeEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
darin's avatar
darin committed
251

hyatt@apple.com's avatar
hyatt@apple.com committed
252
    bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
darin's avatar
darin committed
253 254 255 256 257

    bool passWidgetMouseDownEventToWidget(const MouseEventWithHitTestResults&);
    bool passWidgetMouseDownEventToWidget(RenderWidget*);

    bool passMouseDownEventToWidget(Widget*);
andersca's avatar
andersca committed
258
    bool passWheelEventToWidget(PlatformWheelEvent&, Widget*);
darin's avatar
darin committed
259

darin@apple.com's avatar
darin@apple.com committed
260
    void defaultSpaceEventHandler(KeyboardEvent*);
adachan@apple.com's avatar
adachan@apple.com committed
261
    void defaultTabEventHandler(KeyboardEvent*);
darin's avatar
darin committed
262

263
    void allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const;
darin's avatar
darin committed
264

darin's avatar
darin committed
265 266 267 268
    // The following are called at the beginning of handleMouseUp and handleDrag.  
    // If they return true it indicates that they have consumed the event.
    bool eventLoopHandleMouseUp(const MouseEventWithHitTestResults&);
    bool eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&);
darin's avatar
darin committed
269

mjs's avatar
mjs committed
270 271
    bool invertSenseOfTabsToLinks(KeyboardEvent*) const;

darin's avatar
darin committed
272 273
    void updateSelectionForMouseDrag(Node* targetNode, const IntPoint& localPoint);

treat@webkit.org's avatar
treat@webkit.org committed
274 275
    void updateLastScrollbarUnderMouse(Scrollbar*, bool);

276 277
    bool capturesDragging() const { return m_capturesDragging; }

darin@apple.com's avatar
darin@apple.com committed
278 279 280 281 282 283
#if PLATFORM(MAC) && defined(__OBJC__)
    NSView *mouseDownViewIfStillGood();

    PlatformMouseEvent currentPlatformMouseEvent() const;
#endif

darin's avatar
darin committed
284 285 286
    Frame* m_frame;

    bool m_mousePressed;
287
    bool m_capturesDragging;
darin's avatar
darin committed
288 289
    RefPtr<Node> m_mousePressNode;

darin's avatar
darin committed
290 291 292
    bool m_mouseDownMayStartSelect;
    bool m_mouseDownMayStartDrag;
    bool m_mouseDownWasSingleClickInSelection;
darin's avatar
darin committed
293 294 295 296
    bool m_beganSelectingText;

    IntPoint m_dragStartPos;

297 298 299
    IntPoint m_panScrollStartPos;
    bool m_panScrollInProgress;

darin's avatar
darin committed
300 301 302 303
    Timer<EventHandler> m_hoverTimer;
    
    Timer<EventHandler> m_autoscrollTimer;
    RenderObject* m_autoscrollRenderer;
304
    bool m_autoscrollInProgress;
darin's avatar
darin committed
305
    bool m_mouseDownMayStartAutoscroll;
darin's avatar
darin committed
306
    bool m_mouseDownWasInSubframe;
darin@apple.com's avatar
darin@apple.com committed
307

weinig's avatar
weinig committed
308 309
#if ENABLE(SVG)
    bool m_svgPan;
310 311
    RefPtr<SVGElementInstance> m_instanceUnderMouse;
    RefPtr<SVGElementInstance> m_lastInstanceUnderMouse;
weinig's avatar
weinig committed
312
#endif
darin's avatar
darin committed
313 314 315

    RenderLayer* m_resizeLayer;

adele's avatar
adele committed
316 317
    RefPtr<Node> m_capturingMouseEventsNode;
    
darin's avatar
darin committed
318 319 320
    RefPtr<Node> m_nodeUnderMouse;
    RefPtr<Node> m_lastNodeUnderMouse;
    RefPtr<Frame> m_lastMouseMoveEventSubframe;
hyatt@apple.com's avatar
hyatt@apple.com committed
321
    RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
darin's avatar
darin committed
322 323 324 325 326 327 328 329

    int m_clickCount;
    RefPtr<Node> m_clickNode;

    RefPtr<Node> m_dragTarget;
    
    RefPtr<HTMLFrameSetElement> m_frameSetBeingResized;

330
    IntSize m_offsetFromResizeCorner;   // in the coords of m_resizeLayer
darin's avatar
darin committed
331 332
    
    IntPoint m_currentMousePosition;
aliceli1's avatar
aliceli1 committed
333 334
    IntPoint m_mouseDownPos; // in our view's coords
    double m_mouseDownTimestamp;
335
    PlatformMouseEvent m_mouseDown;
336

andersca@apple.com's avatar
andersca@apple.com committed
337 338 339 340
    bool m_useLatchedWheelEventNode;
    RefPtr<Node> m_latchedWheelEventNode;
    bool m_widgetIsLatched;
    
darin's avatar
darin committed
341 342 343 344 345 346 347 348 349 350
#if PLATFORM(MAC)
    NSView *m_mouseDownView;
    bool m_sendingEventToSubview;
    int m_activationEventNumber;
#endif
};

} // namespace WebCore

#endif // EventHandler_h