[Shortcuts] Improve focus node debug labels#181834
Conversation
There was a problem hiding this comment.
Code Review
This pull request improves the debuggability of Shortcuts widgets by propagating the debugLabel to the underlying Focus node. This is a valuable enhancement for debugging focus-related issues. The implementation is correct and includes new tests to verify the behavior. I have a couple of suggestions to enhance code readability and strengthen the test assertions.
Renzo-Olivares
left a comment
There was a problem hiding this comment.
LGTM, awesome improvement!
justinmc
left a comment
There was a problem hiding this comment.
LGTM 👍 Thanks for taking the time to fix that!
|
autosubmit label was removed for flutter/flutter/181834, because The base commit of the PR is older than 7 days and can not be merged. Please merge the latest changes from the main into this branch and resubmit the PR. |
ab49298 to
6e539da
Compare
### Problem The `Shortcuts` widget creates focus nodes to listen to key events. If your `Shortcuts` don't work as expected, you can enable [`debugFocusChanges`](https://api.flutter.dev/flutter/cupertino/debugFocusChanges.html) to debug your app. However, the log for when a `Shortcuts` widget handles a key event did not make it clear _which_ `Shortcuts` widget handled the key event: ``` FOCUS: Node FocusNode#12e36(Shortcuts [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). ``` Being able to distinguish `Shortcuts` widgets is important as even a minimal Material app has 4 `Shortcuts` widgets. ### Solution This change updates the `Shortcuts` widget to pass its debug label down to the focus node it creates. This improves focus logs to make it clearer which `Shortcuts` handled a key event: ### Before and after examples Example log when a `Shortcuts` handles a key event: ```diff - FOCUS: Node FocusNode#12e36(Shortcuts [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). + FOCUS: Node FocusNode#12e36(Shortcuts: <Web Disabling Text Editing Shortcuts> [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). ``` Example focus tree for a minimal Material app: <details><summary>Focus tree...</summary> App: ```dart import 'package:flutter/material.dart'; void main() { debugFocusChanges = true; runApp( const MaterialApp( home: Scaffold( body: Center( child: Text('Hello, World!'), ), ), ), ); } ``` Resulting focus tree before and after this change: ```diff FocusManager#76dc7 │ primaryFocus: FocusScopeNode#553ee(Root Focus Scope [PRIMARY │ FOCUS]) └─rootScope: FocusScopeNode#553ee(Root Focus Scope [PRIMARY FOCUS]) │ PRIMARY FOCUS │ focusedChildren: FocusScopeNode#9bb6a(View Scope) └─Child 1: _FocusTraversalGroupNode#85c63(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#9bb6a(View Scope) │ context: _FocusScopeWithExternalFocusNode │ focusedChildren: FocusScopeNode#b6f31(Navigator Scope) - └─Child 1: FocusNode#bb974(Shortcuts) + └─Child 1: FocusNode#bb974(Shortcuts: <Default WidgetsApp Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#255fb(Shortcuts) + └─Child 1: FocusNode#255fb(Shortcuts: <Default Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#af347(Shortcuts) + └─Child 1: FocusNode#af347(Shortcuts: <Web Disabling Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE └─Child 1: _FocusTraversalGroupNode#bf036(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#8e60c(Shortcuts) + └─Child 1: FocusNode#8e60c(Shortcuts: <Shortcut Registrar>) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#54bda │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#b6f31(Navigator Scope) │ context: FocusScope │ focusedChildren: FocusScopeNode#2df85(_ModalScopeState<dynamic> │ Focus Scope) └─Child 1: _FocusTraversalGroupNode#82ab3(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#4b8f5(Navigator) │ context: Focus └─Child 1: FocusScopeNode#2df85(_ModalScopeState<dynamic> Focus Scope) context: _FocusScopeWithExternalFocusNode ``` </details> ## 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]. - [ ] 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. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Roll Flutter from b31548feb941 to 1141b2bdce66 (56 revisions) flutter/flutter@b31548f...1141b2b 2026-02-27 maxime.pontoire@me.com flutter#182361 Fix delegate copy on plugins init (flutter/flutter#182362) 2026-02-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 8b036b3e63cb to 1cdb7dfd913e (1 revision) (flutter/flutter#183004) 2026-02-27 vegorov@google.com Manual roll Dart SDK to 3.12.0-192.0.dev (flutter/flutter#182883) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from e2062707b0c0 to ed220c490eea (1 revision) (flutter/flutter#182992) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from e5aa1ab5c59c to e2062707b0c0 (3 revisions) (flutter/flutter#182989) 2026-02-27 oss@simonbinder.eu Linux build hooks: Read compiler config from CMakeCache.txt (flutter/flutter#181004) 2026-02-27 engine-flutter-autoroll@skia.org Roll ICU from a86a32e67b8d to 7971660ba630 (3 revisions) (flutter/flutter#182986) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from 49c2de95384e to e5aa1ab5c59c (2 revisions) (flutter/flutter#182980) 2026-02-27 flar@google.com [Impeller] Remove shared rendering data from TextFrame (flutter/flutter#182886) 2026-02-27 robert.ancell@canonical.com Add fl_view_new_sized_to_content() (flutter/flutter#182924) 2026-02-27 737941+loic-sharma@users.noreply.github.com [Shortcuts] Improve focus node debug labels (flutter/flutter#181834) 2026-02-27 34871572+gmackall@users.noreply.github.com Add a cli flag for toggling HCPP use, and enable it (flutter/flutter#182516) 2026-02-27 nate.w5687@gmail.com `SizedBox.square()` (flutter/flutter#182731) 2026-02-27 1961493+harryterkelsen@users.noreply.github.com [web] Fix stack corruption in Skwasm and harden withStackScope API (flutter/flutter#182912) 2026-02-26 jason-simmons@users.noreply.github.com Roll zlib to 7eda07b1e067 (flutter/flutter#182692) 2026-02-26 bkonyi@google.com [ CI ] Don't crash analysis when ktlint isn't on PATH (flutter/flutter#181854) 2026-02-26 34871572+gmackall@users.noreply.github.com Add calls to await `flutterDriver.waitUntilFirstFrameRasterized()` for all `android_engine_test` screenshot tests (flutter/flutter#182961) 2026-02-26 engine-flutter-autoroll@skia.org Roll Skia from f44d7db68805 to 49c2de95384e (30 revisions) (flutter/flutter#182957) 2026-02-26 robert.ancell@canonical.com Support sending window constraints in metrics events (flutter/flutter#182921) 2026-02-26 34465683+rkishan516@users.noreply.github.com Reland: remove material in context_menu_controller_test, icon_test, list_wheel_scroll_view_test, media_query_test, platform_menu_bar_test (flutter/flutter#182891) 2026-02-26 116356835+AbdeMohlbi@users.noreply.github.com Remove some instances of useMaterial3: true (flutter/flutter#182944) 2026-02-26 serhatguler@hotmail.de [Impeller] Use bilinear filtering for non-uniform scaled text (flutter/flutter#182224) 2026-02-26 chingjun@google.com Add a ResidentCompilerFactory to create ResidentCompiler instances. (flutter/flutter#182930) 2026-02-26 chingjun@google.com Add a getter in run.dart to access use-application-binary flag. (flutter/flutter#182931) 2026-02-26 mdebbar@google.com [web] Roll Firefox to 148 (flutter/flutter#182859) 2026-02-26 engine-flutter-autoroll@skia.org Roll Packages from acd9adb to e1d0169 (8 revisions) (flutter/flutter#182946) 2026-02-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from XI0Ax7fbtYE4XKYAQ... to G1GwOdVt5bM7GjMSY... (flutter/flutter#182942) 2026-02-26 robert.ancell@canonical.com Add test for WindowPositioner.toString (flutter/flutter#182906) 2026-02-26 robert.ancell@canonical.com Remove unused function prototype (flutter/flutter#182915) 2026-02-26 ahmedsameha1@gmail.com Resolve inconsistency with SchedulerBinding.scheduleTask usage recomm… (flutter/flutter#182531) 2026-02-26 51901607+O-Hannonen@users.noreply.github.com Fix false positives for hit test misses in flutter_test (flutter/flutter#180856) 2026-02-26 116356835+AbdeMohlbi@users.noreply.github.com Replace an instance of flutter/engine with flutter/flutter (flutter/flutter#182655) 2026-02-26 146823759+brahim-guaali@users.noreply.github.com Use null-aware elements in widgets/routes.dart (flutter/flutter#181242) 2026-02-26 37593616+itsAdityaRathore@users.noreply.github.com Fix typos in method names across multiple files (flutter/flutter#182584) 2026-02-26 brunocorona.alcantar@gmail.com Fix RawAutocomplete crash when options are hidden (flutter/flutter#182785) 2026-02-26 flar@google.com Describe implications of tree-status and Google Testing for PRs (flutter/flutter#182916) 2026-02-26 ahmedsameha1@gmail.com Make sure that a StretchingOverscrollIndicator doesn't crash when it … (flutter/flutter#182499) 2026-02-26 srawlins@google.com framework: Use a super-parameter in several missed cases (flutter/flutter#182580) 2026-02-25 nate.w5687@gmail.com `WidgetStatesConstraint` as a mixin (flutter/flutter#181704) 2026-02-25 Rusino@users.noreply.github.com Paint the paragraph as a single image (flutter/flutter#181206) 2026-02-25 rmolivares@renzo-olivares.dev Remove `ExtendSelectionByPageIntent` (flutter/flutter#182642) 2026-02-25 34465683+rkishan516@users.noreply.github.com feat: add few required properties to test widgets app (flutter/flutter#182805) 2026-02-25 prbillingsley89@gmail.com Updates MenuAnchor to respect software keyboard (flutter/flutter#180975) 2026-02-25 jason-simmons@users.noreply.github.com Roll ImGui to v1.92.6-docking (flutter/flutter#182799) 2026-02-25 jason-simmons@users.noreply.github.com Roll GoogleTest to e9907112b472 (flutter/flutter#182795) 2026-02-25 Veselblu@yandex.ru Make positionInlineChildren assert much clearer (flutter/flutter#182093) ...
### Problem The `Shortcuts` widget creates focus nodes to listen to key events. If your `Shortcuts` don't work as expected, you can enable [`debugFocusChanges`](https://api.flutter.dev/flutter/cupertino/debugFocusChanges.html) to debug your app. However, the log for when a `Shortcuts` widget handles a key event did not make it clear _which_ `Shortcuts` widget handled the key event: ``` FOCUS: Node FocusNode#12e36(Shortcuts [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). ``` Being able to distinguish `Shortcuts` widgets is important as even a minimal Material app has 4 `Shortcuts` widgets. ### Solution This change updates the `Shortcuts` widget to pass its debug label down to the focus node it creates. This improves focus logs to make it clearer which `Shortcuts` handled a key event: ### Before and after examples Example log when a `Shortcuts` handles a key event: ```diff - FOCUS: Node FocusNode#12e36(Shortcuts [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). + FOCUS: Node FocusNode#12e36(Shortcuts: <Web Disabling Text Editing Shortcuts> [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). ``` Example focus tree for a minimal Material app: <details><summary>Focus tree...</summary> App: ```dart import 'package:flutter/material.dart'; void main() { debugFocusChanges = true; runApp( const MaterialApp( home: Scaffold( body: Center( child: Text('Hello, World!'), ), ), ), ); } ``` Resulting focus tree before and after this change: ```diff FocusManager#76dc7 │ primaryFocus: FocusScopeNode#553ee(Root Focus Scope [PRIMARY │ FOCUS]) └─rootScope: FocusScopeNode#553ee(Root Focus Scope [PRIMARY FOCUS]) │ PRIMARY FOCUS │ focusedChildren: FocusScopeNode#9bb6a(View Scope) └─Child 1: _FocusTraversalGroupNode#85c63(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#9bb6a(View Scope) │ context: _FocusScopeWithExternalFocusNode │ focusedChildren: FocusScopeNode#b6f31(Navigator Scope) - └─Child 1: FocusNode#bb974(Shortcuts) + └─Child 1: FocusNode#bb974(Shortcuts: <Default WidgetsApp Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#255fb(Shortcuts) + └─Child 1: FocusNode#255fb(Shortcuts: <Default Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#af347(Shortcuts) + └─Child 1: FocusNode#af347(Shortcuts: <Web Disabling Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE └─Child 1: _FocusTraversalGroupNode#bf036(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#8e60c(Shortcuts) + └─Child 1: FocusNode#8e60c(Shortcuts: <Shortcut Registrar>) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#54bda │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#b6f31(Navigator Scope) │ context: FocusScope │ focusedChildren: FocusScopeNode#2df85(_ModalScopeState<dynamic> │ Focus Scope) └─Child 1: _FocusTraversalGroupNode#82ab3(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#4b8f5(Navigator) │ context: Focus └─Child 1: FocusScopeNode#2df85(_ModalScopeState<dynamic> Focus Scope) context: _FocusScopeWithExternalFocusNode ``` </details> ## 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]. - [ ] 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. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…r#11137) Roll Flutter from b31548feb941 to 1141b2bdce66 (56 revisions) flutter/flutter@b31548f...1141b2b 2026-02-27 maxime.pontoire@me.com flutter#182361 Fix delegate copy on plugins init (flutter/flutter#182362) 2026-02-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 8b036b3e63cb to 1cdb7dfd913e (1 revision) (flutter/flutter#183004) 2026-02-27 vegorov@google.com Manual roll Dart SDK to 3.12.0-192.0.dev (flutter/flutter#182883) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from e2062707b0c0 to ed220c490eea (1 revision) (flutter/flutter#182992) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from e5aa1ab5c59c to e2062707b0c0 (3 revisions) (flutter/flutter#182989) 2026-02-27 oss@simonbinder.eu Linux build hooks: Read compiler config from CMakeCache.txt (flutter/flutter#181004) 2026-02-27 engine-flutter-autoroll@skia.org Roll ICU from a86a32e67b8d to 7971660ba630 (3 revisions) (flutter/flutter#182986) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from 49c2de95384e to e5aa1ab5c59c (2 revisions) (flutter/flutter#182980) 2026-02-27 flar@google.com [Impeller] Remove shared rendering data from TextFrame (flutter/flutter#182886) 2026-02-27 robert.ancell@canonical.com Add fl_view_new_sized_to_content() (flutter/flutter#182924) 2026-02-27 737941+loic-sharma@users.noreply.github.com [Shortcuts] Improve focus node debug labels (flutter/flutter#181834) 2026-02-27 34871572+gmackall@users.noreply.github.com Add a cli flag for toggling HCPP use, and enable it (flutter/flutter#182516) 2026-02-27 nate.w5687@gmail.com `SizedBox.square()` (flutter/flutter#182731) 2026-02-27 1961493+harryterkelsen@users.noreply.github.com [web] Fix stack corruption in Skwasm and harden withStackScope API (flutter/flutter#182912) 2026-02-26 jason-simmons@users.noreply.github.com Roll zlib to 7eda07b1e067 (flutter/flutter#182692) 2026-02-26 bkonyi@google.com [ CI ] Don't crash analysis when ktlint isn't on PATH (flutter/flutter#181854) 2026-02-26 34871572+gmackall@users.noreply.github.com Add calls to await `flutterDriver.waitUntilFirstFrameRasterized()` for all `android_engine_test` screenshot tests (flutter/flutter#182961) 2026-02-26 engine-flutter-autoroll@skia.org Roll Skia from f44d7db68805 to 49c2de95384e (30 revisions) (flutter/flutter#182957) 2026-02-26 robert.ancell@canonical.com Support sending window constraints in metrics events (flutter/flutter#182921) 2026-02-26 34465683+rkishan516@users.noreply.github.com Reland: remove material in context_menu_controller_test, icon_test, list_wheel_scroll_view_test, media_query_test, platform_menu_bar_test (flutter/flutter#182891) 2026-02-26 116356835+AbdeMohlbi@users.noreply.github.com Remove some instances of useMaterial3: true (flutter/flutter#182944) 2026-02-26 serhatguler@hotmail.de [Impeller] Use bilinear filtering for non-uniform scaled text (flutter/flutter#182224) 2026-02-26 chingjun@google.com Add a ResidentCompilerFactory to create ResidentCompiler instances. (flutter/flutter#182930) 2026-02-26 chingjun@google.com Add a getter in run.dart to access use-application-binary flag. (flutter/flutter#182931) 2026-02-26 mdebbar@google.com [web] Roll Firefox to 148 (flutter/flutter#182859) 2026-02-26 engine-flutter-autoroll@skia.org Roll Packages from acd9adb to e1d0169 (8 revisions) (flutter/flutter#182946) 2026-02-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from XI0Ax7fbtYE4XKYAQ... to G1GwOdVt5bM7GjMSY... (flutter/flutter#182942) 2026-02-26 robert.ancell@canonical.com Add test for WindowPositioner.toString (flutter/flutter#182906) 2026-02-26 robert.ancell@canonical.com Remove unused function prototype (flutter/flutter#182915) 2026-02-26 ahmedsameha1@gmail.com Resolve inconsistency with SchedulerBinding.scheduleTask usage recomm… (flutter/flutter#182531) 2026-02-26 51901607+O-Hannonen@users.noreply.github.com Fix false positives for hit test misses in flutter_test (flutter/flutter#180856) 2026-02-26 116356835+AbdeMohlbi@users.noreply.github.com Replace an instance of flutter/engine with flutter/flutter (flutter/flutter#182655) 2026-02-26 146823759+brahim-guaali@users.noreply.github.com Use null-aware elements in widgets/routes.dart (flutter/flutter#181242) 2026-02-26 37593616+itsAdityaRathore@users.noreply.github.com Fix typos in method names across multiple files (flutter/flutter#182584) 2026-02-26 brunocorona.alcantar@gmail.com Fix RawAutocomplete crash when options are hidden (flutter/flutter#182785) 2026-02-26 flar@google.com Describe implications of tree-status and Google Testing for PRs (flutter/flutter#182916) 2026-02-26 ahmedsameha1@gmail.com Make sure that a StretchingOverscrollIndicator doesn't crash when it … (flutter/flutter#182499) 2026-02-26 srawlins@google.com framework: Use a super-parameter in several missed cases (flutter/flutter#182580) 2026-02-25 nate.w5687@gmail.com `WidgetStatesConstraint` as a mixin (flutter/flutter#181704) 2026-02-25 Rusino@users.noreply.github.com Paint the paragraph as a single image (flutter/flutter#181206) 2026-02-25 rmolivares@renzo-olivares.dev Remove `ExtendSelectionByPageIntent` (flutter/flutter#182642) 2026-02-25 34465683+rkishan516@users.noreply.github.com feat: add few required properties to test widgets app (flutter/flutter#182805) 2026-02-25 prbillingsley89@gmail.com Updates MenuAnchor to respect software keyboard (flutter/flutter#180975) 2026-02-25 jason-simmons@users.noreply.github.com Roll ImGui to v1.92.6-docking (flutter/flutter#182799) 2026-02-25 jason-simmons@users.noreply.github.com Roll GoogleTest to e9907112b472 (flutter/flutter#182795) 2026-02-25 Veselblu@yandex.ru Make positionInlineChildren assert much clearer (flutter/flutter#182093) ...
### Problem The `Shortcuts` widget creates focus nodes to listen to key events. If your `Shortcuts` don't work as expected, you can enable [`debugFocusChanges`](https://api.flutter.dev/flutter/cupertino/debugFocusChanges.html) to debug your app. However, the log for when a `Shortcuts` widget handles a key event did not make it clear _which_ `Shortcuts` widget handled the key event: ``` FOCUS: Node FocusNode#12e36(Shortcuts [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). ``` Being able to distinguish `Shortcuts` widgets is important as even a minimal Material app has 4 `Shortcuts` widgets. ### Solution This change updates the `Shortcuts` widget to pass its debug label down to the focus node it creates. This improves focus logs to make it clearer which `Shortcuts` handled a key event: ### Before and after examples Example log when a `Shortcuts` handles a key event: ```diff - FOCUS: Node FocusNode#12e36(Shortcuts [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). + FOCUS: Node FocusNode#12e36(Shortcuts: <Web Disabling Text Editing Shortcuts> [IN FOCUS PATH])(context: Focus, NOT FOCUSABLE, IN FOCUS PATH) stopped key event propagation: KeyMessage([KeyDownEvent#7b499(physicalKey: PhysicalKeyboardKey#7002c(usbHidUsage: "0x0007002c", debugName: "Space"), logicalKey: LogicalKeyboardKey#00020(keyId: "0x00000020", keyLabel: " ", debugName: "Space"), character: " ", timeStamp: 0:00:04.982699)]). ``` Example focus tree for a minimal Material app: <details><summary>Focus tree...</summary> App: ```dart import 'package:flutter/material.dart'; void main() { debugFocusChanges = true; runApp( const MaterialApp( home: Scaffold( body: Center( child: Text('Hello, World!'), ), ), ), ); } ``` Resulting focus tree before and after this change: ```diff FocusManager#76dc7 │ primaryFocus: FocusScopeNode#553ee(Root Focus Scope [PRIMARY │ FOCUS]) └─rootScope: FocusScopeNode#553ee(Root Focus Scope [PRIMARY FOCUS]) │ PRIMARY FOCUS │ focusedChildren: FocusScopeNode#9bb6a(View Scope) └─Child 1: _FocusTraversalGroupNode#85c63(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#9bb6a(View Scope) │ context: _FocusScopeWithExternalFocusNode │ focusedChildren: FocusScopeNode#b6f31(Navigator Scope) - └─Child 1: FocusNode#bb974(Shortcuts) + └─Child 1: FocusNode#bb974(Shortcuts: <Default WidgetsApp Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#255fb(Shortcuts) + └─Child 1: FocusNode#255fb(Shortcuts: <Default Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#af347(Shortcuts) + └─Child 1: FocusNode#af347(Shortcuts: <Web Disabling Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE └─Child 1: _FocusTraversalGroupNode#bf036(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#8e60c(Shortcuts) + └─Child 1: FocusNode#8e60c(Shortcuts: <Shortcut Registrar>) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#54bda │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#b6f31(Navigator Scope) │ context: FocusScope │ focusedChildren: FocusScopeNode#2df85(_ModalScopeState<dynamic> │ Focus Scope) └─Child 1: _FocusTraversalGroupNode#82ab3(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#4b8f5(Navigator) │ context: Focus └─Child 1: FocusScopeNode#2df85(_ModalScopeState<dynamic> Focus Scope) context: _FocusScopeWithExternalFocusNode ``` </details> ## 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]. - [ ] 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. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…r#11137) Roll Flutter from b31548feb941 to 1141b2bdce66 (56 revisions) flutter/flutter@b31548f...1141b2b 2026-02-27 maxime.pontoire@me.com flutter#182361 Fix delegate copy on plugins init (flutter/flutter#182362) 2026-02-27 engine-flutter-autoroll@skia.org Roll Dart SDK from 8b036b3e63cb to 1cdb7dfd913e (1 revision) (flutter/flutter#183004) 2026-02-27 vegorov@google.com Manual roll Dart SDK to 3.12.0-192.0.dev (flutter/flutter#182883) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from e2062707b0c0 to ed220c490eea (1 revision) (flutter/flutter#182992) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from e5aa1ab5c59c to e2062707b0c0 (3 revisions) (flutter/flutter#182989) 2026-02-27 oss@simonbinder.eu Linux build hooks: Read compiler config from CMakeCache.txt (flutter/flutter#181004) 2026-02-27 engine-flutter-autoroll@skia.org Roll ICU from a86a32e67b8d to 7971660ba630 (3 revisions) (flutter/flutter#182986) 2026-02-27 engine-flutter-autoroll@skia.org Roll Skia from 49c2de95384e to e5aa1ab5c59c (2 revisions) (flutter/flutter#182980) 2026-02-27 flar@google.com [Impeller] Remove shared rendering data from TextFrame (flutter/flutter#182886) 2026-02-27 robert.ancell@canonical.com Add fl_view_new_sized_to_content() (flutter/flutter#182924) 2026-02-27 737941+loic-sharma@users.noreply.github.com [Shortcuts] Improve focus node debug labels (flutter/flutter#181834) 2026-02-27 34871572+gmackall@users.noreply.github.com Add a cli flag for toggling HCPP use, and enable it (flutter/flutter#182516) 2026-02-27 nate.w5687@gmail.com `SizedBox.square()` (flutter/flutter#182731) 2026-02-27 1961493+harryterkelsen@users.noreply.github.com [web] Fix stack corruption in Skwasm and harden withStackScope API (flutter/flutter#182912) 2026-02-26 jason-simmons@users.noreply.github.com Roll zlib to 7eda07b1e067 (flutter/flutter#182692) 2026-02-26 bkonyi@google.com [ CI ] Don't crash analysis when ktlint isn't on PATH (flutter/flutter#181854) 2026-02-26 34871572+gmackall@users.noreply.github.com Add calls to await `flutterDriver.waitUntilFirstFrameRasterized()` for all `android_engine_test` screenshot tests (flutter/flutter#182961) 2026-02-26 engine-flutter-autoroll@skia.org Roll Skia from f44d7db68805 to 49c2de95384e (30 revisions) (flutter/flutter#182957) 2026-02-26 robert.ancell@canonical.com Support sending window constraints in metrics events (flutter/flutter#182921) 2026-02-26 34465683+rkishan516@users.noreply.github.com Reland: remove material in context_menu_controller_test, icon_test, list_wheel_scroll_view_test, media_query_test, platform_menu_bar_test (flutter/flutter#182891) 2026-02-26 116356835+AbdeMohlbi@users.noreply.github.com Remove some instances of useMaterial3: true (flutter/flutter#182944) 2026-02-26 serhatguler@hotmail.de [Impeller] Use bilinear filtering for non-uniform scaled text (flutter/flutter#182224) 2026-02-26 chingjun@google.com Add a ResidentCompilerFactory to create ResidentCompiler instances. (flutter/flutter#182930) 2026-02-26 chingjun@google.com Add a getter in run.dart to access use-application-binary flag. (flutter/flutter#182931) 2026-02-26 mdebbar@google.com [web] Roll Firefox to 148 (flutter/flutter#182859) 2026-02-26 engine-flutter-autoroll@skia.org Roll Packages from acd9adb to e1d0169 (8 revisions) (flutter/flutter#182946) 2026-02-26 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from XI0Ax7fbtYE4XKYAQ... to G1GwOdVt5bM7GjMSY... (flutter/flutter#182942) 2026-02-26 robert.ancell@canonical.com Add test for WindowPositioner.toString (flutter/flutter#182906) 2026-02-26 robert.ancell@canonical.com Remove unused function prototype (flutter/flutter#182915) 2026-02-26 ahmedsameha1@gmail.com Resolve inconsistency with SchedulerBinding.scheduleTask usage recomm… (flutter/flutter#182531) 2026-02-26 51901607+O-Hannonen@users.noreply.github.com Fix false positives for hit test misses in flutter_test (flutter/flutter#180856) 2026-02-26 116356835+AbdeMohlbi@users.noreply.github.com Replace an instance of flutter/engine with flutter/flutter (flutter/flutter#182655) 2026-02-26 146823759+brahim-guaali@users.noreply.github.com Use null-aware elements in widgets/routes.dart (flutter/flutter#181242) 2026-02-26 37593616+itsAdityaRathore@users.noreply.github.com Fix typos in method names across multiple files (flutter/flutter#182584) 2026-02-26 brunocorona.alcantar@gmail.com Fix RawAutocomplete crash when options are hidden (flutter/flutter#182785) 2026-02-26 flar@google.com Describe implications of tree-status and Google Testing for PRs (flutter/flutter#182916) 2026-02-26 ahmedsameha1@gmail.com Make sure that a StretchingOverscrollIndicator doesn't crash when it … (flutter/flutter#182499) 2026-02-26 srawlins@google.com framework: Use a super-parameter in several missed cases (flutter/flutter#182580) 2026-02-25 nate.w5687@gmail.com `WidgetStatesConstraint` as a mixin (flutter/flutter#181704) 2026-02-25 Rusino@users.noreply.github.com Paint the paragraph as a single image (flutter/flutter#181206) 2026-02-25 rmolivares@renzo-olivares.dev Remove `ExtendSelectionByPageIntent` (flutter/flutter#182642) 2026-02-25 34465683+rkishan516@users.noreply.github.com feat: add few required properties to test widgets app (flutter/flutter#182805) 2026-02-25 prbillingsley89@gmail.com Updates MenuAnchor to respect software keyboard (flutter/flutter#180975) 2026-02-25 jason-simmons@users.noreply.github.com Roll ImGui to v1.92.6-docking (flutter/flutter#182799) 2026-02-25 jason-simmons@users.noreply.github.com Roll GoogleTest to e9907112b472 (flutter/flutter#182795) 2026-02-25 Veselblu@yandex.ru Make positionInlineChildren assert much clearer (flutter/flutter#182093) ...
Problem
The
Shortcutswidget creates focus nodes to listen to key events. If yourShortcutsdon't work as expected, you can enabledebugFocusChangesto debug your app. However, the log for when aShortcutswidget handles a key event did not make it clear whichShortcutswidget handled the key event:Being able to distinguish
Shortcutswidgets is important as even a minimal Material app has 4Shortcutswidgets.Solution
This change updates the
Shortcutswidget to pass its debug label down to the focus node it creates. This improves focus logs to make it clearer whichShortcutshandled a key event:Before and after examples
Example log when a
Shortcutshandles a key event:Example focus tree for a minimal Material app:
Focus tree...
App:
Resulting focus tree before and after this change:
FocusManager#76dc7 │ primaryFocus: FocusScopeNode#553ee(Root Focus Scope [PRIMARY │ FOCUS]) └─rootScope: FocusScopeNode#553ee(Root Focus Scope [PRIMARY FOCUS]) │ PRIMARY FOCUS │ focusedChildren: FocusScopeNode#9bb6a(View Scope) └─Child 1: _FocusTraversalGroupNode#85c63(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#9bb6a(View Scope) │ context: _FocusScopeWithExternalFocusNode │ focusedChildren: FocusScopeNode#b6f31(Navigator Scope) - └─Child 1: FocusNode#bb974(Shortcuts) + └─Child 1: FocusNode#bb974(Shortcuts: <Default WidgetsApp Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#255fb(Shortcuts) + └─Child 1: FocusNode#255fb(Shortcuts: <Default Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#af347(Shortcuts) + └─Child 1: FocusNode#af347(Shortcuts: <Web Disabling Text Editing Shortcuts>) │ context: Focus │ NOT FOCUSABLE └─Child 1: _FocusTraversalGroupNode#bf036(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE - └─Child 1: FocusNode#8e60c(Shortcuts) + └─Child 1: FocusNode#8e60c(Shortcuts: <Shortcut Registrar>) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#54bda │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusScopeNode#b6f31(Navigator Scope) │ context: FocusScope │ focusedChildren: FocusScopeNode#2df85(_ModalScopeState<dynamic> │ Focus Scope) └─Child 1: _FocusTraversalGroupNode#82ab3(FocusTraversalGroup) │ context: Focus │ NOT FOCUSABLE └─Child 1: FocusNode#4b8f5(Navigator) │ context: Focus └─Child 1: FocusScopeNode#2df85(_ModalScopeState<dynamic> Focus Scope) context: _FocusScopeWithExternalFocusNodePre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.