diff --git a/engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart b/engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart index d571e631c88..014fffbbd96 100644 --- a/engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart +++ b/engine/src/flutter/lib/web_ui/lib/src/engine/semantics/semantics.dart @@ -2477,6 +2477,7 @@ class EngineSemantics { final PlatformConfiguration newConfiguration = EnginePlatformDispatcher.instance.configuration .copyWith(accessibilityFeatures: original.copyWith(accessibleNavigation: value)); EnginePlatformDispatcher.instance.configuration = newConfiguration; + EnginePlatformDispatcher.instance.invokeOnAccessibilityFeaturesChanged(); _semanticsEnabled = value; diff --git a/engine/src/flutter/lib/web_ui/test/engine/window_test.dart b/engine/src/flutter/lib/web_ui/test/engine/window_test.dart index 73a2bd50a16..822520cf968 100644 --- a/engine/src/flutter/lib/web_ui/test/engine/window_test.dart +++ b/engine/src/flutter/lib/web_ui/test/engine/window_test.dart @@ -334,6 +334,19 @@ Future testMain() async { EnginePlatformDispatcher.instance.invokeOnAccessibilityFeaturesChanged(); }); + test('onAccessibilityFeaturesChanged is called when semantics is enabled', () { + bool a11yChangeInvoked = false; + myWindow.onAccessibilityFeaturesChanged = () { + a11yChangeInvoked = true; + }; + + expect(EngineSemantics.instance.semanticsEnabled, isFalse); + EngineSemantics.instance.semanticsEnabled = true; + + expect(EngineSemantics.instance.semanticsEnabled, isTrue); + expect(a11yChangeInvoked, isTrue); + }); + test('onPlatformMessage preserves the zone', () { final Zone innerZone = Zone.current.fork(); diff --git a/packages/flutter/lib/src/semantics/binding.dart b/packages/flutter/lib/src/semantics/binding.dart index e09ab653843..b02315df9ea 100644 --- a/packages/flutter/lib/src/semantics/binding.dart +++ b/packages/flutter/lib/src/semantics/binding.dart @@ -10,6 +10,7 @@ library; import 'dart:ui' as ui show AccessibilityFeatures, SemanticsActionEvent, SemanticsUpdateBuilder; import 'package:flutter/foundation.dart'; +import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; import 'debug.dart'; @@ -26,7 +27,17 @@ mixin SemanticsBinding on BindingBase { platformDispatcher ..onSemanticsEnabledChanged = _handleSemanticsEnabledChanged ..onSemanticsActionEvent = _handleSemanticsActionEvent - ..onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged; + ..onAccessibilityFeaturesChanged = () { + // TODO(chunhtai): Web should not notify accessibility feature changes during updateSemantics + // https://github.com/flutter/flutter/issues/158399 + if (SchedulerBinding.instance.schedulerPhase == SchedulerPhase.persistentCallbacks) { + SchedulerBinding.instance.addPostFrameCallback((Duration duration) { + handleAccessibilityFeaturesChanged(); + }, debugLabel: 'SemanticsBinding.handleAccessibilityFeaturesChanged'); + } else { + handleAccessibilityFeaturesChanged(); + } + }; _handleSemanticsEnabledChanged(); } diff --git a/packages/flutter/test/material/app_test.dart b/packages/flutter/test/material/app_test.dart index af9e0565ea7..ee04f3d2524 100644 --- a/packages/flutter/test/material/app_test.dart +++ b/packages/flutter/test/material/app_test.dart @@ -425,7 +425,7 @@ void main() { // didChangeAccessibilityFeatures tester.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn; - await tester.pump(); + await tester.pumpAndSettle(); expect(routeBuildCount, equals(1)); expect(dependentBuildCount, equals(5)); diff --git a/packages/flutter/test/widgets/media_query_test.dart b/packages/flutter/test/widgets/media_query_test.dart index 8ca9fddcf8b..6f671c3841b 100644 --- a/packages/flutter/test/widgets/media_query_test.dart +++ b/packages/flutter/test/widgets/media_query_test.dart @@ -451,7 +451,7 @@ void main() { expect(data.accessibleNavigation, true); tester.platformDispatcher.accessibilityFeaturesTestValue = const FakeAccessibilityFeatures(); - await tester.pump(); + await tester.pumpAndSettle(); expect(data.accessibleNavigation, false); expect(rebuildCount, 4); @@ -512,7 +512,7 @@ void main() { expect(data.accessibleNavigation, true); tester.platformDispatcher.accessibilityFeaturesTestValue = const FakeAccessibilityFeatures(); - await tester.pump(); + await tester.pumpAndSettle(); expect(data.accessibleNavigation, true); expect(rebuildCount, 1);