Repository: flutter
Issue: Unable to create idiomatic dropdown menus on desktop
Labels: framework,f: material design,a: quality,c: proposal,a: desktop,P3,team-framework,triaged-framework

I am trying to create dropdown menus for a desktop application, and have tried several different implementation paths but was unable to create a dropdown that behaves as desktop users would expect using any of them. I'll provide more specific examples later in the post, but in brief the methods I've tried are:

- The dropdown is a widget which overflows its parent
  - This causes [exhaustively discussed](https://github.com/flutter/flutter/issues/75747) issues with hit testing
- The dropdown is a widget inserted into an overlay
  - This places the dropdown very far from the dropdown's parent in the widget tree, even though semantically they are a tightly coupled child and parent. I'll expand on specific issues I couldn't resolve due to this later.
- The dropdown is a popup route
  - This places the dropdown even farther from its parent in the widget tree. It resolves some of the issues I had with the previous solution, but only by presenting some new ones.

This issue is *not* about the overflow/hit testing debate. This issue is meant to be about the difficulties of implementing a desktop dropdown in Flutter *given* that there is no solution for hit testing overflows.

### Overlay implementation

Some issues I ran into which I couldn't resolve are around the focus tree:
- Because the overlay entry gets inserted at a different point in the tree, any FocusNode attached above the dropdown's parent will think its subtree does not have focus while the focus is on the actual dropdown. This made it impossible to implement a behaviour where the dropdown closes when it loses focus, so that for example when using tab navigation you can tab past the dropdown and have it close automatically.
- It's impossible to force a correct focus traversal order when the ReadingOrderTraversalPolicy doesn't work correctly (which is common for dropdown layouts), because a WidgetOrderTraversalPolicy can't capture the contents of the overlay entry. Trying to use an OrderedTraversalPolicy would be impossible because it would need to be inserted above the Overlay in question, and would therefore require global coordination to make the ordering work out.

I haven't looked into proper maintenance of the semantics tree yet, but I assume that because the semantics tree is also a sparse subset of the widget tree it will have similar issues when a widget's semantic child is located far away in the actual tree.

### Popup route implementation

This resolves issues with focus traversal and semantics by restricting the focus and semantics tree to just the dropdown while it's open. But it causes other behaviour which is unidiomatic on desktop platforms:
- Tab navigation loops through the dropdown rather than moving on to the next node after the dropdown's parent. This is a particularly annoying issue for small dropdowns which open automatically when they are navigated to. The keyboard navigation flow goes from `tab tab tab tab` to `tab esc tab esc tab esc tab`.
- Exiting a nested dropdown by clicking behind it requires as many clicks as the nesting depth of the dropdown.

### Common issues

Both methods break any widgets implemented via InheritedWidget. Children of the dropdown would need to be explicitly passed the build context of the dropdown's parent.

I would love to hear what kind of workarounds people are using to implement idiomatic dropdowns on desktop platforms. My impression is that it's currently impossible since the dropdown can't be a child of its semantic parent in the actual widget tree without breaking hit testing, and this creates unresolvable issues.