Commit a6c1687b authored by Ella Ge's avatar Ella Ge Committed by Commit Bot

move unlocked state movementX/Y calculation to blink

This change is under a blink flag MovementXYInBlink.
With the flag on, MouseEvent and PointerEvent's movement_x/y is
calculated in blink instead of in browser.

The movement_x/y for pointerrawmove event is not set yet. And also this
CL does not handle the calculation when pointer is locked. These is
going to be done in the following changes. See the design doc:
https://docs.google.com/document/d/1jL93PMbNHLhr6jYd4AWkjB8wgS73C5EDUa_2kYOjOn4/

With the flag, movement_x/y is in dip (same scale with screenX/Y),
which is different the current behavior(physical pixel). The coordinate
space is discuss in this doc:
https://docs.google.com/document/d/1mYk4qMxBVsFweqFOku2FZvMajejp2Q7XWGIld9ivlXE/
It needs to be changed or clarified before we enable the flag.

Bug: 802067
Change-Id: I5abb71181702c3b5265985f6ff8d2537116c5e18
Reviewed-on: https://chromium-review.googlesource.com/c/1297744Reviewed-by: default avatarMustaq Ahmed <mustaq@chromium.org>
Reviewed-by: default avatarDavid Bokan <bokan@chromium.org>
Commit-Queue: Ella Ge <eirage@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610148}
parent 9b1a9eb7
...@@ -190,7 +190,7 @@ MouseEvent::MouseEvent(const AtomicString& event_type, ...@@ -190,7 +190,7 @@ MouseEvent::MouseEvent(const AtomicString& event_type,
screen_location_( screen_location_(
DoublePoint(initializer->screenX(), initializer->screenY())), DoublePoint(initializer->screenX(), initializer->screenY())),
movement_delta_( movement_delta_(
IntPoint(initializer->movementX(), initializer->movementY())), DoublePoint(initializer->movementX(), initializer->movementY())),
position_type_(synthetic_event_type == kPositionless position_type_(synthetic_event_type == kPositionless
? PositionType::kPositionless ? PositionType::kPositionless
: PositionType::kPosition), : PositionType::kPosition),
...@@ -236,11 +236,13 @@ void MouseEvent::SetCoordinatesFromWebPointerProperties( ...@@ -236,11 +236,13 @@ void MouseEvent::SetCoordinatesFromWebPointerProperties(
initializer->setClientX(client_point.X()); initializer->setClientX(client_point.X());
initializer->setClientY(client_point.Y()); initializer->setClientY(client_point.Y());
// TODO(nzolghadr): We need to scale movement attrinutes as well. But if we do // TODO(nzolghadr): We need to scale movement attrinutes as well. But if we
// that here and round it to the int again it causes inconsistencies between // do that here and round it to the int again it causes inconsistencies
// screenX/Y and cumulative movementX/Y. // between screenX/Y and cumulative movementX/Y.
initializer->setMovementX(web_pointer_properties.movement_x); if (!RuntimeEnabledFeatures::MovementXYInBlinkEnabled()) {
initializer->setMovementY(web_pointer_properties.movement_y); initializer->setMovementX(web_pointer_properties.movement_x);
initializer->setMovementY(web_pointer_properties.movement_y);
}
} }
MouseEvent::~MouseEvent() = default; MouseEvent::~MouseEvent() = default;
......
...@@ -185,8 +185,8 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState { ...@@ -185,8 +185,8 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
WebMenuSourceType GetMenuSourceType() const { return menu_source_type_; } WebMenuSourceType GetMenuSourceType() const { return menu_source_type_; }
// Page point in "absolute" coordinates (i.e. post-zoomed, page-relative // Page point in "absolute" coordinates (i.e. post-zoomed, page-relative
// coords, usable with LayoutObject::absoluteToLocal) relative to view(), i.e. // coords, usable with LayoutObject::absoluteToLocal) relative to view(),
// the local frame. // i.e. the local frame.
const DoublePoint& AbsoluteLocation() const { return absolute_location_; } const DoublePoint& AbsoluteLocation() const { return absolute_location_; }
DispatchEventResult DispatchEvent(EventDispatcher&) override; DispatchEventResult DispatchEvent(EventDispatcher&) override;
...@@ -215,7 +215,7 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState { ...@@ -215,7 +215,7 @@ class CORE_EXPORT MouseEvent : public UIEventWithKeyState {
DoublePoint screen_location_; DoublePoint screen_location_;
DoublePoint client_location_; DoublePoint client_location_;
DoublePoint page_location_; // zoomed CSS pixels DoublePoint page_location_; // zoomed CSS pixels
DoublePoint offset_location_; // zoomed CSS pixels DoublePoint offset_location_; // zoomed CSS pixels
bool has_cached_relative_position_ = false; bool has_cached_relative_position_ = false;
......
...@@ -80,7 +80,9 @@ float GetPointerEventPressure(float force, int buttons) { ...@@ -80,7 +80,9 @@ float GetPointerEventPressure(float force, int buttons) {
return 0.5; return 0.5;
return force; return force;
} }
void UpdateCommonPointerEventInit(const WebPointerEvent& web_pointer_event, void UpdateCommonPointerEventInit(const WebPointerEvent& web_pointer_event,
const FloatPoint& last_global_position,
LocalDOMWindow* dom_window, LocalDOMWindow* dom_window,
PointerEventInit* pointer_event_init) { PointerEventInit* pointer_event_init) {
// This function should not update attributes like pointerId, isPrimary, // This function should not update attributes like pointerId, isPrimary,
...@@ -92,6 +94,15 @@ void UpdateCommonPointerEventInit(const WebPointerEvent& web_pointer_event, ...@@ -92,6 +94,15 @@ void UpdateCommonPointerEventInit(const WebPointerEvent& web_pointer_event,
MouseEvent::SetCoordinatesFromWebPointerProperties( MouseEvent::SetCoordinatesFromWebPointerProperties(
web_pointer_event_in_root_frame, dom_window, pointer_event_init); web_pointer_event_in_root_frame, dom_window, pointer_event_init);
if (RuntimeEnabledFeatures::MovementXYInBlinkEnabled() &&
web_pointer_event.GetType() == WebInputEvent::kPointerMove) {
// TODO(eirage): pointerrawmove event's movements are not calculated.
pointer_event_init->setMovementX(web_pointer_event.PositionInScreen().x -
last_global_position.X());
pointer_event_init->setMovementY(web_pointer_event.PositionInScreen().y -
last_global_position.Y());
}
// If width/height is unknown we let PointerEventInit set it to 1. // If width/height is unknown we let PointerEventInit set it to 1.
// See https://w3c.github.io/pointerevents/#dom-pointerevent-width // See https://w3c.github.io/pointerevents/#dom-pointerevent-width
if (web_pointer_event_in_root_frame.HasWidth() && if (web_pointer_event_in_root_frame.HasWidth() &&
...@@ -115,49 +126,61 @@ void UpdateCommonPointerEventInit(const WebPointerEvent& web_pointer_event, ...@@ -115,49 +126,61 @@ void UpdateCommonPointerEventInit(const WebPointerEvent& web_pointer_event,
pointer_event_init->setTwist(web_pointer_event.twist); pointer_event_init->setTwist(web_pointer_event.twist);
} }
HeapVector<Member<PointerEvent>> CreateEventSequence( } // namespace
HeapVector<Member<PointerEvent>> PointerEventFactory::CreateEventSequence(
const WebPointerEvent& web_pointer_event, const WebPointerEvent& web_pointer_event,
const PointerEventInit* pointer_event_init, const PointerEventInit* pointer_event_init,
const Vector<WebPointerEvent>& event_list, const Vector<WebPointerEvent>& event_list,
LocalDOMWindow* view) { LocalDOMWindow* view) {
AtomicString type = PointerEventNameForEventType(web_pointer_event.GetType()); AtomicString type = PointerEventNameForEventType(web_pointer_event.GetType());
HeapVector<Member<PointerEvent>> result; HeapVector<Member<PointerEvent>> result;
for (const auto& event : event_list) {
DCHECK_EQ(web_pointer_event.id, event.id); if (!event_list.IsEmpty()) {
DCHECK_EQ(web_pointer_event.GetType(), event.GetType()); // Make a copy of LastPointerPosition so we can modify it after creating
DCHECK_EQ(web_pointer_event.pointer_type, event.pointer_type); // each coalesced event.
FloatPoint last_global_position = GetLastPointerPosition(
PointerEventInit* new_event_init = PointerEventInit::Create(); pointer_event_init->pointerId(), event_list.front());
if (pointer_event_init->hasButton())
new_event_init->setButton(pointer_event_init->button()); for (const auto& event : event_list) {
if (pointer_event_init->hasButtons()) DCHECK_EQ(web_pointer_event.id, event.id);
new_event_init->setButtons(pointer_event_init->buttons()); DCHECK_EQ(web_pointer_event.GetType(), event.GetType());
if (pointer_event_init->hasIsPrimary()) DCHECK_EQ(web_pointer_event.pointer_type, event.pointer_type);
new_event_init->setIsPrimary(pointer_event_init->isPrimary());
if (pointer_event_init->hasPointerId()) PointerEventInit* new_event_init = PointerEventInit::Create();
new_event_init->setPointerId(pointer_event_init->pointerId()); if (pointer_event_init->hasButton())
if (pointer_event_init->hasPointerType()) new_event_init->setButton(pointer_event_init->button());
new_event_init->setPointerType(pointer_event_init->pointerType()); if (pointer_event_init->hasButtons())
if (pointer_event_init->hasView()) new_event_init->setButtons(pointer_event_init->buttons());
new_event_init->setView(pointer_event_init->view()); if (pointer_event_init->hasIsPrimary())
new_event_init->setIsPrimary(pointer_event_init->isPrimary());
new_event_init->setCancelable(false); if (pointer_event_init->hasPointerId())
new_event_init->setBubbles(false); new_event_init->setPointerId(pointer_event_init->pointerId());
UpdateCommonPointerEventInit(event, view, new_event_init); if (pointer_event_init->hasPointerType())
PointerEvent* pointer_event = new_event_init->setPointerType(pointer_event_init->pointerType());
PointerEvent::Create(type, new_event_init, event.TimeStamp()); if (pointer_event_init->hasView())
// Set the trusted flag for these events at the creation time as oppose to new_event_init->setView(pointer_event_init->view());
// the normal events which is done at the dispatch time. This is because we
// don't want to go over all these events at every dispatch and add the new_event_init->setCancelable(false);
// implementation complexity while it has no sensible usecase at this time. new_event_init->setBubbles(false);
pointer_event->SetTrusted(true); UpdateCommonPointerEventInit(event, last_global_position, view,
result.push_back(pointer_event); new_event_init);
last_global_position = event.PositionInScreen();
PointerEvent* pointer_event =
PointerEvent::Create(type, new_event_init, event.TimeStamp());
// Set the trusted flag for these events at the creation time as oppose to
// the normal events which is done at the dispatch time. This is because
// we don't want to go over all these events at every dispatch and add the
// implementation complexity while it has no sensible usecase at this
// time.
pointer_event->SetTrusted(true);
result.push_back(pointer_event);
}
} }
return result; return result;
} }
} // namespace
const int PointerEventFactory::kInvalidId = 0; const int PointerEventFactory::kInvalidId = 0;
// Mouse id is 1 to behave the same as MS Edge for compatibility reasons. // Mouse id is 1 to behave the same as MS Edge for compatibility reasons.
...@@ -263,7 +286,11 @@ PointerEvent* PointerEventFactory::Create( ...@@ -263,7 +286,11 @@ PointerEvent* PointerEventFactory::Create(
} }
pointer_event_init->setView(view); pointer_event_init->setView(view);
UpdateCommonPointerEventInit(web_pointer_event, view, pointer_event_init); UpdateCommonPointerEventInit(
web_pointer_event,
GetLastPointerPosition(pointer_event_init->pointerId(),
web_pointer_event),
view, pointer_event_init);
UIEventWithKeyState::SetFromWebInputEventModifiers( UIEventWithKeyState::SetFromWebInputEventModifiers(
pointer_event_init, pointer_event_init,
...@@ -285,10 +312,30 @@ PointerEvent* PointerEventFactory::Create( ...@@ -285,10 +312,30 @@ PointerEvent* PointerEventFactory::Create(
pointer_event_init->setCoalescedEvents(coalesced_pointer_events); pointer_event_init->setCoalescedEvents(coalesced_pointer_events);
pointer_event_init->setPredictedEvents(predicted_pointer_events); pointer_event_init->setPredictedEvents(predicted_pointer_events);
SetLastPosition(pointer_event_init->pointerId(), web_pointer_event);
return PointerEvent::Create(type, pointer_event_init, return PointerEvent::Create(type, pointer_event_init,
web_pointer_event.TimeStamp()); web_pointer_event.TimeStamp());
} }
void PointerEventFactory::SetLastPosition(int pointer_id,
const WebPointerProperties& event) {
pointer_id_last_position_mapping_.Set(pointer_id, event.PositionInScreen());
}
void PointerEventFactory::RemoveLastPosition(const int pointer_id) {
return pointer_id_last_position_mapping_.erase(pointer_id);
}
FloatPoint PointerEventFactory::GetLastPointerPosition(
int pointer_id,
const WebPointerProperties& event) const {
if (pointer_id_last_position_mapping_.Contains(pointer_id))
return pointer_id_last_position_mapping_.at(pointer_id);
// If pointer_id is not in the map, returns the current position so the
// movement will be zero.
return event.PositionInScreen();
}
PointerEvent* PointerEventFactory::CreatePointerCancelEvent( PointerEvent* PointerEventFactory::CreatePointerCancelEvent(
const int pointer_id, const int pointer_id,
TimeTicks platfrom_time_stamp) { TimeTicks platfrom_time_stamp) {
...@@ -399,6 +446,7 @@ void PointerEventFactory::Clear() { ...@@ -399,6 +446,7 @@ void PointerEventFactory::Clear() {
} }
pointer_incoming_id_mapping_.clear(); pointer_incoming_id_mapping_.clear();
pointer_id_mapping_.clear(); pointer_id_mapping_.clear();
pointer_id_last_position_mapping_.clear();
// Always add mouse pointer in initialization and never remove it. // Always add mouse pointer in initialization and never remove it.
// No need to add it to m_pointerIncomingIdMapping as it is not going to be // No need to add it to m_pointerIncomingIdMapping as it is not going to be
...@@ -449,6 +497,7 @@ bool PointerEventFactory::Remove(const int mapped_id) { ...@@ -449,6 +497,7 @@ bool PointerEventFactory::Remove(const int mapped_id) {
int type_int = p.PointerTypeInt(); int type_int = p.PointerTypeInt();
pointer_id_mapping_.erase(mapped_id); pointer_id_mapping_.erase(mapped_id);
pointer_incoming_id_mapping_.erase(p); pointer_incoming_id_mapping_.erase(p);
RemoveLastPosition(mapped_id);
if (primary_id_[type_int] == mapped_id) if (primary_id_[type_int] == mapped_id)
primary_id_[type_int] = PointerEventFactory::kInvalidId; primary_id_[type_int] = PointerEventFactory::kInvalidId;
id_count_[type_int]--; id_count_[type_int]--;
......
...@@ -80,6 +80,15 @@ class CORE_EXPORT PointerEventFactory { ...@@ -80,6 +80,15 @@ class CORE_EXPORT PointerEventFactory {
static const int kMouseId; static const int kMouseId;
// Removes pointer_id from the map.
void RemoveLastPosition(const int 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(int pointer_id,
const WebPointerProperties& event) const;
private: private:
typedef WTF::UnsignedWithZeroKeyHashTraits<int> UnsignedHash; typedef WTF::UnsignedWithZeroKeyHashTraits<int> UnsignedHash;
typedef struct IncomingId : public std::pair<int, int> { typedef struct IncomingId : public std::pair<int, int> {
...@@ -119,6 +128,14 @@ class CORE_EXPORT PointerEventFactory { ...@@ -119,6 +128,14 @@ class CORE_EXPORT PointerEventFactory {
const AtomicString&, const AtomicString&,
EventTarget*); EventTarget*);
HeapVector<Member<PointerEvent>> CreateEventSequence(
const WebPointerEvent& web_pointer_event,
const PointerEventInit* pointer_event_init,
const Vector<WebPointerEvent>& event_list,
LocalDOMWindow* view);
void SetLastPosition(int pointer_id, const WebPointerProperties& event);
static const int kInvalidId; static const int kInvalidId;
int current_id_; int current_id_;
...@@ -135,6 +152,9 @@ class CORE_EXPORT PointerEventFactory { ...@@ -135,6 +152,9 @@ class CORE_EXPORT PointerEventFactory {
int id_count_[static_cast<int>( int id_count_[static_cast<int>(
WebPointerProperties::PointerType::kLastEntry) + WebPointerProperties::PointerType::kLastEntry) +
1]; 1];
HashMap<int, FloatPoint, WTF::IntHash<int>, UnsignedHash>
pointer_id_last_position_mapping_;
}; };
} // namespace blink } // namespace blink
......
...@@ -807,6 +807,7 @@ void EventHandler::HandleMouseLeaveEvent(const WebMouseEvent& event) { ...@@ -807,6 +807,7 @@ void EventHandler::HandleMouseLeaveEvent(const WebMouseEvent& event) {
HandleMouseMoveOrLeaveEvent(event, Vector<WebMouseEvent>(), HandleMouseMoveOrLeaveEvent(event, Vector<WebMouseEvent>(),
Vector<WebMouseEvent>(), nullptr, nullptr, false, Vector<WebMouseEvent>(), nullptr, nullptr, false,
true); true);
pointer_event_manager_->RemoveLastMousePosition();
} }
WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent( WebInputEventResult EventHandler::HandleMouseMoveOrLeaveEvent(
...@@ -1899,7 +1900,7 @@ WebInputEventResult EventHandler::SendContextMenuEvent( ...@@ -1899,7 +1900,7 @@ WebInputEventResult EventHandler::SendContextMenuEvent(
return mouse_event_manager_->DispatchMouseEvent( return mouse_event_manager_->DispatchMouseEvent(
EffectiveMouseEventTargetNode(target_node), EffectiveMouseEventTargetNode(target_node),
event_type_names::kContextmenu, event, event_type_names::kContextmenu, event,
mev.GetHitTestResult().CanvasRegionId(), nullptr); mev.GetHitTestResult().CanvasRegionId(), nullptr, nullptr);
} }
static bool ShouldShowContextMenuAtSelection(const FrameSelection& selection) { static bool ShouldShowContextMenuAtSelection(const FrameSelection& selection) {
......
...@@ -61,6 +61,27 @@ String CanvasRegionId(Node* node, const WebMouseEvent& mouse_event) { ...@@ -61,6 +61,27 @@ String CanvasRegionId(Node* node, const WebMouseEvent& mouse_event) {
return canvas->GetIdFromControl(element); return canvas->GetIdFromControl(element);
} }
void UpdateMouseMovementXY(const WebMouseEvent& mouse_event,
const FloatPoint* last_position,
MouseEventInit* initializer) {
if (RuntimeEnabledFeatures::MovementXYInBlinkEnabled() &&
mouse_event.GetType() == WebInputEvent::kMouseMove && last_position) {
if (RuntimeEnabledFeatures::FractionalMouseEventEnabled()) {
initializer->setMovementX(mouse_event.PositionInScreen().x -
last_position->X());
initializer->setMovementY(mouse_event.PositionInScreen().y -
last_position->Y());
} else {
initializer->setMovementX(
static_cast<int>(mouse_event.PositionInScreen().x) -
static_cast<int>(last_position->X()));
initializer->setMovementY(
static_cast<int>(mouse_event.PositionInScreen().y) -
static_cast<int>(last_position->Y()));
}
}
}
// The amount of time to wait before sending a fake mouse event triggered // The amount of time to wait before sending a fake mouse event triggered
// during a scroll. // during a scroll.
constexpr TimeDelta kFakeMouseMoveIntervalDuringScroll = constexpr TimeDelta kFakeMouseMoveIntervalDuringScroll =
...@@ -192,8 +213,8 @@ void MouseEventManager::MouseEventBoundaryEventDispatcher::Dispatch( ...@@ -192,8 +213,8 @@ void MouseEventManager::MouseEventBoundaryEventDispatcher::Dispatch(
const WebMouseEvent& web_mouse_event, const WebMouseEvent& web_mouse_event,
bool check_for_listener) { bool check_for_listener) {
mouse_event_manager_->DispatchMouseEvent(target, type, web_mouse_event, mouse_event_manager_->DispatchMouseEvent(target, type, web_mouse_event,
canvas_region_id, related_target, canvas_region_id, nullptr,
check_for_listener); related_target, check_for_listener);
} }
void MouseEventManager::SendBoundaryEvents(EventTarget* exited_target, void MouseEventManager::SendBoundaryEvents(EventTarget* exited_target,
...@@ -210,6 +231,7 @@ WebInputEventResult MouseEventManager::DispatchMouseEvent( ...@@ -210,6 +231,7 @@ WebInputEventResult MouseEventManager::DispatchMouseEvent(
const AtomicString& mouse_event_type, const AtomicString& mouse_event_type,
const WebMouseEvent& mouse_event, const WebMouseEvent& mouse_event,
const String& canvas_region_id, const String& canvas_region_id,
const FloatPoint* last_position,
EventTarget* related_target, EventTarget* related_target,
bool check_for_listener) { bool check_for_listener) {
if (target && target->ToNode() && if (target && target->ToNode() &&
...@@ -232,6 +254,7 @@ WebInputEventResult MouseEventManager::DispatchMouseEvent( ...@@ -232,6 +254,7 @@ WebInputEventResult MouseEventManager::DispatchMouseEvent(
MouseEvent::SetCoordinatesFromWebPointerProperties( MouseEvent::SetCoordinatesFromWebPointerProperties(
mouse_event.FlattenTransform(), target_node->GetDocument().domWindow(), mouse_event.FlattenTransform(), target_node->GetDocument().domWindow(),
initializer); initializer);
UpdateMouseMovementXY(mouse_event, last_position, initializer);
initializer->setButton(static_cast<short>(mouse_event.button)); initializer->setButton(static_cast<short>(mouse_event.button));
initializer->setButtons(MouseEvent::WebInputEventModifiersToButtons( initializer->setButtons(MouseEvent::WebInputEventModifiersToButtons(
mouse_event.GetModifiers())); mouse_event.GetModifiers()));
...@@ -275,7 +298,7 @@ WebInputEventResult MouseEventManager::SetMousePositionAndDispatchMouseEvent( ...@@ -275,7 +298,7 @@ WebInputEventResult MouseEventManager::SetMousePositionAndDispatchMouseEvent(
SetNodeUnderMouse(target_node, canvas_region_id, web_mouse_event); SetNodeUnderMouse(target_node, canvas_region_id, web_mouse_event);
return DispatchMouseEvent(node_under_mouse_, event_type, web_mouse_event, return DispatchMouseEvent(node_under_mouse_, event_type, web_mouse_event,
canvas_region_id, nullptr); canvas_region_id, nullptr, nullptr);
} }
WebInputEventResult MouseEventManager::DispatchMouseClickIfNeeded( WebInputEventResult MouseEventManager::DispatchMouseClickIfNeeded(
...@@ -340,7 +363,7 @@ WebInputEventResult MouseEventManager::DispatchMouseClickIfNeeded( ...@@ -340,7 +363,7 @@ WebInputEventResult MouseEventManager::DispatchMouseClickIfNeeded(
(mev.Event().button == WebPointerProperties::Button::kLeft) (mev.Event().button == WebPointerProperties::Button::kLeft)
? event_type_names::kClick ? event_type_names::kClick
: event_type_names::kAuxclick, : event_type_names::kAuxclick,
mev.Event(), mev.CanvasRegionId(), nullptr); mev.Event(), mev.CanvasRegionId(), nullptr, nullptr);
} }
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
......
...@@ -49,6 +49,7 @@ class CORE_EXPORT MouseEventManager final ...@@ -49,6 +49,7 @@ class CORE_EXPORT MouseEventManager final
const AtomicString&, const AtomicString&,
const WebMouseEvent&, const WebMouseEvent&,
const String& canvas_region_id, const String& canvas_region_id,
const FloatPoint* last_position,
EventTarget* related_target, EventTarget* related_target,
bool check_for_listener = false); bool check_for_listener = false);
......
...@@ -610,12 +610,18 @@ WebInputEventResult PointerEventManager::DirectDispatchMousePointerEvent( ...@@ -610,12 +610,18 @@ WebInputEventResult PointerEventManager::DirectDispatchMousePointerEvent(
const Vector<WebMouseEvent>& coalesced_events, const Vector<WebMouseEvent>& coalesced_events,
const Vector<WebMouseEvent>& predicted_events, const Vector<WebMouseEvent>& predicted_events,
const String& canvas_region_id) { const String& canvas_region_id) {
// Fetch the last_mouse_position for creating MouseEvent before
// pointer_event_factory updates it.
FloatPoint last_mouse_position =
pointer_event_factory_.GetLastPointerPosition(
PointerEventFactory::kMouseId, event);
WebInputEventResult result = CreateAndDispatchPointerEvent( WebInputEventResult result = CreateAndDispatchPointerEvent(
target, mouse_event_type, event, coalesced_events, predicted_events); target, mouse_event_type, event, coalesced_events, predicted_events);
result = event_handling_util::MergeEventResult( result = event_handling_util::MergeEventResult(
result, mouse_event_manager_->DispatchMouseEvent( result, mouse_event_manager_->DispatchMouseEvent(
target, mouse_event_type, event, canvas_region_id, nullptr)); target, mouse_event_type, event, canvas_region_id,
&last_mouse_position, nullptr));
return result; return result;
} }
...@@ -639,6 +645,12 @@ WebInputEventResult PointerEventManager::SendMousePointerEvent( ...@@ -639,6 +645,12 @@ WebInputEventResult PointerEventManager::SendMousePointerEvent(
for (const WebMouseEvent& e : predicted_events) for (const WebMouseEvent& e : predicted_events)
pointer_predicted_events.push_back(WebPointerEvent(event_type, e)); pointer_predicted_events.push_back(WebPointerEvent(event_type, e));
// Fetch the last_mouse_position for creating MouseEvent before
// pointer_event_factory updates it.
FloatPoint last_mouse_position =
pointer_event_factory_.GetLastPointerPosition(
PointerEventFactory::kMouseId, mouse_event);
PointerEvent* pointer_event = pointer_event_factory_.Create( PointerEvent* pointer_event = pointer_event_factory_.Create(
web_pointer_event, pointer_coalesced_events, pointer_predicted_events, web_pointer_event, pointer_coalesced_events, pointer_predicted_events,
frame_->GetDocument()->domWindow()); frame_->GetDocument()->domWindow());
...@@ -714,7 +726,7 @@ WebInputEventResult PointerEventManager::SendMousePointerEvent( ...@@ -714,7 +726,7 @@ WebInputEventResult PointerEventManager::SendMousePointerEvent(
result, result,
mouse_event_manager_->DispatchMouseEvent( mouse_event_manager_->DispatchMouseEvent(
mouse_target, MouseEventNameForPointerEventInputType(event_type), mouse_target, MouseEventNameForPointerEventInputType(event_type),
mouse_event, canvas_region_id, nullptr)); mouse_event, canvas_region_id, &last_mouse_position, nullptr));
} }
if (pointer_event->type() == event_type_names::kPointerup || if (pointer_event->type() == event_type_names::kPointerup ||
...@@ -958,4 +970,8 @@ bool PointerEventManager::PrimaryPointerdownCanceled( ...@@ -958,4 +970,8 @@ bool PointerEventManager::PrimaryPointerdownCanceled(
return false; return false;
} }
void PointerEventManager::RemoveLastMousePosition() {
pointer_event_factory_.RemoveLastPosition(PointerEventFactory::kMouseId);
}
} // namespace blink } // namespace blink
...@@ -107,6 +107,8 @@ class CORE_EXPORT PointerEventManager ...@@ -107,6 +107,8 @@ class CORE_EXPORT PointerEventManager
void ProcessPendingPointerCaptureForPointerLock(const WebMouseEvent&); void ProcessPendingPointerCaptureForPointerLock(const WebMouseEvent&);
void RemoveLastMousePosition();
// Sends any outstanding events. For example it notifies TouchEventManager // Sends any outstanding events. For example it notifies TouchEventManager
// to group any changes to touch since last FlushEvents and send the touch // to group any changes to touch since last FlushEvents and send the touch
// event out to js. Since after this function any outstanding event is sent, // event out to js. Since after this function any outstanding event is sent,
......
...@@ -207,4 +207,71 @@ TEST_F(PointerEventManagerTest, PointerEventCoordinates) { ...@@ -207,4 +207,71 @@ TEST_F(PointerEventManagerTest, PointerEventCoordinates) {
ASSERT_EQ(callback->last_movement_y_, 10); ASSERT_EQ(callback->last_movement_y_, 10);
} }
TEST_F(PointerEventManagerTest, PointerEventMovements) {
WebView().Resize(WebSize(400, 400));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Complete(
"<body style='padding: 0px; width: 400px; height: 400px;'>"
"</body>");
PointerEventCoordinateListenerCallback* callback =
PointerEventCoordinateListenerCallback::Create();
GetDocument().body()->addEventListener(event_type_names::kPointermove,
callback);
// Turn on the flag for test.
RuntimeEnabledFeatures::SetMovementXYInBlinkEnabled(true);
WebView().HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
WebFloatPoint(150, 210), WebFloatPoint(100, 50),
10, 10),
std::vector<WebPointerEvent>(), std::vector<WebPointerEvent>()));
// The first pointermove event has movement_x/y 0.
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 50);
ASSERT_EQ(callback->last_movement_x_, 0);
ASSERT_EQ(callback->last_movement_y_, 0);
WebView().HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
WebFloatPoint(150, 200), WebFloatPoint(132, 29),
10, 10),
std::vector<WebPointerEvent>(), std::vector<WebPointerEvent>()));
// pointermove event movement = event.screenX/Y - last_event.screenX/Y.
ASSERT_EQ(callback->last_screen_x_, 132);
ASSERT_EQ(callback->last_screen_y_, 29);
ASSERT_EQ(callback->last_movement_x_, 32);
ASSERT_EQ(callback->last_movement_y_, -21);
WebView().HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
WebFloatPoint(150, 210),
WebFloatPoint(113.8, 32.7), 10, 10),
std::vector<WebPointerEvent>(), std::vector<WebPointerEvent>()));
// fractional screen coordinates result in fractional movement.
ASSERT_FLOAT_EQ(callback->last_screen_x_, 113.8);
ASSERT_FLOAT_EQ(callback->last_screen_y_, 32.7);
// TODO(eirage): These should be float value once mouse_event.idl change.
ASSERT_FLOAT_EQ(callback->last_movement_x_, -18);
ASSERT_FLOAT_EQ(callback->last_movement_y_, 3);
// When flag is off, movementX/Y follows the value in WebPointerProperties.
RuntimeEnabledFeatures::SetMovementXYInBlinkEnabled(false);
WebView().HandleInputEvent(WebCoalescedInputEvent(
CreateTestPointerEvent(WebInputEvent::kPointerMove,
WebPointerProperties::PointerType::kMouse,
WebFloatPoint(150, 210), WebFloatPoint(100, 16.25),
1024, -8765),
std::vector<WebPointerEvent>(), std::vector<WebPointerEvent>()));
ASSERT_EQ(callback->last_screen_x_, 100);
ASSERT_EQ(callback->last_screen_y_, 16.25);
ASSERT_EQ(callback->last_movement_x_, 1024);
ASSERT_EQ(callback->last_movement_y_, -8765);
}
} // namespace blink } // namespace blink
...@@ -805,6 +805,9 @@ ...@@ -805,6 +805,9 @@
name: "MojoJSTest", name: "MojoJSTest",
status: "test", status: "test",
}, },
{
name: "MovementXYInBlink",
},
{ {
name: "NavigatorContentUtils", name: "NavigatorContentUtils",
}, },
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment