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
|
// 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 PointerEventManager_h
#define PointerEventManager_h
#include "core/CoreExport.h"
#include "core/events/PointerEvent.h"
#include "core/events/PointerEventFactory.h"
#include "core/input/BoundaryEventDispatcher.h"
#include "core/input/TouchEventManager.h"
#include "public/platform/WebInputEventResult.h"
#include "public/platform/WebPointerProperties.h"
#include "wtf/Allocator.h"
#include "wtf/HashMap.h"
namespace blink {
class LocalFrame;
class MouseEventManager;
// This class takes care of dispatching all pointer events and keeps track of
// properties of active pointer events.
class CORE_EXPORT PointerEventManager
: public GarbageCollectedFinalized<PointerEventManager> {
WTF_MAKE_NONCOPYABLE(PointerEventManager);
public:
PointerEventManager(LocalFrame&, MouseEventManager&);
DECLARE_TRACE();
// Sends the mouse pointer events and the boundary events
// that it may cause. It also sends the compat mouse events
// and sets the newNodeUnderMouse if the capturing is set
// in this function.
WebInputEventResult sendMousePointerEvent(
Node* target,
const AtomicString& type,
const PlatformMouseEvent&,
const Vector<PlatformMouseEvent>& coalescedEvents);
WebInputEventResult handleTouchEvents(
const PlatformTouchEvent&,
const Vector<PlatformTouchEvent>& coalescedEvents);
// Sends boundary events pointerout/leave/over/enter and
// mouseout/leave/over/enter to the corresponding targets.
// inside the document. This functions handles the cases that pointer is
// leaving a frame. Note that normal mouse events (e.g. mousemove/down/up)
// and their corresponding boundary events will be handled altogether by
// sendMousePointerEvent function.
void sendMouseAndPointerBoundaryEvents(Node* enteredNode,
const PlatformMouseEvent&);
// Resets the internal state of this object.
void clear();
void elementRemoved(EventTarget*);
void setPointerCapture(int, EventTarget*);
void releasePointerCapture(int, EventTarget*);
// See Element::hasPointerCapture(int).
bool hasPointerCapture(int, const EventTarget*) const;
// See Element::hasProcessedPointerCapture(int).
bool hasProcessedPointerCapture(int, const EventTarget*) const;
bool isActive(const int) const;
// Returns whether there is any touch on the screen.
bool isAnyTouchActive() const;
// Returns whether pointerId is for an active touch pointerevent and whether
// the last event was sent to the given frame.
bool isTouchPointerIdActiveOnFrame(int, LocalFrame*) const;
// Returns true if the primary pointerdown corresponding to the given
// |uniqueTouchEventId| was canceled. Also drops stale ids from
// |m_touchIdsForCanceledPointerdowns|.
bool primaryPointerdownCanceled(uint32_t uniqueTouchEventId);
private:
typedef HeapHashMap<int,
Member<EventTarget>,
WTF::IntHash<int>,
WTF::UnsignedWithZeroKeyHashTraits<int>>
PointerCapturingMap;
class EventTargetAttributes {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
DEFINE_INLINE_TRACE() { visitor->trace(target); }
Member<EventTarget> target;
bool hasRecievedOverEvent;
EventTargetAttributes() : target(nullptr), hasRecievedOverEvent(false) {}
EventTargetAttributes(EventTarget* target, bool hasRecievedOverEvent)
: target(target), hasRecievedOverEvent(hasRecievedOverEvent) {}
};
class PointerEventBoundaryEventDispatcher : public BoundaryEventDispatcher {
WTF_MAKE_NONCOPYABLE(PointerEventBoundaryEventDispatcher);
public:
PointerEventBoundaryEventDispatcher(PointerEventManager*, PointerEvent*);
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&,
bool checkForListener);
Member<PointerEventManager> m_pointerEventManager;
Member<PointerEvent> m_pointerEvent;
};
// Inhibits firing of touch-type PointerEvents until unblocked by
// unblockTouchPointers(). Also sends pointercancels for existing touch-type
// PointerEvents. See:
// www.w3.org/TR/pointerevents/#declaring-candidate-regions-for-default-touch-behaviors
void blockTouchPointers();
// Enables firing of touch-type PointerEvents after they were inhibited by
// blockTouchPointers().
void unblockTouchPointers();
// Generate the TouchInfos for a PlatformTouchEvent, hit-testing as necessary.
void computeTouchTargets(const PlatformTouchEvent&,
HeapVector<TouchEventManager::TouchInfo>&);
// Sends touch pointer events and sets consumed bits in TouchInfo array
// based on the return value of pointer event handlers.
void dispatchTouchPointerEvents(
const PlatformTouchEvent&,
const Vector<PlatformTouchEvent>& coalescedEvents,
HeapVector<TouchEventManager::TouchInfo>&);
// Returns whether the event is consumed or not.
WebInputEventResult sendTouchPointerEvent(EventTarget*, PointerEvent*);
void sendBoundaryEvents(EventTarget* exitedTarget,
EventTarget* enteredTarget,
PointerEvent*);
void setNodeUnderPointer(PointerEvent*, EventTarget*);
// Processes the assignment of |m_pointerCaptureTarget| from
// |m_pendingPointerCaptureTarget| and sends the got/lostpointercapture
// events, as per the spec:
// https://w3c.github.io/pointerevents/#process-pending-pointer-capture
void processPendingPointerCapture(PointerEvent*);
// Processes the capture state of a pointer, updates node under
// pointer, and sends corresponding boundary events for pointer if
// setPointerPosition is true. It also sends corresponding boundary events
// for mouse if sendMouseEvent is true.
// Returns the target that the pointer event is supposed to be fired at.
EventTarget* processCaptureAndPositionOfPointerEvent(
PointerEvent*,
EventTarget* hitTestTarget,
const PlatformMouseEvent& = PlatformMouseEvent(),
bool sendMouseEvent = false);
void removeTargetFromPointerCapturingMapping(PointerCapturingMap&,
const EventTarget*);
EventTarget* getEffectiveTargetForPointerEvent(EventTarget*, int);
EventTarget* getCapturingNode(int);
void removePointer(PointerEvent*);
WebInputEventResult dispatchPointerEvent(EventTarget*,
PointerEvent*,
bool checkForListener = false);
void releasePointerCapture(int);
// Returns true if capture target and pending capture target were different.
bool getPointerCaptureState(int pointerId,
EventTarget** pointerCaptureTarget,
EventTarget** pendingPointerCaptureTarget);
// NOTE: If adding a new field to this class please ensure that it is
// cleared in |PointerEventManager::clear()|.
const Member<LocalFrame> m_frame;
// Prevents firing mousedown, mousemove & mouseup in-between a canceled
// pointerdown and next pointerup/pointercancel.
// See "PREVENT MOUSE EVENT flag" in the spec:
// https://w3c.github.io/pointerevents/#compatibility-mapping-with-mouse-events
bool m_preventMouseEventForPointerType
[static_cast<size_t>(WebPointerProperties::PointerType::LastEntry) + 1];
// Set upon TouchScrollStarted when sending a pointercancel, prevents PE
// dispatches for touches until all touch-points become inactive.
bool m_inCanceledStateForPointerTypeTouch;
Deque<uint32_t> m_touchIdsForCanceledPointerdowns;
// Note that this map keeps track of node under pointer with id=1 as well
// which might be different than m_nodeUnderMouse in EventHandler. That one
// keeps track of any compatibility mouse event positions but this map for
// the pointer with id=1 is only taking care of true mouse related events.
using NodeUnderPointerMap =
HeapHashMap<int,
EventTargetAttributes,
WTF::IntHash<int>,
WTF::UnsignedWithZeroKeyHashTraits<int>>;
NodeUnderPointerMap m_nodeUnderPointer;
PointerCapturingMap m_pointerCaptureTarget;
PointerCapturingMap m_pendingPointerCaptureTarget;
PointerEventFactory m_pointerEventFactory;
Member<TouchEventManager> m_touchEventManager;
Member<MouseEventManager> m_mouseEventManager;
};
} // namespace blink
#endif // PointerEventManager_h
|