From 90de24e784383b4c2c1311f9ae1cd45938fece36 Mon Sep 17 00:00:00 2001 From: Sahir Vellani Date: Wed, 15 Mar 2023 19:15:40 +0000 Subject: [PATCH] Add deviceId to pointer event in blink. This CL is the first in a series that will introduce deviceId as an attribute of pointer event. This one implements the attribute in blink and the pointer event api. Specification/Explainer: https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/PointerEventDeviceId/explainer.md Design doc: https://docs.google.com/document/d/1o53mMNRcDnEnt55ftBe8pIPCS0pMlS0CVihs_I8g_UI/edit#heading=h.mx5ptksqe96w Prototype: https://chromium-review.googlesource.com/c/chromium/src/+/4225372 Change-Id: I4a8e506f2cf1602e4b521491dfed49ff036efbbf Bug: 1420685 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4298332 Reviewed-by: Chris Bookholt Reviewed-by: Robert Flack Commit-Queue: Sahir Vellani Reviewed-by: Olga Gerchikov Reviewed-by: Mustaq Ahmed Reviewed-by: Philip Rogers Cr-Commit-Position: refs/heads/main@{#1117672} --- .../web_coalesced_input_event_mojom_traits.cc | 3 +- .../common/input/web_pointer_properties.h | 3 ++ .../public/mojom/input/input_handler.mojom | 1 + .../renderer/core/events/pointer_event.cc | 3 ++ .../renderer/core/events/pointer_event.h | 4 ++ .../renderer/core/events/pointer_event.idl | 1 + .../core/events/pointer_event_factory.cc | 11 +++- .../core/events/pointer_event_factory.h | 4 +- .../core/events/pointer_event_factory_test.cc | 3 +- .../core/events/pointer_event_init.idl | 1 + .../core/input/pointer_event_manager.cc | 9 ++-- .../platform/runtime_enabled_features.json5 | 4 ++ third_party/blink/web_tests/VirtualTestSuites | 9 ++++ .../get-device-id-from-pointer-event.html | 50 +++++++++++++++++ ...has-device-id-from-pointer-event-init.html | 54 +++++++++++++++++++ .../events/pointerevents/device-id/README.txt | 2 + .../global-interface-listing-expected.txt | 1 + 17 files changed, 156 insertions(+), 7 deletions(-) create mode 100644 third_party/blink/web_tests/fast/events/pointerevents/device-id/get-device-id-from-pointer-event.html create mode 100644 third_party/blink/web_tests/fast/events/pointerevents/device-id/pointer-event-has-device-id-from-pointer-event-init.html create mode 100644 third_party/blink/web_tests/virtual/disable-device-id-pointer-event/fast/events/pointerevents/device-id/README.txt diff --git a/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc b/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc index 053d68bae28e2..cae8aad3ffa91 100644 --- a/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc +++ b/third_party/blink/common/input/web_coalesced_input_event_mojom_traits.cc @@ -36,7 +36,7 @@ blink::mojom::PointerDataPtr PointerDataFromPointerProperties( pointer.tangential_pressure, pointer.twist, pointer.button, pointer.pointer_type, pointer.movement_x, pointer.movement_y, pointer.is_raw_movement_event, pointer.PositionInWidget(), - pointer.PositionInScreen(), std::move(mouse_data)); + pointer.PositionInScreen(), std::move(mouse_data), pointer.device_id); } void PointerPropertiesFromPointerData( @@ -54,6 +54,7 @@ void PointerPropertiesFromPointerData( pointer_properties->movement_y = pointer_data->movement_y; pointer_properties->is_raw_movement_event = pointer_data->is_raw_movement_event; + pointer_properties->device_id = pointer_data->device_id; } void TouchPointPropertiesFromPointerData( diff --git a/third_party/blink/public/common/input/web_pointer_properties.h b/third_party/blink/public/common/input/web_pointer_properties.h index 661c05e5663de..33940cc682fc0 100644 --- a/third_party/blink/public/common/input/web_pointer_properties.h +++ b/third_party/blink/public/common/input/web_pointer_properties.h @@ -109,6 +109,9 @@ class WebPointerProperties { // TODO(crbug.com/982379): Figure out how to avoid using this boolean. bool is_raw_movement_event = false; + // Contains unique device id for pen on supported devices. + int32_t device_id = -1; + protected: // Widget coordinate, which is relative to the bound of current RenderWidget // (e.g. a plugin or OOPIF inside a RenderView). Similar to viewport diff --git a/third_party/blink/public/mojom/input/input_handler.mojom b/third_party/blink/public/mojom/input/input_handler.mojom index 9b41db62630cd..020807b5e96da 100644 --- a/third_party/blink/public/mojom/input/input_handler.mojom +++ b/third_party/blink/public/mojom/input/input_handler.mojom @@ -63,6 +63,7 @@ struct PointerData { gfx.mojom.PointF widget_position; gfx.mojom.PointF screen_position; MouseData? mouse_data; + int32 device_id; }; struct WheelData { diff --git a/third_party/blink/renderer/core/events/pointer_event.cc b/third_party/blink/renderer/core/events/pointer_event.cc index faab97b950193..66d194da08795 100644 --- a/third_party/blink/renderer/core/events/pointer_event.cc +++ b/third_party/blink/renderer/core/events/pointer_event.cc @@ -89,6 +89,9 @@ PointerEvent::PointerEvent(const AtomicString& type, PointerEventUtil::TransformToAzimuthInValidRange(azimuth_angle_), PointerEventUtil::TransformToAltitudeInValidRange(altitude_angle_)); } + if (initializer->hasDeviceId()) { + device_id_ = initializer->deviceId(); + } } bool PointerEvent::IsMouseEvent() const { diff --git a/third_party/blink/renderer/core/events/pointer_event.h b/third_party/blink/renderer/core/events/pointer_event.h index fa8c8dc2214fd..2c5a82cdf1067 100644 --- a/third_party/blink/renderer/core/events/pointer_event.h +++ b/third_party/blink/renderer/core/events/pointer_event.h @@ -103,6 +103,8 @@ class CORE_EXPORT PointerEvent : public MouseEvent { Document* GetDocument() const; + int32_t deviceId() const { return device_id_; } + void Trace(Visitor*) const override; private: @@ -127,6 +129,8 @@ class CORE_EXPORT PointerEvent : public MouseEvent { HeapVector> coalesced_events_; HeapVector> predicted_events_; + + int32_t device_id_; }; template <> diff --git a/third_party/blink/renderer/core/events/pointer_event.idl b/third_party/blink/renderer/core/events/pointer_event.idl index 640a313a9b6f7..4b1a4324d322b 100644 --- a/third_party/blink/renderer/core/events/pointer_event.idl +++ b/third_party/blink/renderer/core/events/pointer_event.idl @@ -20,6 +20,7 @@ [MeasureAs=PointerEventAttributeCount] readonly attribute long twist; [MeasureAs=PointerEventAttributeCount] readonly attribute DOMString pointerType; [MeasureAs=PointerEventAttributeCount] readonly attribute boolean isPrimary; + [MeasureAs=PointerEventAttributeCount, RuntimeEnabled=PointerEventDeviceId] readonly attribute long deviceId; // https://w3c.github.io/pointerevents/extension.html#extensions-to-the-pointerevent-interface sequence getCoalescedEvents(); diff --git a/third_party/blink/renderer/core/events/pointer_event_factory.cc b/third_party/blink/renderer/core/events/pointer_event_factory.cc index 6177db7741455..3d0315a999f47 100644 --- a/third_party/blink/renderer/core/events/pointer_event_factory.cc +++ b/third_party/blink/renderer/core/events/pointer_event_factory.cc @@ -197,6 +197,10 @@ HeapVector> PointerEventFactory::CreateEventSequence( last_global_position = event.PositionInScreen(); + if (pointer_event_init->hasDeviceId()) { + new_event_init->setDeviceId(pointer_event_init->deviceId()); + } + 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 @@ -352,6 +356,7 @@ PointerEvent* PointerEventFactory::Create( SetLastPosition(pointer_event_init->pointerId(), web_pointer_event.PositionInScreen(), event_type); + return PointerEvent::Create(type, pointer_event_init, web_pointer_event.TimeStamp()); } @@ -388,7 +393,8 @@ gfx::PointF PointerEventFactory::GetLastPointerPosition( PointerEvent* PointerEventFactory::CreatePointerCancelEvent( const int pointer_id, - base::TimeTicks platfrom_time_stamp) { + base::TimeTicks platfrom_time_stamp, + const int32_t device_id) { DCHECK(pointer_id_mapping_.Contains(pointer_id)); pointer_id_mapping_.Set( pointer_id, @@ -404,6 +410,8 @@ PointerEvent* PointerEventFactory::CreatePointerCancelEvent( SetEventSpecificFields(pointer_event_init, event_type_names::kPointercancel); + pointer_event_init->setDeviceId(device_id); + return PointerEvent::Create(event_type_names::kPointercancel, pointer_event_init, platfrom_time_stamp); } @@ -432,6 +440,7 @@ PointerEvent* PointerEventFactory::CreatePointerEventFrom( pointer_event->tangentialPressure()); pointer_event_init->setTwist(pointer_event->twist()); pointer_event_init->setView(pointer_event->view()); + pointer_event_init->setDeviceId(pointer_event->deviceId()); SetEventSpecificFields(pointer_event_init, type); diff --git a/third_party/blink/renderer/core/events/pointer_event_factory.h b/third_party/blink/renderer/core/events/pointer_event_factory.h index 361eb71e16734..323fe7d9e149b 100644 --- a/third_party/blink/renderer/core/events/pointer_event_factory.h +++ b/third_party/blink/renderer/core/events/pointer_event_factory.h @@ -5,6 +5,7 @@ #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/abseil-cpp/absl/types/optional.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" @@ -42,7 +43,8 @@ class CORE_EXPORT PointerEventFactory { LocalDOMWindow* view); PointerEvent* CreatePointerCancelEvent(const PointerId pointer_id, - base::TimeTicks platfrom_time_stamp); + base::TimeTicks platfrom_time_stamp, + const int32_t device_id); // For creating raw update events in chorded button case. PointerEvent* CreatePointerRawUpdateEvent(PointerEvent*); diff --git a/third_party/blink/renderer/core/events/pointer_event_factory_test.cc b/third_party/blink/renderer/core/events/pointer_event_factory_test.cc index 2e99a62bd238b..9634da882f79a 100644 --- a/third_party/blink/renderer/core/events/pointer_event_factory_test.cc +++ b/third_party/blink/renderer/core/events/pointer_event_factory_test.cc @@ -129,7 +129,8 @@ PointerEvent* PointerEventFactoryTest::CreateAndCheckPointerCancel( int unique_id, bool is_primary) { PointerEvent* pointer_event = pointer_event_factory_.CreatePointerCancelEvent( - unique_id, WebInputEvent::GetStaticTimeStampForTests()); + unique_id, WebInputEvent::GetStaticTimeStampForTests(), + /* deviceId */ -1); EXPECT_EQ("pointercancel", pointer_event->type()); EXPECT_EQ(unique_id, pointer_event->pointerId()); EXPECT_EQ(is_primary, pointer_event->isPrimary()); diff --git a/third_party/blink/renderer/core/events/pointer_event_init.idl b/third_party/blink/renderer/core/events/pointer_event_init.idl index 2a76a4ba86a98..9e0d4a9220e74 100644 --- a/third_party/blink/renderer/core/events/pointer_event_init.idl +++ b/third_party/blink/renderer/core/events/pointer_event_init.idl @@ -17,6 +17,7 @@ dictionary PointerEventInit : MouseEventInit { long twist = 0; DOMString pointerType = ""; boolean isPrimary = false; + long deviceId = -1; // https://w3c.github.io/pointerevents/extension.html#extensions-to-the-pointerevent-interface sequence coalescedEvents = []; diff --git a/third_party/blink/renderer/core/input/pointer_event_manager.cc b/third_party/blink/renderer/core/input/pointer_event_manager.cc index 51c6e73943ca8..f05d79727d6c1 100644 --- a/third_party/blink/renderer/core/input/pointer_event_manager.cc +++ b/third_party/blink/renderer/core/input/pointer_event_manager.cc @@ -318,7 +318,8 @@ void PointerEventManager::HandlePointerInterruption( WebPointerProperties::PointerType::kMouse) { canceled_pointer_events.push_back( pointer_event_factory_.CreatePointerCancelEvent( - PointerEventFactory::kMouseId, web_pointer_event.TimeStamp())); + PointerEventFactory::kMouseId, web_pointer_event.TimeStamp(), + web_pointer_event.device_id)); } else { // TODO(nzolghadr): Maybe canceling all the non-hovering pointers is not // the best strategy here. See the github issue for more details: @@ -332,7 +333,8 @@ void PointerEventManager::HandlePointerInterruption( for (PointerId pointer_id : non_hovering_pointer_ids) { canceled_pointer_events.push_back( pointer_event_factory_.CreatePointerCancelEvent( - pointer_id, web_pointer_event.TimeStamp())); + pointer_id, web_pointer_event.TimeStamp(), + web_pointer_event.device_id)); } non_hovering_pointers_canceled_ = true; @@ -691,7 +693,8 @@ WebInputEventResult PointerEventManager::HandlePointerEvent( SendTouchPointerEvent( pointer_event_target.target_element, pointer_event_factory_.CreatePointerCancelEvent( - core_pointer_event->pointerId(), event.TimeStamp()), + core_pointer_event->pointerId(), event.TimeStamp(), + core_pointer_event->deviceId()), event.hovering); } diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index cde3e90c09fc4..4f9a550afadd7 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5 @@ -2563,6 +2563,10 @@ base_feature: "none", origin_trial_feature_name: "PNaCl", }, + { + name: "PointerEventDeviceId", + status: "test", + }, { name: "PointerLockOptions", origin_trial_feature_name: "PointerLockOptions", diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 24edb1267ff25..bb510c1b29dbd 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites @@ -1862,6 +1862,15 @@ "args": ["--enable-features=AllowRTCEncodedVideoFrameSetMetadataAllFields"], "expires": "Jul 1, 2023" }, + { + "prefix": "disable-device-id-pointer-event", + "platforms": ["Linux", "Mac", "Win"], + "bases": ["fast/events/pointerevents/device-id"], + "args": [ + "--disable-blink-features=PointerEventDeviceId" + ], + "expires": "Jul 1, 2023" + }, { "prefix": "webrtc-legacy-stats-trial-disabled", "platforms": ["Linux", "Mac", "Win"], diff --git a/third_party/blink/web_tests/fast/events/pointerevents/device-id/get-device-id-from-pointer-event.html b/third_party/blink/web_tests/fast/events/pointerevents/device-id/get-device-id-from-pointer-event.html new file mode 100644 index 0000000000000..0976983a2ce14 --- /dev/null +++ b/third_party/blink/web_tests/fast/events/pointerevents/device-id/get-device-id-from-pointer-event.html @@ -0,0 +1,50 @@ + + + + +
+
+ + \ No newline at end of file diff --git a/third_party/blink/web_tests/fast/events/pointerevents/device-id/pointer-event-has-device-id-from-pointer-event-init.html b/third_party/blink/web_tests/fast/events/pointerevents/device-id/pointer-event-has-device-id-from-pointer-event-init.html new file mode 100644 index 0000000000000..97a1e7b554d4c --- /dev/null +++ b/third_party/blink/web_tests/fast/events/pointerevents/device-id/pointer-event-has-device-id-from-pointer-event-init.html @@ -0,0 +1,54 @@ + + + +
+ + + \ No newline at end of file diff --git a/third_party/blink/web_tests/virtual/disable-device-id-pointer-event/fast/events/pointerevents/device-id/README.txt b/third_party/blink/web_tests/virtual/disable-device-id-pointer-event/fast/events/pointerevents/device-id/README.txt new file mode 100644 index 0000000000000..7399b3701e3b1 --- /dev/null +++ b/third_party/blink/web_tests/virtual/disable-device-id-pointer-event/fast/events/pointerevents/device-id/README.txt @@ -0,0 +1,2 @@ +This test suite runs the tests in fast/events/pointerevents/device-id +with the flag PointerEventDeviceId disabled. \ No newline at end of file diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index df3feb6e21ec4..a586cca0e394b 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt @@ -7046,6 +7046,7 @@ interface PointerEvent : MouseEvent attribute @@toStringTag getter altitudeAngle getter azimuthAngle + getter deviceId getter height getter isPrimary getter pointerId