From facbe5202f4bf7c00e08f319ff18ccded6af8a48 Mon Sep 17 00:00:00 2001 From: Pavan Kumar Date: Thu, 10 Apr 2025 01:13:19 +0530 Subject: [PATCH] Fix: Focus on leading icon when null (#164966) Fix: Focus on leading icon when null fixes: #164905 ## 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. - [x] 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. --- .../lib/src/material/dropdown_menu.dart | 11 +++ .../test/material/dropdown_menu_test.dart | 78 +++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/packages/flutter/lib/src/material/dropdown_menu.dart b/packages/flutter/lib/src/material/dropdown_menu.dart index 6e2fb035a99..52326b95c2e 100644 --- a/packages/flutter/lib/src/material/dropdown_menu.dart +++ b/packages/flutter/lib/src/material/dropdown_menu.dart @@ -1417,6 +1417,17 @@ class _RenderDropdownMenuBody extends RenderBox } return false; } + + // Children except the text field (first child) are laid out for measurement purpose but not painted. + @override + void visitChildrenForSemantics(RenderObjectVisitor visitor) { + visitChildren((RenderObject renderObjectChild) { + final RenderBox child = renderObjectChild as RenderBox; + if (child == firstChild) { + visitor(renderObjectChild); + } + }); + } } // Hand coded defaults. These will be updated once we have tokens/spec. diff --git a/packages/flutter/test/material/dropdown_menu_test.dart b/packages/flutter/test/material/dropdown_menu_test.dart index 11804862ba5..99123f4b2c4 100644 --- a/packages/flutter/test/material/dropdown_menu_test.dart +++ b/packages/flutter/test/material/dropdown_menu_test.dart @@ -10,6 +10,8 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import '../widgets/semantics_tester.dart'; + void main() { const String longText = 'one two three four five six seven eight nine ten eleven twelve'; final List> menuChildren = >[]; @@ -4135,6 +4137,82 @@ void main() { expect(tester.takeException(), isNull); expect(tester.getSize(findMenuItemButton(menuChildren.first.label)).width, 150.0); }); + + // Regression test for https://github.com/flutter/flutter/issues/164905. + testWidgets('ensure exclude semantics for trailing button', (WidgetTester tester) async { + final SemanticsTester semantics = SemanticsTester(tester); + + await tester.pumpWidget( + const MaterialApp( + home: Scaffold( + body: DropdownMenu( + dropdownMenuEntries: >[ + DropdownMenuEntry(value: 0, label: 'Item 0'), + ], + ), + ), + ), + ); + + expect( + semantics, + hasSemantics( + TestSemantics.root( + children: [ + TestSemantics( + id: 1, + textDirection: TextDirection.ltr, + children: [ + TestSemantics( + id: 2, + children: [ + TestSemantics( + id: 3, + flags: [SemanticsFlag.scopesRoute], + children: [ + TestSemantics( + id: 5, + flags: [ + SemanticsFlag.isTextField, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isReadOnly, + ], + actions: [SemanticsAction.focus], + textDirection: TextDirection.ltr, + children: [ + TestSemantics( + id: 6, + flags: [ + SemanticsFlag.hasSelectedState, + SemanticsFlag.isButton, + SemanticsFlag.hasEnabledState, + SemanticsFlag.isEnabled, + SemanticsFlag.isFocusable, + ], + actions: [ + SemanticsAction.tap, + SemanticsAction.focus, + ], + ), + ], + ), + ], + ), + ], + ), + ], + ), + ], + ), + ignoreRect: true, + ignoreTransform: true, + ignoreId: true, + ), + ); + + semantics.dispose(); + }); } enum TestMenu {