blob: 27530abc869d1cc5ab34ef32577982012672d8d3 [file] [log] [blame]
// 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 THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POINTER_EVENT_FACTORY_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POINTER_EVENT_FACTORY_H_
#include "third_party/blink/public/common/input/web_pointer_event.h"
#include "third_party/blink/public/common/input/web_pointer_properties.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/events/pointer_event.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
namespace blink {
// Helper class for tracking the pointer ids for each type of PointerEvents.
// Using id re-mapping at this layer, this class makes sure that regardless of
// the domain of the id (i.e. in touch or pen) the corresponding pointer event
// will have a unique id amongst all pointer events as per pointer events'
// specification. This class intended to behave the same as existing browsers as
// much as possible for compatibility reasons. Particularly it behaves very
// similar to MS Edge to have pointer event ids generated by mouse always equal
// 1 and those that are generated by touch and pen will have increasing ids from
// 2.
class CORE_EXPORT PointerEventFactory {
DISALLOW_NEW();
public:
PointerEventFactory();
~PointerEventFactory();
// Returns nullptr if the |web_pointer_event| is invalid from event stream
// perspective (e.g. it is a pointercancel for a non-existent id).
PointerEvent* Create(const WebPointerEvent& web_pointer_event,
const Vector<WebPointerEvent>& coalesced_events,
const Vector<WebPointerEvent>& predicted_events,
LocalDOMWindow* view);
PointerEvent* CreatePointerCancelEvent(const PointerId pointer_id,
base::TimeTicks platfrom_time_stamp);
// For creating raw update events in chorded button case.
PointerEvent* CreatePointerRawUpdateEvent(PointerEvent*);
// For creating capture events (i.e got/lostpointercapture).
PointerEvent* CreatePointerCaptureEvent(PointerEvent*, const AtomicString&);
// For creating boundary events (i.e pointerout/leave/over/enter).
PointerEvent* CreatePointerBoundaryEvent(PointerEvent*,
const AtomicString&,
EventTarget*);
// Clear all the existing ids.
void Clear();
// When a particular pointerId is removed, the id is considered free even
// though there might have been other PointerEvents that were generated with
// the same id before.
bool Remove(const PointerId);
// Returns all ids of pointers that are not hovering.
Vector<PointerId> GetPointerIdsOfNonHoveringPointers() const;
// Returns whether a pointer id exists and active.
bool IsActive(const PointerId) const;
// Returns whether a pointer id exists and has at least one pressed button.
bool IsActiveButtonsState(const PointerId) const;
// Returns the id of the pointer event corresponding to the given pointer
// properties if exists otherwise s_invalidId.
int GetPointerEventId(const WebPointerProperties&) const;
// Returns pointerType of for the given pointerId if such id is active.
// Otherwise it returns WebPointerProperties::PointerType::Unknown.
WebPointerProperties::PointerType GetPointerType(PointerId pointer_id) const;
// Returns whether a WebPoinerProperties is primary pointer.
bool IsPrimary(const WebPointerProperties&) const;
static const PointerId kMouseId;
static const PointerId kInvalidId;
// Removes pointer_id from the map.
void RemoveLastPosition(const PointerId pointer_id);
// Returns last_position of for the given pointerId if such id is active.
// Otherwise it returns the PositionInScreen of the given events, so we will
// get movement = 0 when there is no last position.
FloatPoint GetLastPointerPosition(PointerId pointer_id,
const WebPointerProperties& event,
WebInputEvent::Type event_type) const;
void SetLastPosition(PointerId pointer_id,
const FloatPoint& position_in_screen,
WebInputEvent::Type event_type);
private:
// We use int64_t to cover the whole range for PointerId with no
// deleted hash value.
template <typename T>
using PointerIdKeyMap = HashMap<int64_t,
T,
WTF::IntHash<int64_t>,
WTF::UnsignedWithZeroKeyHashTraits<int64_t>>;
typedef struct IncomingId : public std::pair<int, int> {
IncomingId() = default;
IncomingId(WebPointerProperties::PointerType pointer_type, int raw_id)
: std::pair<int, int>(static_cast<int>(pointer_type), raw_id) {}
int PointerTypeInt() const { return first; }
WebPointerProperties::PointerType GetPointerType() const {
return static_cast<WebPointerProperties::PointerType>(first);
}
int RawId() const { return second; }
} IncomingId;
typedef struct PointerAttributes {
IncomingId incoming_id;
bool is_active_buttons;
bool hovering;
PointerAttributes()
: incoming_id(), is_active_buttons(false), hovering(true) {}
PointerAttributes(IncomingId incoming_id,
bool is_active_buttons,
bool hovering)
: incoming_id(incoming_id),
is_active_buttons(is_active_buttons),
hovering(hovering) {}
} PointerAttributes;
PointerId AddIdAndActiveButtons(const IncomingId,
bool is_active_buttons,
bool hovering,
WebInputEvent::Type event_type);
bool IsPrimary(const PointerId) const;
// Returns nullptr when the event is unexpected. E.g. pointercancel for a
// non-existent id (see crbug.com/1007164).
PointerEventInit* ConvertIdTypeButtonsEvent(const WebPointerEvent&);
void SetEventSpecificFields(PointerEventInit*, const AtomicString& type);
// Creates pointerevents like boundary and capture events from another
// pointerevent (i.e. up/down/move events).
PointerEvent* CreatePointerEventFrom(PointerEvent*,
const AtomicString&,
EventTarget*);
HeapVector<Member<PointerEvent>> CreateEventSequence(
const WebPointerEvent& web_pointer_event,
const PointerEventInit* pointer_event_init,
const Vector<WebPointerEvent>& event_list,
LocalDOMWindow* view);
PointerId current_id_;
HashMap<IncomingId,
PointerId,
WTF::PairHash<int, int>,
WTF::PairHashTraits<WTF::UnsignedWithZeroKeyHashTraits<int>,
WTF::UnsignedWithZeroKeyHashTraits<int>>>
pointer_incoming_id_mapping_;
PointerIdKeyMap<PointerAttributes> pointer_id_mapping_;
int primary_id_[static_cast<int>(
WebPointerProperties::PointerType::kMaxValue) +
1];
int id_count_[static_cast<int>(WebPointerProperties::PointerType::kMaxValue) +
1];
PointerIdKeyMap<FloatPoint> pointer_id_last_position_mapping_;
PointerIdKeyMap<FloatPoint> pointerrawupdate_last_position_mapping_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_EVENTS_POINTER_EVENT_FACTORY_H_