diff --git a/lib/web_ui/lib/src/engine/pointer_binding.dart b/lib/web_ui/lib/src/engine/pointer_binding.dart index 7a67c14588fc3837368a8e10990c76adfd63235c..2e837091010eb6f7aea4c785de0ea3c823b95ae5 100644 --- a/lib/web_ui/lib/src/engine/pointer_binding.dart +++ b/lib/web_ui/lib/src/engine/pointer_binding.dart @@ -14,6 +14,7 @@ class PointerBinding { /// The singleton instance of this object. static PointerBinding get instance => _instance; static PointerBinding _instance; + // Set of pointerIds that are added before routing hover and mouse wheel // events. // @@ -61,6 +62,7 @@ class PointerBinding { newDetector ??= const PointerSupportDetector(); // When changing the detector, we need to swap the adapter. if (newDetector != _detector) { + _activePointerIds.clear(); _detector = newDetector; _adapter?.clearListeners(); _adapter = _createAdapter(); @@ -213,6 +215,8 @@ class PointerAdapter extends BaseAdapter { _addEventListener('pointerdown', (html.Event event) { final int pointerButton = _pointerButtonFromHtmlEvent(event); final int device = _deviceFromHtmlEvent(event); + // The pointerdown event will cause an 'add' event on the framework side. + PointerBinding._instance._activePointerIds.add(device); if (_isButtonDown(device, pointerButton)) { // TODO(flutter_web): Remove this temporary fix for right click // on web platform once context guesture is implemented. @@ -452,6 +456,10 @@ class MouseAdapter extends BaseAdapter { html.MouseEvent event, ) { final List data = []; + // The mousedown event will cause an 'add' event on the framework side. + if (event.type == 'mousedown') { + PointerBinding._instance._activePointerIds.add(_mouseDeviceId); + } if (event.type == 'mousemove') { _ensureMouseDeviceAdded(data, event.client.x, event.client.y, event.buttons, event.timeStamp, _mouseDeviceId); diff --git a/lib/web_ui/test/engine/pointer_binding_test.dart b/lib/web_ui/test/engine/pointer_binding_test.dart index 0f4dee1f61f383f3bdba6c56248f771fa6d04eb4..3638376cc6b8b7f45289b87fe59fec00476ee19f 100644 --- a/lib/web_ui/test/engine/pointer_binding_test.dart +++ b/lib/web_ui/test/engine/pointer_binding_test.dart @@ -83,6 +83,41 @@ void main() { expect(packets[1].data[0].change, equals(ui.PointerChange.down)); expect(packets[1].data[0].device, equals(2)); }); + + test('creates an add event if the first pointer activity is a hover', () { + List packets = []; + ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) { + packets.add(packet); + }; + + glassPane.dispatchEvent(html.PointerEvent('pointermove', { + 'pointerId': 1, + 'button': 1, + })); + + expect(packets, hasLength(1)); + expect(packets.single.data, hasLength(2)); + + expect(packets.single.data[0].change, equals(ui.PointerChange.add)); + expect(packets.single.data[1].change, equals(ui.PointerChange.hover)); + }); + + test('does not create an add event if got a pointerdown', () { + List packets = []; + ui.window.onPointerDataPacket = (ui.PointerDataPacket packet) { + packets.add(packet); + }; + + glassPane.dispatchEvent(html.PointerEvent('pointerdown', { + 'pointerId': 1, + 'button': 1, + })); + + expect(packets, hasLength(1)); + expect(packets.single.data, hasLength(1)); + + expect(packets.single.data[0].change, equals(ui.PointerChange.down)); + }); }); }