Skip to content

[go_router] Fix SelectionArea dead zones after ShellRoute navigation#11062

Open
davidmigloz wants to merge 2 commits intoflutter:mainfrom
davidmigloz:fix-selection-dead-zones
Open

[go_router] Fix SelectionArea dead zones after ShellRoute navigation#11062
davidmigloz wants to merge 2 commits intoflutter:mainfrom
davidmigloz:fix-selection-dead-zones

Conversation

@davidmigloz
Copy link
Contributor

Description

When a SelectionArea wraps a ShellRoute's child (a common pattern for enabling text selection across an app), offstage pages kept their Text widgets registered with the SelectableRegion. These invisible selectables intercepted drag-to-select events, creating "dead zones" on the currently visible page where selection silently failed.

Fix

ShellRoute: Adds _OffstageSelectionDisabler — a lightweight widget inserted around each route's content that detects non-current routes via ModalRoute.of(context) and wraps them with SelectionContainer.disabled to unregister their selectables.

StatefulShellRoute: Wraps inactive branches with SelectionContainer.disabled in _IndexedStackedRouteBranchContainer._buildRouteBranchContainer. Navigator state is preserved via GlobalObjectKey reparenting.

Reproduction

Fixes flutter/flutter#182573

Tests

Added 12 new widget tests in builder_test.dart covering:

  • ShellRoute: builder, pageBuilder, back navigation, deep linking, 3+ level nesting, CustomTransitionPage, pop navigation
  • StatefulShellRoute: branch selection toggle, navigator state preservation, composition with route-level disabling

When a SelectionArea wraps a ShellRoute's child (e.g. in a Scaffold body),
offstage pages kept their Text widgets registered with the SelectableRegion.
These invisible selectables intercepted drag-to-select events, creating
dead zones on the active page.

For ShellRoute: adds _OffstageSelectionDisabler that detects non-current
routes via ModalRoute.of(context) and wraps them with
SelectionContainer.disabled.

For StatefulShellRoute: wraps inactive branches with
SelectionContainer.disabled in _IndexedStackedRouteBranchContainer.

Fixes flutter/flutter#182573
@github-actions github-actions bot added p: go_router triage-framework Should be looked at in framework triage labels Feb 18, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The pull request successfully addresses the issue of text selection "dead zones" by disabling selection for offstage routes. However, the current implementation of conditionally wrapping widgets with SelectionContainer.disabled or _OffstageSelectionDisabler will cause the entire subtree (including Navigators and their pages) to be unmounted and remounted whenever a route's visibility changes. This leads to a complete loss of state (e.g., scroll positions, text field contents) for those routes. I have suggested an alternative approach that toggles the registrar property of a persistent SelectionContainer to maintain the widget tree structure and preserve state.

- Convert _OffstageSelectionDisabler to StatefulWidget with GlobalKey-based
  reparenting to preserve descendant State across tree structure changes
- Add _SelectionGuard StatefulWidget in route.dart for StatefulShellRoute
  branch containers with the same GlobalKey preservation pattern
- Fix type parameter mismatch: try both <dynamic> and <void> in
  _addSelectionGuardToPage so user pageBuilder pages (which default to
  <dynamic>) get the selection guard applied
- Switch to pending_changelogs/ instead of direct CHANGELOG.md/pubspec.yaml
  edits (revert version back to 17.1.0)
- Fix omit_obvious_local_variable_types lint in 3 test declarations
- Add 4 new tests: state preservation for ShellRoute and
  StatefulShellRoute, and <dynamic> type parameter coverage for
  NoTransitionPage and CustomTransitionPage
@davidmigloz davidmigloz requested a review from chunhtai February 18, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p: go_router triage-framework Should be looked at in framework triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[go_router] SelectionArea dead zones after ShellRoute navigation — offstage page selectables intercept drag events

2 participants

Comments