From 243413f11b689bc32d44480a766828a72a72fe64 Mon Sep 17 00:00:00 2001 From: Kostia Sokolovskyi Date: Wed, 5 Feb 2025 22:55:44 +0100 Subject: [PATCH] Add role check in SemanticsNode._isDifferentFromCurrentSemanticAnnotation function. (#162578) Fixes https://github.com/flutter/flutter/issues/162577 ### Description - Adds `role` check in `SemanticsNode._isDifferentFromCurrentSemanticAnnotation` function. - Adds `SemanticsNode.debugIsDirty` property to check in tests whether the node is marked as dirty. ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [X] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [X] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. --- .../flutter/lib/src/semantics/semantics.dart | 18 +++++++++++++++++- .../flutter/test/semantics/semantics_test.dart | 13 +++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/semantics/semantics.dart b/packages/flutter/lib/src/semantics/semantics.dart index 4f6254f309..8d7223c6e2 100644 --- a/packages/flutter/lib/src/semantics/semantics.dart +++ b/packages/flutter/lib/src/semantics/semantics.dart @@ -2429,6 +2429,22 @@ class SemanticsNode with DiagnosticableTreeMixin { } } + /// When asserts are enabled, returns whether node is marked as dirty. + /// + /// Otherwise, returns null. + /// + /// This getter is intended for use in framework unit tests. Applications must + /// not depend on its value. + @visibleForTesting + bool? get debugIsDirty { + bool? isDirty; + assert(() { + isDirty = _dirty; + return true; + }()); + return isDirty; + } + bool _isDifferentFromCurrentSemanticAnnotation(SemanticsConfiguration config) { return _attributedLabel != config.attributedLabel || _attributedHint != config.attributedHint || @@ -2454,7 +2470,7 @@ class SemanticsNode with DiagnosticableTreeMixin { _areUserActionsBlocked != config.isBlockingUserActions || _headingLevel != config._headingLevel || _linkUrl != config._linkUrl || - _linkUrl != config._linkUrl; + _role != config.role; } // TAGS, LABELS, ACTIONS diff --git a/packages/flutter/test/semantics/semantics_test.dart b/packages/flutter/test/semantics/semantics_test.dart index b268c32674..418f02969c 100644 --- a/packages/flutter/test/semantics/semantics_test.dart +++ b/packages/flutter/test/semantics/semantics_test.dart @@ -464,6 +464,19 @@ void main() { expect(root.debugSemantics!.getSemanticsData().actions, expectedActions); }, ); + + test('updateWith marks node as dirty when role changes', () { + final SemanticsNode node = SemanticsNode(); + + expect(node.role, SemanticsRole.none); + expect(node.debugIsDirty, isFalse); + + final SemanticsConfiguration config = SemanticsConfiguration()..role = SemanticsRole.tab; + node.updateWith(config: config); + + expect(node.role, config.role); + expect(node.debugIsDirty, isTrue); + }); }); test('toStringDeep() does not throw with transform == null', () {