File: MouseEventManager.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (230 lines) | stat: -rw-r--r-- 7,709 bytes parent folder | download
1
2
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MouseEventManager_h
#define MouseEventManager_h

#include "core/CoreExport.h"
#include "core/dom/SynchronousMutationObserver.h"
#include "core/input/BoundaryEventDispatcher.h"
#include "core/page/DragActions.h"
#include "core/page/EventWithHitTestResults.h"
#include "platform/PlatformMouseEvent.h"
#include "platform/Timer.h"
#include "public/platform/WebInputEventResult.h"
#include "wtf/Allocator.h"
#include "wtf/Time.h"

namespace blink {

class ContainerNode;
class DragState;
class DataTransfer;
class Element;
class FloatQuad;
class HitTestResult;
class InputDeviceCapabilities;
class LocalFrame;
class ScrollManager;

enum class DragInitiator;

// This class takes care of dispatching all mouse events and keeps track of
// positions and states of mouse.
class CORE_EXPORT MouseEventManager final
    : public GarbageCollectedFinalized<MouseEventManager>,
      public SynchronousMutationObserver {
  WTF_MAKE_NONCOPYABLE(MouseEventManager);
  USING_GARBAGE_COLLECTED_MIXIN(MouseEventManager);

 public:
  MouseEventManager(LocalFrame&, ScrollManager&);
  virtual ~MouseEventManager();
  DECLARE_TRACE();

  WebInputEventResult dispatchMouseEvent(EventTarget*,
                                         const AtomicString&,
                                         const PlatformMouseEvent&,
                                         EventTarget* relatedTarget,
                                         bool checkForListener = false);

  WebInputEventResult setMousePositionAndDispatchMouseEvent(
      Node* targetNode,
      const AtomicString& eventType,
      const PlatformMouseEvent&);

  WebInputEventResult dispatchMouseClickIfNeeded(
      const MouseEventWithHitTestResults&);

  WebInputEventResult dispatchDragSrcEvent(const AtomicString& eventType,
                                           const PlatformMouseEvent&);
  WebInputEventResult dispatchDragEvent(const AtomicString& eventType,
                                        Node* target,
                                        const PlatformMouseEvent&,
                                        DataTransfer*);

  // Resets the internal state of this object.
  void clear();

  void sendBoundaryEvents(EventTarget* exitedTarget,
                          EventTarget* enteredTarget,
                          const PlatformMouseEvent& mousePlatformEvent);

  void setNodeUnderMouse(Node*, const PlatformMouseEvent&);

  WebInputEventResult handleMouseFocus(
      const HitTestResult&,
      InputDeviceCapabilities* sourceCapabilities);

  void fakeMouseMoveEventTimerFired(TimerBase*);

  void cancelFakeMouseMoveEvent();
  void dispatchFakeMouseMoveEventSoon();
  void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&);

  void setLastKnownMousePosition(const PlatformMouseEvent&);

  bool handleDragDropIfPossible(const GestureEventWithHitTestResults&);

  WebInputEventResult handleMouseDraggedEvent(
      const MouseEventWithHitTestResults&);
  WebInputEventResult handleMousePressEvent(
      const MouseEventWithHitTestResults&);
  WebInputEventResult handleMouseReleaseEvent(
      const MouseEventWithHitTestResults&);

  static DragState& dragState();

  void focusDocumentView();

  // Resets the state that indicates the next events could cause a drag. It is
  // called when we realize the next events should not cause drag based on the
  // drag heuristics.
  void clearDragHeuristicState();

  void dragSourceEndedAt(const PlatformMouseEvent&, DragOperation);

  void updateSelectionForMouseDrag();

  void handleMousePressEventUpdateStates(const PlatformMouseEvent&);

  // Returns whether pan is handled and resets the state on release.
  bool handleSvgPanIfNeeded(bool isReleaseEvent);

  void invalidateClick();

  // TODO: These functions ideally should be private but the code needs more
  // refactoring to be able to remove the dependency from EventHandler.
  Node* getNodeUnderMouse();
  bool isMousePositionUnknown();
  IntPoint lastKnownMousePosition();

