diff --git a/lib/web_ui/lib/src/engine/semantics/semantics_helper.dart b/lib/web_ui/lib/src/engine/semantics/semantics_helper.dart index 93c086670addd..0b9245b922c8d 100644 --- a/lib/web_ui/lib/src/engine/semantics/semantics_helper.dart +++ b/lib/web_ui/lib/src/engine/semantics/semantics_helper.dart @@ -256,8 +256,11 @@ class MobileSemanticsEnabler extends SemanticsEnabler { @override bool tryEnableSemantics(html.Event event) { if (_schedulePlaceholderRemoval) { - final bool removeNow = - (browserEngine != BrowserEngine.webkit || event.type == 'touchend'); + // The event type can also be click for VoiceOver. + final bool removeNow = (browserEngine != BrowserEngine.webkit || + event.type == 'touchend' || + event.type == 'pointerup' || + event.type == 'click'); if (removeNow) { _semanticsPlaceholder!.remove(); _semanticsPlaceholder = null; @@ -280,10 +283,16 @@ class MobileSemanticsEnabler extends SemanticsEnabler { return true; } + // ios-safari browsers which starts sending `pointer` events instead of + // `touch` events. (Tested with 12.1 which uses touch events vs 13.5 + // which uses pointer events.) const Set kInterestingEventTypes = { 'click', 'touchstart', 'touchend', + 'pointerdown', + 'pointermove', + 'pointerup', }; if (!kInterestingEventTypes.contains(event.type)) { @@ -333,6 +342,11 @@ class MobileSemanticsEnabler extends SemanticsEnabler { final html.TouchEvent touch = event as html.TouchEvent; activationPoint = touch.changedTouches!.first.client; break; + case 'pointerdown': + case 'pointerup': + final html.PointerEvent touch = event as html.PointerEvent; + activationPoint = new html.Point(touch.client.x, touch.client.y); + break; default: // The event is not relevant, forward to framework as normal. return true; @@ -341,9 +355,11 @@ class MobileSemanticsEnabler extends SemanticsEnabler { final html.Rectangle activatingElementRect = domRenderer.glassPaneElement!.getBoundingClientRect(); final double midX = (activatingElementRect.left + - (activatingElementRect.right - activatingElementRect.left) / 2).toDouble(); + (activatingElementRect.right - activatingElementRect.left) / 2) + .toDouble(); final double midY = (activatingElementRect.top + - (activatingElementRect.bottom - activatingElementRect.top) / 2).toDouble(); + (activatingElementRect.bottom - activatingElementRect.top) / 2) + .toDouble(); final double deltaX = activationPoint.x.toDouble() - midX; final double deltaY = activationPoint.y.toDouble() - midY; final double deltaSquared = deltaX * deltaX + deltaY * deltaY; diff --git a/lib/web_ui/test/engine/semantics/semantics_helper_test.dart b/lib/web_ui/test/engine/semantics/semantics_helper_test.dart index 137bd2baf8cb0..0df7f7449da3e 100644 --- a/lib/web_ui/test/engine/semantics/semantics_helper_test.dart +++ b/lib/web_ui/test/engine/semantics/semantics_helper_test.dart @@ -9,6 +9,8 @@ import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; import 'package:ui/src/engine.dart'; +const PointerSupportDetector _defaultSupportDetector = PointerSupportDetector(); + void main() { internalBootstrapBrowserTest(() => testMain); } @@ -151,15 +153,22 @@ void testMain() { skip: browserEngine == BrowserEngine.webkit); test('Not relevant events should be forwarded to the framework', () async { - final html.Event event = html.TouchEvent('touchcancel'); + html.Event event; + if (_defaultSupportDetector.hasPointerEvents) { + event = html.PointerEvent('pointermove'); + } else if (_defaultSupportDetector.hasTouchEvents) { + event = html.TouchEvent('touchcancel'); + } else { + event = html.MouseEvent('mousemove'); + } + bool shouldForwardToFramework = mobileSemanticsEnabler.tryEnableSemantics(event); expect(shouldForwardToFramework, true); - }, - // TODO(nurhan): https://github.com/flutter/flutter/issues/50590 - // TODO(nurhan): https://github.com/flutter/flutter/issues/46638 - // TODO(nurhan): https://github.com/flutter/flutter/issues/50754 - skip: browserEngine != BrowserEngine.blink); - }); + }); + }, // Run the `MobileSemanticsEnabler` only on mobile browsers. + skip: operatingSystem == OperatingSystem.linux || + operatingSystem == OperatingSystem.macOs || + operatingSystem == OperatingSystem.windows); }