Description
Copied from Google internal issue b/374241149. See this issue for more context, links, and repro video.
Unable to dismiss the popup menu by double tapping outside the menu in voice over mode in specific iOS devices.
PopupMenuButton pushes _PopupMenuRoute which extends PopupRoute which extends ModalRoute which uses for rendering the scrim.
The double tap to dismiss is handled by the ModalBarrier by calling Navigator.maybePop().
Issue: This particular call is getting stuck in some iPhones (Example: My test device is an iPhone XR with iOS version 15.5). I tested this in the Hello Flutter codelab app.
Upon further debugging, its getting stuck at exactly await lastEntry.route.willPop()
.
lastEntry.route here is _PopupMenuRoute.
Tracing the willPop() implementations using debug print statements, I observed the following:
- _PopupMenuRoute does not have willPop() implementation.
- PopupRoute does not have willPop() implementation.
- ModalRoute's willPop() completes and calls super.willPop().
- LocalHistoryRoute's willPop() completes and calls super.willPop().
- ... no other implementations of willPop() in between.
- Route's willPop() is called.
- But apparently the last call is getting stuck for some reason because
await lastEntry.route.willPop()
is stuck without a return value here:
Repro project
The bug can be reproduced in any flutter app with the following:
PopupMenuButton<int>(
// Set tooltip to empty to prevent the screen reader announcing
// 'show menu'.
tooltip: '',
itemBuilder: (context) {
return [
PopupMenuItem<int>(
value: 1,
child: Text('Item 1'),
),
PopupMenuItem<int>(
value: 2,
child: Text('Item 2'),
),
PopupMenuItem<int>(
value: 3,
child: Text('Item 3'),
),
];
},
),