  bool mousePressed();
  void setMousePressed(bool);

  bool capturesDragging() const;
  void setCapturesDragging(bool);

  void setMouseDownMayStartAutoscroll() {
    m_mouseDownMayStartAutoscroll = true;
  }

  Node* mousePressNode();
  void setMousePressNode(Node*);

  void setClickNode(Node*);
  void setClickCount(int);

  bool mouseDownMayStartDrag();

 private:
  class MouseEventBoundaryEventDispatcher : public BoundaryEventDispatcher {
    WTF_MAKE_NONCOPYABLE(MouseEventBoundaryEventDispatcher);

   public:
    MouseEventBoundaryEventDispatcher(MouseEventManager*,
                                      const PlatformMouseEvent*,
                                      EventTarget* exitedTarget);

   protected:
    void dispatchOut(EventTarget*, EventTarget* relatedTarget) override;
    void dispatchOver(EventTarget*, EventTarget* relatedTarget) override;
    void dispatchLeave(EventTarget*,
                       EventTarget* relatedTarget,
                       bool checkForListener) override;
    void dispatchEnter(EventTarget*,
                       EventTarget* relatedTarget,
                       bool checkForListener) override;
    AtomicString getLeaveEvent() override;
    AtomicString getEnterEvent() override;

   private:
    void dispatch(EventTarget*,
                  EventTarget* relatedTarget,
                  const AtomicString&,
                  const PlatformMouseEvent&,
                  bool checkForListener);
    Member<MouseEventManager> m_mouseEventManager;
    const PlatformMouseEvent* m_platformMouseEvent;
    Member<EventTarget> m_exitedTarget;
  };

  // If the given element is a shadow host and its root has delegatesFocus=false
  // flag, slide focus to its inner element. Returns true if the resulting focus
  // is different from the given element.
  bool slideFocusOnShadowHostIfNecessary(const Element&);

  bool dragThresholdExceeded(const IntPoint&) const;
  bool handleDrag(const MouseEventWithHitTestResults&, DragInitiator);
  bool tryStartDrag(const MouseEventWithHitTestResults&);
  void clearDragDataTransfer();
  DataTransfer* createDraggingDataTransfer() const;

  // Implementations of |SynchronousMutationObserver|
  void nodeChildrenWillBeRemoved(ContainerNode&) final;
  void nodeWillBeRemoved(Node& nodeToBeRemoved) final;

  // NOTE: If adding a new field to this class please ensure that it is
  // cleared in |MouseEventManager::clear()|.

  const Member<LocalFrame> m_frame;
  Member<ScrollManager> m_scrollManager;

  // The effective position of the mouse pointer.
  // See
  // https://w3c.github.io/pointerevents/#dfn-tracking-the-effective-position-of-the-legacy-mouse-pointer.
  Member<Node> m_nodeUnderMouse;

  // The last mouse movement position this frame has seen in root frame
  // coordinates.
  IntPoint m_lastKnownMousePosition;
  IntPoint m_lastKnownMouseGlobalPosition;

  unsigned m_isMousePositionUnknown : 1;
  // Current button-press state for mouse/mouse-like-stylus.
  // TODO(crbug.com/563676): Buggy for chorded buttons.
  unsigned m_mousePressed : 1;

  unsigned m_mouseDownMayStartAutoscroll : 1;
  unsigned m_svgPan : 1;
  unsigned m_capturesDragging : 1;
  unsigned m_mouseDownMayStartDrag : 1;

  Member<Node> m_mousePressNode;

  int m_clickCount;
  Member<Node> m_clickNode;

  IntPoint m_mouseDownPos;  // In our view's coords.
  TimeTicks m_mouseDownTimestamp;
  PlatformMouseEvent m_mouseDown;

  LayoutPoint m_dragStartPos;

  TaskRunnerTimer<MouseEventManager> m_fakeMouseMoveEventTimer;
};

}  // namespace blink

#endif  // MouseEventManager_h