Commit 48b81fca authored by Navid Zolghadr's avatar Navid Zolghadr Committed by Commit Bot

Unify the pointer cancel path in PEManager

Before this CL we had two different paths
for creating pointercancels. One for mouse
pointercancels and one for touch/pen cancels.
This LC refactor the code for these two paths.

Bug: 778351
Change-Id: Ie498c5afb2e3aee7938e51db33ea8de7cb7323dc
Reviewed-on: https://chromium-review.googlesource.com/740144Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarMustaq Ahmed <mustaq@chromium.org>
Commit-Queue: Navid Zolghadr <nzolghadr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#513238}
parent fdf2d5ef
...@@ -1565,6 +1565,7 @@ jumbo_source_set("unit_tests") { ...@@ -1565,6 +1565,7 @@ jumbo_source_set("unit_tests") {
"imagebitmap/ImageBitmapTest.cpp", "imagebitmap/ImageBitmapTest.cpp",
"input/EventHandlerTest.cpp", "input/EventHandlerTest.cpp",
"input/ImeOnFocusTest.cpp", "input/ImeOnFocusTest.cpp",
"input/PointerEventManagerTest.cpp",
"input/ScrollBoundaryBehaviorTest.cpp", "input/ScrollBoundaryBehaviorTest.cpp",
"input/TouchActionTest.cpp", "input/TouchActionTest.cpp",
"input/TouchEventManagerTest.cpp", "input/TouchEventManagerTest.cpp",
......
...@@ -373,19 +373,8 @@ PointerEvent* PointerEventFactory::Create( ...@@ -373,19 +373,8 @@ PointerEvent* PointerEventFactory::Create(
event_platform_time_stamp); event_platform_time_stamp);
} }
PointerEvent* PointerEventFactory::CreatePointerCancelEvent(
const WebPointerEvent& event) {
DCHECK_EQ(event.GetType(), WebInputEvent::Type::kPointerCancel);
int pointer_id = GetPointerEventId(event);
return CreatePointerCancelEvent(
pointer_id, event.pointer_type,
TimeTicks::FromSeconds(event.TimeStampSeconds()));
}
PointerEvent* PointerEventFactory::CreatePointerCancelEvent( PointerEvent* PointerEventFactory::CreatePointerCancelEvent(
const int pointer_id, const int pointer_id,
const WebPointerProperties::PointerType pointer_type,
TimeTicks platfrom_time_stamp) { TimeTicks platfrom_time_stamp) {
DCHECK(pointer_id_mapping_.Contains(pointer_id)); DCHECK(pointer_id_mapping_.Contains(pointer_id));
pointer_id_mapping_.Set( pointer_id_mapping_.Set(
...@@ -396,8 +385,8 @@ PointerEvent* PointerEventFactory::CreatePointerCancelEvent( ...@@ -396,8 +385,8 @@ PointerEvent* PointerEventFactory::CreatePointerCancelEvent(
PointerEventInit pointer_event_init; PointerEventInit pointer_event_init;
pointer_event_init.setPointerId(pointer_id); pointer_event_init.setPointerId(pointer_id);
pointer_event_init.setPointerType( pointer_event_init.setPointerType(PointerTypeNameForWebPointPointerType(
PointerTypeNameForWebPointPointerType(pointer_type)); pointer_id_mapping_.at(pointer_id).incoming_id.GetPointerType()));
pointer_event_init.setIsPrimary(IsPrimary(pointer_id)); pointer_event_init.setIsPrimary(IsPrimary(pointer_id));
SetEventSpecificFields(pointer_event_init, EventTypeNames::pointercancel); SetEventSpecificFields(pointer_event_init, EventTypeNames::pointercancel);
......
...@@ -42,11 +42,8 @@ class CORE_EXPORT PointerEventFactory { ...@@ -42,11 +42,8 @@ class CORE_EXPORT PointerEventFactory {
LocalFrame*, LocalFrame*,
DOMWindow*); DOMWindow*);
PointerEvent* CreatePointerCancelEvent(const WebPointerEvent&);
PointerEvent* CreatePointerCancelEvent( PointerEvent* CreatePointerCancelEvent(
const int pointer_id, const int pointer_id,
const WebPointerProperties::PointerType,
TimeTicks platfrom_time_stamp); TimeTicks platfrom_time_stamp);
// For creating capture events (i.e got/lostpointercapture) // For creating capture events (i.e got/lostpointercapture)
......
...@@ -35,10 +35,10 @@ const char* PointerTypeNameForWebPointPointerType( ...@@ -35,10 +35,10 @@ const char* PointerTypeNameForWebPointPointerType(
class PointerEventFactoryTest : public ::testing::Test { class PointerEventFactoryTest : public ::testing::Test {
protected: protected:
void SetUp() override; void SetUp() override;
PointerEvent* CreateAndCheckTouchCancel(WebPointerProperties::PointerType, PointerEvent* CreateAndCheckPointerCancel(WebPointerProperties::PointerType,
int raw_id, int raw_id,
int unique_id, int unique_id,
bool is_primary); bool is_primary);
PointerEvent* CreateAndCheckTouchEvent( PointerEvent* CreateAndCheckTouchEvent(
WebPointerProperties::PointerType, WebPointerProperties::PointerType,
int raw_id, int raw_id,
...@@ -53,12 +53,6 @@ class PointerEventFactoryTest : public ::testing::Test { ...@@ -53,12 +53,6 @@ class PointerEventFactoryTest : public ::testing::Test {
bool is_primary, bool is_primary,
WebInputEvent::Modifiers = WebInputEvent::kNoModifiers, WebInputEvent::Modifiers = WebInputEvent::kNoModifiers,
size_t coalesced_event_count = 0); size_t coalesced_event_count = 0);
PointerEvent* CreateAndCheckPointerCancelEvent(
WebPointerProperties::PointerType,
int raw_id,
int unique_id,
bool is_primary,
WebInputEvent::Modifiers = WebInputEvent::kNoModifiers);
void CreateAndCheckPointerTransitionEvent(PointerEvent*, const AtomicString&); void CreateAndCheckPointerTransitionEvent(PointerEvent*, const AtomicString&);
void CheckScrollCapablePointers(const std::set<int>& expected); void CheckScrollCapablePointers(const std::set<int>& expected);
...@@ -109,19 +103,21 @@ PointerEventFactoryTest::WebMouseEventBuilder::WebMouseEventBuilder( ...@@ -109,19 +103,21 @@ PointerEventFactoryTest::WebMouseEventBuilder::WebMouseEventBuilder(
time_stamp_seconds_ = platform_time_stamp; time_stamp_seconds_ = platform_time_stamp;
} }
PointerEvent* PointerEventFactoryTest::CreateAndCheckTouchCancel( PointerEvent* PointerEventFactoryTest::CreateAndCheckPointerCancel(
WebPointerProperties::PointerType pointer_type, WebPointerProperties::PointerType pointer_type,
int raw_id, int raw_id,
int unique_id, int unique_id,
bool is_primary) { bool is_primary) {
TimeTicks now = TimeTicks::Now();
PointerEvent* pointer_event = pointer_event_factory_.CreatePointerCancelEvent( PointerEvent* pointer_event = pointer_event_factory_.CreatePointerCancelEvent(
unique_id, pointer_type, now); unique_id, TimeTicks::FromSeconds(WebInputEvent::kTimeStampForTesting));
EXPECT_EQ("pointercancel", pointer_event->type());
EXPECT_EQ(unique_id, pointer_event->pointerId()); EXPECT_EQ(unique_id, pointer_event->pointerId());
EXPECT_EQ(is_primary, pointer_event->isPrimary()); EXPECT_EQ(is_primary, pointer_event->isPrimary());
EXPECT_EQ(PointerTypeNameForWebPointPointerType(pointer_type), EXPECT_EQ(PointerTypeNameForWebPointPointerType(pointer_type),
pointer_event->pointerType()); pointer_event->pointerType());
EXPECT_EQ(now, pointer_event->PlatformTimeStamp()); EXPECT_EQ(TimeTicks::FromSeconds(WebInputEvent::kTimeStampForTesting),
pointer_event->PlatformTimeStamp());
return pointer_event; return pointer_event;
} }
...@@ -181,28 +177,6 @@ PointerEvent* PointerEventFactoryTest::CreateAndCheckTouchEvent( ...@@ -181,28 +177,6 @@ PointerEvent* PointerEventFactoryTest::CreateAndCheckTouchEvent(
return pointer_event; return pointer_event;
} }
PointerEvent* PointerEventFactoryTest::CreateAndCheckPointerCancelEvent(
WebPointerProperties::PointerType pointer_type,
int raw_id,
int unique_id,
bool is_primary,
WebInputEvent::Modifiers modifiers) {
PointerEvent* pointer_event = pointer_event_factory_.CreatePointerCancelEvent(
WebPointerEvent(WebInputEvent::Type::kPointerCancel,
PointerEventFactoryTest::WebMouseEventBuilder(
pointer_type, raw_id, modifiers,
WebInputEvent::kTimeStampForTesting)));
EXPECT_EQ("pointercancel", pointer_event->type());
EXPECT_EQ(unique_id, pointer_event->pointerId());
EXPECT_EQ(is_primary, pointer_event->isPrimary());
EXPECT_EQ(TimeTicks::FromSeconds(WebInputEvent::kTimeStampForTesting),
pointer_event->PlatformTimeStamp());
const char* expected_pointer_type =
PointerTypeNameForWebPointPointerType(pointer_type);
EXPECT_EQ(expected_pointer_type, pointer_event->pointerType());
return pointer_event;
}
PointerEvent* PointerEventFactoryTest::CreateAndCheckMouseEvent( PointerEvent* PointerEventFactoryTest::CreateAndCheckMouseEvent(
WebPointerProperties::PointerType pointer_type, WebPointerProperties::PointerType pointer_type,
int raw_id, int raw_id,
...@@ -282,8 +256,8 @@ TEST_F(PointerEventFactoryTest, MousePointer) { ...@@ -282,8 +256,8 @@ TEST_F(PointerEventFactoryTest, MousePointer) {
EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_)); EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
EXPECT_TRUE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_)); EXPECT_TRUE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
CreateAndCheckPointerCancelEvent(WebPointerProperties::PointerType::kMouse, 0, CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kMouse, 0,
expected_mouse_id_, true); expected_mouse_id_, true);
EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_)); EXPECT_TRUE(pointer_event_factory_.IsActive(expected_mouse_id_));
EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_)); EXPECT_FALSE(pointer_event_factory_.IsActiveButtonsState(expected_mouse_id_));
...@@ -391,8 +365,8 @@ TEST_F(PointerEventFactoryTest, TouchAndDrag) { ...@@ -391,8 +365,8 @@ TEST_F(PointerEventFactoryTest, TouchAndDrag) {
CreateAndCheckTouchEvent(WebPointerProperties::PointerType::kTouch, 0, CreateAndCheckTouchEvent(WebPointerProperties::PointerType::kTouch, 0,
mapped_id_start_ + 1, true); mapped_id_start_ + 1, true);
CreateAndCheckTouchCancel(WebPointerProperties::PointerType::kTouch, 0, CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kTouch, 0,
mapped_id_start_ + 1, true); mapped_id_start_ + 1, true);
EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_ + 1)); EXPECT_TRUE(pointer_event_factory_.IsActive(mapped_id_start_ + 1));
EXPECT_FALSE( EXPECT_FALSE(
...@@ -507,8 +481,8 @@ TEST_F(PointerEventFactoryTest, PenAsTouchAndMouseEvent) { ...@@ -507,8 +481,8 @@ TEST_F(PointerEventFactoryTest, PenAsTouchAndMouseEvent) {
mapped_id_start_ + 3, false); mapped_id_start_ + 3, false);
CreateAndCheckMouseEvent(WebPointerProperties::PointerType::kPen, 0, CreateAndCheckMouseEvent(WebPointerProperties::PointerType::kPen, 0,
mapped_id_start_ + 3, false); mapped_id_start_ + 3, false);
CreateAndCheckTouchCancel(WebPointerProperties::PointerType::kPen, 0, CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kPen, 0,
mapped_id_start_ + 3, false); mapped_id_start_ + 3, false);
pointer_event_factory_.Clear(); pointer_event_factory_.Clear();
...@@ -520,10 +494,10 @@ TEST_F(PointerEventFactoryTest, PenAsTouchAndMouseEvent) { ...@@ -520,10 +494,10 @@ TEST_F(PointerEventFactoryTest, PenAsTouchAndMouseEvent) {
mapped_id_start_, true); mapped_id_start_, true);
CreateAndCheckMouseEvent(WebPointerProperties::PointerType::kPen, 0, CreateAndCheckMouseEvent(WebPointerProperties::PointerType::kPen, 0,
mapped_id_start_ + 1, false); mapped_id_start_ + 1, false);
CreateAndCheckTouchCancel(WebPointerProperties::PointerType::kPen, 1, CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kPen, 1,
mapped_id_start_, true); mapped_id_start_, true);
CreateAndCheckTouchCancel(WebPointerProperties::PointerType::kPen, 0, CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kPen, 0,
mapped_id_start_ + 1, false); mapped_id_start_ + 1, false);
} }
TEST_F(PointerEventFactoryTest, OutOfRange) { TEST_F(PointerEventFactoryTest, OutOfRange) {
...@@ -539,8 +513,8 @@ TEST_F(PointerEventFactoryTest, OutOfRange) { ...@@ -539,8 +513,8 @@ TEST_F(PointerEventFactoryTest, OutOfRange) {
mapped_id_start_ + 3, false); mapped_id_start_ + 3, false);
CreateAndCheckMouseEvent(WebPointerProperties::PointerType::kUnknown, 2, CreateAndCheckMouseEvent(WebPointerProperties::PointerType::kUnknown, 2,
mapped_id_start_ + 2, false); mapped_id_start_ + 2, false);
CreateAndCheckTouchCancel(WebPointerProperties::PointerType::kUnknown, 3, CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kUnknown, 3,
mapped_id_start_ + 3, false); mapped_id_start_ + 3, false);
pointer_event_factory_.Remove(pointer_event1->pointerId()); pointer_event_factory_.Remove(pointer_event1->pointerId());
...@@ -560,8 +534,8 @@ TEST_F(PointerEventFactoryTest, OutOfRange) { ...@@ -560,8 +534,8 @@ TEST_F(PointerEventFactoryTest, OutOfRange) {
CreateAndCheckTouchEvent(WebPointerProperties::PointerType::kMouse, i, CreateAndCheckTouchEvent(WebPointerProperties::PointerType::kMouse, i,
expected_mouse_id_, true); expected_mouse_id_, true);
} }
CreateAndCheckTouchCancel(WebPointerProperties::PointerType::kMouse, 0, CreateAndCheckPointerCancel(WebPointerProperties::PointerType::kMouse, 0,
expected_mouse_id_, true); expected_mouse_id_, true);
} }
TEST_F(PointerEventFactoryTest, CoalescedEvents) { TEST_F(PointerEventFactoryTest, CoalescedEvents) {
......
...@@ -550,9 +550,8 @@ EventHandler::OptionalCursor EventHandler::SelectAutoCursor( ...@@ -550,9 +550,8 @@ EventHandler::OptionalCursor EventHandler::SelectAutoCursor(
} }
WebInputEventResult EventHandler::HandlePointerEvent( WebInputEventResult EventHandler::HandlePointerEvent(
const WebPointerEvent& web_pointer_event, const WebPointerEvent& web_pointer_event) {
Node* target) { return pointer_event_manager_->HandlePointerEvent(web_pointer_event);
return pointer_event_manager_->HandlePointerEvent(web_pointer_event, target);
} }
WebInputEventResult EventHandler::HandleMousePressEvent( WebInputEventResult EventHandler::HandleMousePressEvent(
......
...@@ -148,7 +148,7 @@ class CORE_EXPORT EventHandler final ...@@ -148,7 +148,7 @@ class CORE_EXPORT EventHandler final
const Vector<WebMouseEvent>& coalesced_events); const Vector<WebMouseEvent>& coalesced_events);
void HandleMouseLeaveEvent(const WebMouseEvent&); void HandleMouseLeaveEvent(const WebMouseEvent&);
WebInputEventResult HandlePointerEvent(const WebPointerEvent&, Node* target); WebInputEventResult HandlePointerEvent(const WebPointerEvent&);
WebInputEventResult HandleMousePressEvent(const WebMouseEvent&); WebInputEventResult HandleMousePressEvent(const WebMouseEvent&);
WebInputEventResult HandleMouseReleaseEvent(const WebMouseEvent&); WebInputEventResult HandleMouseReleaseEvent(const WebMouseEvent&);
......
...@@ -913,8 +913,7 @@ bool MouseEventManager::HandleDrag(const MouseEventWithHitTestResults& event, ...@@ -913,8 +913,7 @@ bool MouseEventManager::HandleDrag(const MouseEventWithHitTestResults& event,
// corresponding pointer. // corresponding pointer.
if (initiator == DragInitiator::kMouse) { if (initiator == DragInitiator::kMouse) {
frame_->GetEventHandler().HandlePointerEvent( frame_->GetEventHandler().HandlePointerEvent(
WebPointerEvent(WebInputEvent::Type::kPointerCancel, event.Event()), WebPointerEvent(WebInputEvent::Type::kPointerCancel, event.Event()));
event.InnerNode());
} }
// TODO(crbug.com/708278): If the drag starts with touch the touch cancel // TODO(crbug.com/708278): If the drag starts with touch the touch cancel
// should trigger the release of pointer capture. // should trigger the release of pointer capture.
......
...@@ -80,7 +80,7 @@ void PointerEventManager::Clear() { ...@@ -80,7 +80,7 @@ void PointerEventManager::Clear() {
for (auto& entry : prevent_mouse_event_for_pointer_type_) for (auto& entry : prevent_mouse_event_for_pointer_type_)
entry = false; entry = false;
touch_event_manager_->Clear(); touch_event_manager_->Clear();
in_canceled_state_for_pointer_type_touch_ = false; scroll_capable_pointers_canceled_ = false;
pointer_event_factory_.Clear(); pointer_event_factory_.Clear();
touch_ids_for_canceled_pointerdowns_.clear(); touch_ids_for_canceled_pointerdowns_.clear();
node_under_pointer_.clear(); node_under_pointer_.clear();
...@@ -257,53 +257,81 @@ void PointerEventManager::SetNodeUnderPointer(PointerEvent* pointer_event, ...@@ -257,53 +257,81 @@ void PointerEventManager::SetNodeUnderPointer(PointerEvent* pointer_event,
} }
} }
void PointerEventManager::BlockTouchPointers(TimeTicks platform_time_stamp) { void PointerEventManager::DispatchPointerCancelEvents(
if (in_canceled_state_for_pointer_type_touch_) const WebPointerEvent& web_pointer_event) {
return; DCHECK(web_pointer_event.GetType() == WebInputEvent::Type::kPointerCancel);
in_canceled_state_for_pointer_type_touch_ = true;
Vector<int> touch_pointer_ids =
pointer_event_factory_.GetPointerIdsOfScrollCapablePointers();
for (int pointer_id : touch_pointer_ids) { HeapVector<Member<PointerEvent>> canceled_pointer_events;
PointerEvent* pointer_event = if (web_pointer_event.pointer_type ==
WebPointerProperties::PointerType::kMouse) {
canceled_pointer_events.push_back(
pointer_event_factory_.CreatePointerCancelEvent( pointer_event_factory_.CreatePointerCancelEvent(
pointer_id, WebPointerProperties::PointerType::kTouch, PointerEventFactory::kMouseId,
platform_time_stamp); TimeTicks::FromSeconds(web_pointer_event.TimeStampSeconds())));
} else {
// TODO(nzolghadr): Maybe canceling all the scroll capable pointers is not
// the best strategy here. See the github issue for more details:
// https://github.com/w3c/pointerevents/issues/226
// Cancel all scroll capable pointers if the pointer is not mouse.
if (!scroll_capable_pointers_canceled_) {
Vector<int> scroll_capable_pointer_ids =
pointer_event_factory_.GetPointerIdsOfScrollCapablePointers();
for (int pointer_id : scroll_capable_pointer_ids) {
canceled_pointer_events.push_back(
pointer_event_factory_.CreatePointerCancelEvent(
pointer_id,
TimeTicks::FromSeconds(web_pointer_event.TimeStampSeconds())));
}
DCHECK(node_under_pointer_.Contains(pointer_id)); scroll_capable_pointers_canceled_ = true;
EventTarget* target = node_under_pointer_.at(pointer_id).target; }
}
ProcessCaptureAndPositionOfPointerEvent(pointer_event, target); for (auto pointer_event : canceled_pointer_events) {
// If we are sending a pointercancel we have sent the pointerevent to some
// target before.
DCHECK(node_under_pointer_.Contains(pointer_event->pointerId()));
EventTarget* target =
node_under_pointer_.at(pointer_event->pointerId()).target;
// TODO(nzolghadr): This event follows implicit TE capture. The actual
// target would depend on PE capturing. Perhaps need to split TE/PE event
// path upstream? crbug.com/579553.
DispatchPointerEvent( DispatchPointerEvent(
GetEffectiveTargetForPointerEvent(target, pointer_event->pointerId()), GetEffectiveTargetForPointerEvent(target, pointer_event->pointerId()),
pointer_event); pointer_event);
ReleasePointerCapture(pointer_event->pointerId()); ReleasePointerCapture(pointer_event->pointerId());
// Sending the leave/out events and lostpointercapture // Send the leave/out events and lostpointercapture if needed.
// because the next touch event will have a different id. So delayed // Note that for mouse due to the web compat we still don't send the
// sending of lostpointercapture won't work here. // boundary events and for now only send lostpointercapture if needed.
ProcessCaptureAndPositionOfPointerEvent(pointer_event, nullptr); // Sending boundary events and possibly updating hover for mouse
// in this case may cause some of the existing pages to break.
if (web_pointer_event.pointer_type ==
WebPointerProperties::PointerType::kMouse) {
ProcessPendingPointerCapture(pointer_event);
} else {
ProcessCaptureAndPositionOfPointerEvent(pointer_event, nullptr);
}
RemovePointer(pointer_event); RemovePointer(pointer_event);
} }
} }
void PointerEventManager::UnblockTouchPointers() { void PointerEventManager::UnblockTouchPointers() {
in_canceled_state_for_pointer_type_touch_ = false; scroll_capable_pointers_canceled_ = false;
} }
WebInputEventResult PointerEventManager::HandleTouchEvents( WebInputEventResult PointerEventManager::HandleTouchEvents(
const WebTouchEvent& event, const WebTouchEvent& event,
const Vector<WebTouchEvent>& coalesced_events) { const Vector<WebTouchEvent>& coalesced_events) {
if (event.GetType() == WebInputEvent::kTouchScrollStarted) { if (event.GetType() == WebInputEvent::kTouchScrollStarted) {
BlockTouchPointers(TimeTicks::FromSeconds(event.TimeStampSeconds())); WebPointerEvent web_pointer_event_cancel;
return WebInputEventResult::kHandledSystem; web_pointer_event_cancel.SetType(WebInputEvent::Type::kPointerCancel);
web_pointer_event_cancel.SetTimeStampSeconds(event.TimeStampSeconds());
web_pointer_event_cancel.pointer_type =
WebPointerProperties::PointerType::kTouch;
return HandlePointerEvent(web_pointer_event_cancel);
} }
bool new_touch_sequence = true; bool new_touch_sequence = true;
...@@ -333,7 +361,7 @@ WebInputEventResult PointerEventManager::HandleTouchEvents( ...@@ -333,7 +361,7 @@ WebInputEventResult PointerEventManager::HandleTouchEvents(
// associated with so just pick the first finger. // associated with so just pick the first finger.
std::unique_ptr<UserGestureIndicator> holder; std::unique_ptr<UserGestureIndicator> holder;
if (event.GetType() == WebInputEvent::kTouchEnd && if (event.GetType() == WebInputEvent::kTouchEnd &&
!in_canceled_state_for_pointer_type_touch_ && event.touches_length && !scroll_capable_pointers_canceled_ && event.touches_length &&
first_pointer_event_target.target_frame) { first_pointer_event_target.target_frame) {
holder = holder =
Frame::NotifyUserActivation(first_pointer_event_target.target_frame); Frame::NotifyUserActivation(first_pointer_event_target.target_frame);
...@@ -432,7 +460,7 @@ void PointerEventManager::DispatchTouchPointerEvent( ...@@ -432,7 +460,7 @@ void PointerEventManager::DispatchTouchPointerEvent(
// required. // required.
// Do not send pointer events for stationary touches or null targetFrame // Do not send pointer events for stationary touches or null targetFrame
if (pointer_event_target.target_node && pointer_event_target.target_frame && if (pointer_event_target.target_node && pointer_event_target.target_frame &&
!in_canceled_state_for_pointer_type_touch_) { !scroll_capable_pointers_canceled_) {
PointerEvent* pointer_event = pointer_event_factory_.Create( PointerEvent* pointer_event = pointer_event_factory_.Create(
touch_point, coalesced_events, touch_point, coalesced_events,
static_cast<WebInputEvent::Modifiers>(modifiers), static_cast<WebInputEvent::Modifiers>(modifiers),
...@@ -461,7 +489,7 @@ void PointerEventManager::DispatchTouchPointerEvent( ...@@ -461,7 +489,7 @@ void PointerEventManager::DispatchTouchPointerEvent(
WebInputEventResult PointerEventManager::SendTouchPointerEvent( WebInputEventResult PointerEventManager::SendTouchPointerEvent(
EventTarget* target, EventTarget* target,
PointerEvent* pointer_event) { PointerEvent* pointer_event) {
if (in_canceled_state_for_pointer_type_touch_) if (scroll_capable_pointers_canceled_)
return WebInputEventResult::kNotHandled; return WebInputEventResult::kNotHandled;
ProcessCaptureAndPositionOfPointerEvent(pointer_event, target); ProcessCaptureAndPositionOfPointerEvent(pointer_event, target);
...@@ -489,29 +517,16 @@ WebInputEventResult PointerEventManager::SendTouchPointerEvent( ...@@ -489,29 +517,16 @@ WebInputEventResult PointerEventManager::SendTouchPointerEvent(
} }
WebInputEventResult PointerEventManager::HandlePointerEvent( WebInputEventResult PointerEventManager::HandlePointerEvent(
const WebPointerEvent& web_pointer_event, const WebPointerEvent& web_pointer_event) {
Node* target) {
// TODO(crbug.com/625841): This function only handles pointercancel for now. // TODO(crbug.com/625841): This function only handles pointercancel for now.
// But we should extend it to handle any pointerevents. // But we should extend it to handle any pointerevents.
DCHECK(web_pointer_event.GetType() == WebInputEvent::Type::kPointerCancel); DCHECK(web_pointer_event.GetType() == WebInputEvent::Type::kPointerCancel);
PointerEvent* pointer_event =
pointer_event_factory_.CreatePointerCancelEvent(web_pointer_event);
EventTarget* effective_target =
GetEffectiveTargetForPointerEvent(target, pointer_event->pointerId());
WebInputEventResult result =
DispatchPointerEvent(effective_target, pointer_event);
ReleasePointerCapture(pointer_event->pointerId()); if (web_pointer_event.GetType() == WebInputEvent::Type::kPointerCancel) {
DispatchPointerCancelEvents(web_pointer_event);
// TODO(nzolghadr): Instead of |ProcessPendingPointerCapture| maybe we }
// should have used ProcessCaptureAndPositionOfPointerEvent but that might
// be sending boundary events however we probably not want that all the
// time.
ProcessPendingPointerCapture(pointer_event);
RemovePointer(pointer_event); return WebInputEventResult::kHandledSystem;
return result;
} }
WebInputEventResult PointerEventManager::SendMousePointerEvent( WebInputEventResult PointerEventManager::SendMousePointerEvent(
......
...@@ -34,7 +34,7 @@ class CORE_EXPORT PointerEventManager ...@@ -34,7 +34,7 @@ class CORE_EXPORT PointerEventManager
// cause firing DOM pointerevents, mouseevent, and touch events accordingly. // cause firing DOM pointerevents, mouseevent, and touch events accordingly.
// TODO(crbug.com/625841): We need to get all event handling path to go // TODO(crbug.com/625841): We need to get all event handling path to go
// through this function. // through this function.
WebInputEventResult HandlePointerEvent(const WebPointerEvent&, Node* target); WebInputEventResult HandlePointerEvent(const WebPointerEvent&);
// Sends the mouse pointer events and the boundary events // Sends the mouse pointer events and the boundary events
// that it may cause. It also sends the compat mouse events // that it may cause. It also sends the compat mouse events
...@@ -137,11 +137,10 @@ class CORE_EXPORT PointerEventManager ...@@ -137,11 +137,10 @@ class CORE_EXPORT PointerEventManager
Member<PointerEvent> pointer_event_; Member<PointerEvent> pointer_event_;
}; };
// Inhibits firing of touch-type PointerEvents until unblocked by // Sends pointercancels for existing PointerEvents. For example when browser
// unblockTouchPointers(). Also sends pointercancels for existing touch-type // starts dragging with mouse or when we start scrolling with scroll capable
// PointerEvents. See: // pointers pointercancel events should be dispatched.
// www.w3.org/TR/pointerevents/#declaring-candidate-regions-for-default-touch-behaviors void DispatchPointerCancelEvents(const WebPointerEvent&);
void BlockTouchPointers(TimeTicks platform_time_stamp);
// Enables firing of touch-type PointerEvents after they were inhibited by // Enables firing of touch-type PointerEvents after they were inhibited by
// blockTouchPointers(). // blockTouchPointers().
...@@ -212,9 +211,9 @@ class CORE_EXPORT PointerEventManager ...@@ -212,9 +211,9 @@ class CORE_EXPORT PointerEventManager
bool prevent_mouse_event_for_pointer_type_ bool prevent_mouse_event_for_pointer_type_
[static_cast<size_t>(WebPointerProperties::PointerType::kLastEntry) + 1]; [static_cast<size_t>(WebPointerProperties::PointerType::kLastEntry) + 1];
// Set upon TouchScrollStarted when sending a pointercancel, prevents PE // Set upon scrolling starts when sending a pointercancel, prevents PE
// dispatches for touches until all touch-points become inactive. // dispatches for scroll capable pointers until all of them become inactive.
bool in_canceled_state_for_pointer_type_touch_; bool scroll_capable_pointers_canceled_;
Deque<uint32_t> touch_ids_for_canceled_pointerdowns_; Deque<uint32_t> touch_ids_for_canceled_pointerdowns_;
......
// Copyright 2017 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.
#include "core/dom/Document.h"
#include "core/dom/events/EventListener.h"
#include "core/html/HTMLElement.h"
#include "core/input/EventHandler.h"
#include "core/input/PointerEventManager.h"
#include "core/testing/sim/SimRequest.h"
#include "core/testing/sim/SimTest.h"
namespace blink {
namespace {
class CheckPointerEventListenerCallback final : public EventListener {
public:
static CheckPointerEventListenerCallback* Create() {
return new CheckPointerEventListenerCallback();
}
bool operator==(const EventListener& other) const override {
return this == &other;
}
void handleEvent(ExecutionContext*, Event* event) override {
const String pointer_type = ((PointerEvent*)event)->pointerType();
if (pointer_type == "mouse")
mouse_event_received_count_++;
else if (pointer_type == "touch")
touch_event_received_count_++;
else if (pointer_type == "pen")
pen_event_received_count_++;
}
int mouseEventCount() const { return mouse_event_received_count_; }
int touchEventCount() const { return touch_event_received_count_; }
int penEventCount() const { return pen_event_received_count_; }
private:
CheckPointerEventListenerCallback()
: EventListener(EventListener::kCPPEventListenerType) {}
int mouse_event_received_count_ = 0;
int touch_event_received_count_ = 0;
int pen_event_received_count_ = 0;
};
} // namespace
class PointerEventManagerTest : public SimTest {
protected:
EventHandler& EventHandler() {
return GetDocument().GetFrame()->GetEventHandler();
}
};
TEST_F(PointerEventManagerTest, PointerCancelsOfAllTypes) {
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;'>"
"<div draggable='true' style='width: 150px; height: 150px;'></div>"
"</body>");
CheckPointerEventListenerCallback* callback =
CheckPointerEventListenerCallback::Create();
GetDocument().body()->addEventListener(EventTypeNames::pointercancel,
callback);
WebTouchEvent event;
event.SetFrameScale(1);
WebTouchPoint point(
WebPointerProperties(1, WebPointerProperties::PointerType::kTouch,
WebPointerProperties::Button::kLeft,
WebFloatPoint(100, 100), WebFloatPoint(100, 100)));
point.state = WebTouchPoint::State::kStatePressed;
event.touches[event.touches_length++] = point;
event.SetType(WebInputEvent::kTouchStart);
EventHandler().HandleTouchEvent(event, Vector<WebTouchEvent>());
point.pointer_type = WebPointerProperties::PointerType::kPen;
event.touches[0] = point;
event.SetType(WebInputEvent::kTouchStart);
EventHandler().HandleTouchEvent(event, Vector<WebTouchEvent>());
WebMouseEvent mouse_down_event(
WebInputEvent::kMouseDown, WebFloatPoint(100, 100),
WebFloatPoint(100, 100), WebPointerProperties::Button::kLeft, 0, 0, 0);
mouse_down_event.SetFrameScale(1);
EventHandler().HandleMousePressEvent(mouse_down_event);
ASSERT_EQ(callback->mouseEventCount(), 0);
ASSERT_EQ(callback->touchEventCount(), 0);
ASSERT_EQ(callback->penEventCount(), 0);
point.pointer_type = WebPointerProperties::PointerType::kPen;
event.touches[0] = point;
event.SetType(WebInputEvent::kTouchScrollStarted);
EventHandler().HandleTouchEvent(event, Vector<WebTouchEvent>());
ASSERT_EQ(callback->mouseEventCount(), 0);
ASSERT_EQ(callback->touchEventCount(), 1);
ASSERT_EQ(callback->penEventCount(), 1);
point.pointer_type = WebPointerProperties::PointerType::kTouch;
event.touches[0] = point;
event.SetType(WebInputEvent::kTouchScrollStarted);
EventHandler().HandleTouchEvent(event, Vector<WebTouchEvent>());
ASSERT_EQ(callback->mouseEventCount(), 0);
ASSERT_EQ(callback->touchEventCount(), 1);
ASSERT_EQ(callback->penEventCount(), 1);
WebMouseEvent mouse_move_event(
WebInputEvent::kMouseMove, WebFloatPoint(200, 200),
WebFloatPoint(200, 200), WebPointerProperties::Button::kLeft, 0, 0, 0);
mouse_move_event.SetFrameScale(1);
EventHandler().HandleMouseMoveEvent(mouse_move_event,
Vector<WebMouseEvent>());
ASSERT_EQ(callback->mouseEventCount(), 1);
ASSERT_EQ(callback->touchEventCount(), 1);
ASSERT_EQ(callback->penEventCount(), 1);
}
} // namespace blink
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