Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
77b41ba8
Unverified
Commit
77b41ba8
authored
Aug 22, 2022
by
Greg Spencer
Committed by
GitHub
Aug 22, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove the FocusScopeNode in the navigator (#109702)
parent
d4eaf01a
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
97 additions
and
79 deletions
+97
-79
app.dart
packages/flutter/lib/src/widgets/app.dart
+18
-13
navigator.dart
packages/flutter/lib/src/widgets/navigator.dart
+30
-18
routes.dart
packages/flutter/lib/src/widgets/routes.dart
+5
-5
app_builder_test.dart
packages/flutter/test/material/app_builder_test.dart
+1
-1
debug_test.dart
packages/flutter/test/material/debug_test.dart
+8
-2
dropdown_test.dart
packages/flutter/test/material/dropdown_test.dart
+35
-40
No files found.
packages/flutter/lib/src/widgets/app.dart
View file @
77b41ba8
...
@@ -13,6 +13,7 @@ import 'banner.dart';
...
@@ -13,6 +13,7 @@ import 'banner.dart';
import
'basic.dart'
;
import
'basic.dart'
;
import
'binding.dart'
;
import
'binding.dart'
;
import
'default_text_editing_shortcuts.dart'
;
import
'default_text_editing_shortcuts.dart'
;
import
'focus_scope.dart'
;
import
'focus_traversal.dart'
;
import
'focus_traversal.dart'
;
import
'framework.dart'
;
import
'framework.dart'
;
import
'localizations.dart'
;
import
'localizations.dart'
;
...
@@ -1625,19 +1626,23 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
...
@@ -1625,19 +1626,23 @@ class _WidgetsAppState extends State<WidgetsApp> with WidgetsBindingObserver {
);
);
}
else
if
(
_usesNavigator
)
{
}
else
if
(
_usesNavigator
)
{
assert
(
_navigator
!=
null
);
assert
(
_navigator
!=
null
);
routing
=
Navigator
(
routing
=
FocusScope
(
restorationScopeId:
'nav'
,
debugLabel:
'Navigator Scope'
,
key:
_navigator
,
autofocus:
true
,
initialRoute:
_initialRouteName
,
child:
Navigator
(
onGenerateRoute:
_onGenerateRoute
,
restorationScopeId:
'nav'
,
onGenerateInitialRoutes:
widget
.
onGenerateInitialRoutes
==
null
key:
_navigator
,
?
Navigator
.
defaultGenerateInitialRoutes
initialRoute:
_initialRouteName
,
:
(
NavigatorState
navigator
,
String
initialRouteName
)
{
onGenerateRoute:
_onGenerateRoute
,
return
widget
.
onGenerateInitialRoutes
!(
initialRouteName
);
onGenerateInitialRoutes:
widget
.
onGenerateInitialRoutes
==
null
},
?
Navigator
.
defaultGenerateInitialRoutes
onUnknownRoute:
_onUnknownRoute
,
:
(
NavigatorState
navigator
,
String
initialRouteName
)
{
observers:
widget
.
navigatorObservers
!,
return
widget
.
onGenerateInitialRoutes
!(
initialRouteName
);
reportsRouteUpdateToEngine:
true
,
},
onUnknownRoute:
_onUnknownRoute
,
observers:
widget
.
navigatorObservers
!,
reportsRouteUpdateToEngine:
true
,
),
);
);
}
else
if
(
_usesRouterWithConfig
)
{
}
else
if
(
_usesRouterWithConfig
)
{
routing
=
Router
<
Object
>.
withConfig
(
routing
=
Router
<
Object
>.
withConfig
(
...
...
packages/flutter/lib/src/widgets/navigator.dart
View file @
77b41ba8
...
@@ -17,6 +17,7 @@ import 'basic.dart';
...
@@ -17,6 +17,7 @@ import 'basic.dart';
import
'binding.dart'
;
import
'binding.dart'
;
import
'focus_manager.dart'
;
import
'focus_manager.dart'
;
import
'focus_scope.dart'
;
import
'focus_scope.dart'
;
import
'focus_traversal.dart'
;
import
'framework.dart'
;
import
'framework.dart'
;
import
'heroes.dart'
;
import
'heroes.dart'
;
import
'overlay.dart'
;
import
'overlay.dart'
;
...
@@ -217,7 +218,7 @@ abstract class Route<T> {
...
@@ -217,7 +218,7 @@ abstract class Route<T> {
TickerFuture
didPush
()
{
TickerFuture
didPush
()
{
return
TickerFuture
.
complete
()..
then
<
void
>((
void
_
)
{
return
TickerFuture
.
complete
()..
then
<
void
>((
void
_
)
{
if
(
navigator
?.
widget
.
requestFocus
??
false
)
{
if
(
navigator
?.
widget
.
requestFocus
??
false
)
{
navigator
!.
focus
ScopeNode
.
requestFocus
();
navigator
!.
focus
Node
.
enclosingScope
?
.
requestFocus
();
}
}
});
});
}
}
...
@@ -233,11 +234,11 @@ abstract class Route<T> {
...
@@ -233,11 +234,11 @@ abstract class Route<T> {
@mustCallSuper
@mustCallSuper
void
didAdd
()
{
void
didAdd
()
{
if
(
navigator
?.
widget
.
requestFocus
??
false
)
{
if
(
navigator
?.
widget
.
requestFocus
??
false
)
{
// This TickerFuture serves two purposes. First, we want to make sure
// This TickerFuture serves two purposes. First, we want to make sure
that
//
that animations triggered by other operations will finish before focusing the
//
animations triggered by other operations will finish before focusing
//
navigator. Second, navigator.focusScope
Node might acquire more focused
//
the navigator. Second, navigator.focus
Node might acquire more focused
// children in Route.install asynchronously. This TickerFuture will wait
for
// children in Route.install asynchronously. This TickerFuture will wait
// it to finish first.
//
for
it to finish first.
//
//
// The later case can be found when subclasses manage their own focus scopes.
// The later case can be found when subclasses manage their own focus scopes.
// For example, ModalRoute creates a focus scope in its overlay entries. The
// For example, ModalRoute creates a focus scope in its overlay entries. The
...
@@ -255,7 +256,7 @@ abstract class Route<T> {
...
@@ -255,7 +256,7 @@ abstract class Route<T> {
// Since the reference to the navigator will be set to null after it is
// Since the reference to the navigator will be set to null after it is
// disposed, we have to do a null-safe operation in case that happens
// disposed, we have to do a null-safe operation in case that happens
// within the same frame when it is added.
// within the same frame when it is added.
navigator
?.
focus
ScopeNode
.
requestFocus
();
navigator
?.
focus
Node
.
enclosingScope
?
.
requestFocus
();
});
});
}
}
}
}
...
@@ -3207,8 +3208,15 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
...
@@ -3207,8 +3208,15 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
final
Queue
<
_NavigatorObservation
>
_observedRouteAdditions
=
Queue
<
_NavigatorObservation
>();
final
Queue
<
_NavigatorObservation
>
_observedRouteAdditions
=
Queue
<
_NavigatorObservation
>();
final
Queue
<
_NavigatorObservation
>
_observedRouteDeletions
=
Queue
<
_NavigatorObservation
>();
final
Queue
<
_NavigatorObservation
>
_observedRouteDeletions
=
Queue
<
_NavigatorObservation
>();
/// The [FocusScopeNode] for the [FocusScope] that encloses the routes.
/// The [FocusScopeNode] for the [FocusScope] that encloses the topmost navigator.
final
FocusScopeNode
focusScopeNode
=
FocusScopeNode
(
debugLabel:
'Navigator Scope'
);
@Deprecated
(
'Use focusNode.enclosingScope! instead. '
'This feature was deprecated after v3.1.0-0.0.pre.'
)
FocusScopeNode
get
focusScopeNode
=>
focusNode
.
enclosingScope
!;
/// The [FocusNode] for the [Focus] that encloses the routes.
final
FocusNode
focusNode
=
FocusNode
(
debugLabel:
'Navigator'
);
bool
_debugLocked
=
false
;
// used to prevent re-entrant calls to push, pop, and friends
bool
_debugLocked
=
false
;
// used to prevent re-entrant calls to push, pop, and friends
...
@@ -3531,7 +3539,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
...
@@ -3531,7 +3539,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
return
true
;
return
true
;
}());
}());
_updateHeroController
(
null
);
_updateHeroController
(
null
);
focus
Scope
Node
.
dispose
();
focusNode
.
dispose
();
for
(
final
_RouteEntry
entry
in
_history
)
{
for
(
final
_RouteEntry
entry
in
_history
)
{
entry
.
dispose
();
entry
.
dispose
();
}
}
...
@@ -5226,14 +5234,18 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
...
@@ -5226,14 +5234,18 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
onPointerCancel:
_handlePointerUpOrCancel
,
onPointerCancel:
_handlePointerUpOrCancel
,
child:
AbsorbPointer
(
child:
AbsorbPointer
(
absorbing:
false
,
// it's mutated directly by _cancelActivePointers above
absorbing:
false
,
// it's mutated directly by _cancelActivePointers above
child:
FocusScope
(
child:
FocusTraversalGroup
(
node:
focusScopeNode
,
child:
Focus
(
autofocus:
true
,
focusNode:
focusNode
,
child:
UnmanagedRestorationScope
(
autofocus:
true
,
bucket:
bucket
,
skipTraversal:
true
,
child:
Overlay
(
includeSemantics:
false
,
key:
_overlayKey
,
child:
UnmanagedRestorationScope
(
initialEntries:
overlay
==
null
?
_allRouteOverlayEntries
.
toList
(
growable:
false
)
:
const
<
OverlayEntry
>[],
bucket:
bucket
,
child:
Overlay
(
key:
_overlayKey
,
initialEntries:
overlay
==
null
?
_allRouteOverlayEntries
.
toList
(
growable:
false
)
:
const
<
OverlayEntry
>[],
),
),
),
),
),
),
),
...
...
packages/flutter/lib/src/widgets/routes.dart
View file @
77b41ba8
...
@@ -819,7 +819,7 @@ class _ModalScopeState<T> extends State<_ModalScope<T>> {
...
@@ -819,7 +819,7 @@ class _ModalScopeState<T> extends State<_ModalScope<T>> {
];
];
_listenable
=
Listenable
.
merge
(
animations
);
_listenable
=
Listenable
.
merge
(
animations
);
if
(
widget
.
route
.
isCurrent
&&
_shouldRequestFocus
)
{
if
(
widget
.
route
.
isCurrent
&&
_shouldRequestFocus
)
{
widget
.
route
.
navigator
!.
focus
ScopeNode
.
setFirstFocus
(
focusScopeNode
);
widget
.
route
.
navigator
!.
focus
Node
.
enclosingScope
?
.
setFirstFocus
(
focusScopeNode
);
}
}
}
}
...
@@ -828,7 +828,7 @@ class _ModalScopeState<T> extends State<_ModalScope<T>> {
...
@@ -828,7 +828,7 @@ class _ModalScopeState<T> extends State<_ModalScope<T>> {
super
.
didUpdateWidget
(
oldWidget
);
super
.
didUpdateWidget
(
oldWidget
);
assert
(
widget
.
route
==
oldWidget
.
route
);
assert
(
widget
.
route
==
oldWidget
.
route
);
if
(
widget
.
route
.
isCurrent
&&
_shouldRequestFocus
)
{
if
(
widget
.
route
.
isCurrent
&&
_shouldRequestFocus
)
{
widget
.
route
.
navigator
!.
focus
ScopeNode
.
setFirstFocus
(
focusScopeNode
);
widget
.
route
.
navigator
!.
focus
Node
.
enclosingScope
?
.
setFirstFocus
(
focusScopeNode
);
}
}
}
}
...
@@ -863,7 +863,7 @@ class _ModalScopeState<T> extends State<_ModalScope<T>> {
...
@@ -863,7 +863,7 @@ class _ModalScopeState<T> extends State<_ModalScope<T>> {
// and route.offstage.
// and route.offstage.
void
_routeSetState
(
VoidCallback
fn
)
{
void
_routeSetState
(
VoidCallback
fn
)
{
if
(
widget
.
route
.
isCurrent
&&
!
_shouldIgnoreFocusRequest
&&
_shouldRequestFocus
)
{
if
(
widget
.
route
.
isCurrent
&&
!
_shouldIgnoreFocusRequest
&&
_shouldRequestFocus
)
{
widget
.
route
.
navigator
!.
focus
ScopeNode
.
setFirstFocus
(
focusScopeNode
);
widget
.
route
.
navigator
!.
focus
Node
.
enclosingScope
?
.
setFirstFocus
(
focusScopeNode
);
}
}
setState
(
fn
);
setState
(
fn
);
}
}
...
@@ -1213,7 +1213,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
...
@@ -1213,7 +1213,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
@override
@override
TickerFuture
didPush
()
{
TickerFuture
didPush
()
{
if
(
_scopeKey
.
currentState
!=
null
&&
navigator
!.
widget
.
requestFocus
)
{
if
(
_scopeKey
.
currentState
!=
null
&&
navigator
!.
widget
.
requestFocus
)
{
navigator
!.
focus
ScopeNode
.
setFirstFocus
(
_scopeKey
.
currentState
!.
focusScopeNode
);
navigator
!.
focus
Node
.
enclosingScope
?
.
setFirstFocus
(
_scopeKey
.
currentState
!.
focusScopeNode
);
}
}
return
super
.
didPush
();
return
super
.
didPush
();
}
}
...
@@ -1221,7 +1221,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
...
@@ -1221,7 +1221,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
@override
@override
void
didAdd
()
{
void
didAdd
()
{
if
(
_scopeKey
.
currentState
!=
null
&&
navigator
!.
widget
.
requestFocus
)
{
if
(
_scopeKey
.
currentState
!=
null
&&
navigator
!.
widget
.
requestFocus
)
{
navigator
!.
focus
ScopeNode
.
setFirstFocus
(
_scopeKey
.
currentState
!.
focusScopeNode
);
navigator
!.
focus
Node
.
enclosingScope
?
.
setFirstFocus
(
_scopeKey
.
currentState
!.
focusScopeNode
);
}
}
super
.
didAdd
();
super
.
didAdd
();
}
}
...
...
packages/flutter/test/material/app_builder_test.dart
View file @
77b41ba8
...
@@ -17,7 +17,7 @@ void main() {
...
@@ -17,7 +17,7 @@ void main() {
log
.
add
(
'build'
);
log
.
add
(
'build'
);
expect
(
Theme
.
of
(
context
).
primaryColor
,
Colors
.
green
);
expect
(
Theme
.
of
(
context
).
primaryColor
,
Colors
.
green
);
expect
(
Directionality
.
of
(
context
),
TextDirection
.
ltr
);
expect
(
Directionality
.
of
(
context
),
TextDirection
.
ltr
);
expect
(
child
,
isA
<
Navigator
>());
expect
(
child
,
isA
<
FocusScope
>());
return
const
Placeholder
();
return
const
Placeholder
();
},
},
);
);
...
...
packages/flutter/test/material/debug_test.dart
View file @
77b41ba8
...
@@ -156,12 +156,18 @@ void main() {
...
@@ -156,12 +156,18 @@ void main() {
' Overlay-[LabeledGlobalKey<OverlayState>#00000]
\n
'
' Overlay-[LabeledGlobalKey<OverlayState>#00000]
\n
'
' UnmanagedRestorationScope
\n
'
' UnmanagedRestorationScope
\n
'
' _FocusMarker
\n
'
' _FocusMarker
\n
'
' Semantics
\n
'
' Focus
\n
'
' FocusScope
\n
'
' _FocusMarker
\n
'
' Focus
\n
'
' _FocusTraversalGroupMarker
\n
'
' FocusTraversalGroup
\n
'
' AbsorbPointer
\n
'
' AbsorbPointer
\n
'
' Listener
\n
'
' Listener
\n
'
' HeroControllerScope
\n
'
' HeroControllerScope
\n
'
' Navigator-[GlobalObjectKey<NavigatorState> _WidgetsAppState#00000]
\n
'
' Navigator-[GlobalObjectKey<NavigatorState> _WidgetsAppState#00000]
\n
'
' _FocusMarker
\n
'
' Semantics
\n
'
' FocusScope
\n
'
' DefaultSelectionStyle
\n
'
' DefaultSelectionStyle
\n
'
' IconTheme
\n
'
' IconTheme
\n
'
' IconTheme
\n
'
' IconTheme
\n
'
...
...
packages/flutter/test/material/dropdown_test.dart
View file @
77b41ba8
...
@@ -1326,53 +1326,49 @@ void main() {
...
@@ -1326,53 +1326,49 @@ void main() {
TestSemantics
.
rootChild
(
TestSemantics
.
rootChild
(
children:
<
TestSemantics
>[
children:
<
TestSemantics
>[
TestSemantics
(
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
scopesRoute
,
SemanticsFlag
.
namesRoute
,
],
label:
'Popup menu'
,
children:
<
TestSemantics
>[
children:
<
TestSemantics
>[
TestSemantics
(
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
scopesRoute
,
SemanticsFlag
.
namesRoute
,
],
label:
'Popup menu'
,
children:
<
TestSemantics
>[
children:
<
TestSemantics
>[
TestSemantics
(
TestSemantics
(
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
hasImplicitScrolling
,
],
children:
<
TestSemantics
>[
children:
<
TestSemantics
>[
TestSemantics
(
TestSemantics
(
label:
'one'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
hasImplicitScrolling
,
SemanticsFlag
.
isFocused
,
],
SemanticsFlag
.
isFocusable
,
children:
<
TestSemantics
>[
TestSemantics
(
label:
'one'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isFocused
,
SemanticsFlag
.
isFocusable
,
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
TestSemantics
(
label:
'two'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isFocusable
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
TestSemantics
(
label:
'three'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isFocusable
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
TestSemantics
(
label:
'four'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isFocusable
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
],
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
TestSemantics
(
label:
'two'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isFocusable
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
TestSemantics
(
label:
'three'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isFocusable
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
TestSemantics
(
label:
'four'
,
textDirection:
TextDirection
.
ltr
,
flags:
<
SemanticsFlag
>[
SemanticsFlag
.
isFocusable
],
tags:
<
SemanticsTag
>[
const
SemanticsTag
(
'RenderViewport.twoPane'
)],
actions:
<
SemanticsAction
>[
SemanticsAction
.
tap
],
),
),
],
],
),
),
...
@@ -1380,7 +1376,6 @@ void main() {
...
@@ -1380,7 +1376,6 @@ void main() {
),
),
],
],
),
),
TestSemantics
(),
],
],
),
),
],
],
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment