Skip to content

PopupMenuButton Semantics expanded state does not update #183432

Description

@AhmedLSayed9

Steps to reproduce

  1. Run the sample code below.
  2. Open the Widget Inspector and observe the Semantics tree.
  3. Tap the PopupMenuButton to open the menu.
  4. Observe that the Semantics expanded state does not update to true.
  5. Perform a hot-reload to force a rebuild.
  6. Observe that the Semantics expanded state update properly to true.

Expected results

The Semantics's expanded property should properly update to true when the menu opens and back to false when it closes, so that screen readers can announce the current state.

Actual results

The _isMenuExpanded field is updated without calling setState(), so the Semantics(expanded: _isMenuExpanded) widget doesn't rebuild and the expanded state doesn't updates.

Code sample

Code sample
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('PopupMenuButton Semantics Bug')),
        body: Center(
          child: PopupMenuButton<String>(
            onSelected: (value) {},
            itemBuilder: (context) => const [
              PopupMenuItem(value: 'A', child: Text('Option A')),
              PopupMenuItem(value: 'B', child: Text('Option B')),
              PopupMenuItem(value: 'C', child: Text('Option C')),
            ],
            child: Container(
              height: 50,
              width: 200,
              color: Colors.blue,
              alignment: Alignment.center,
              child: Text('Popup button'),
            ),
          ),
        ),
      ),
    );
  }
}

Screenshots or Video

Screenshots / Video demonstration
Screen.Recording.2026-03-10.at.6.10.17.AM.mp4

Root cause

_isMenuExpanded is updated without calling setState(), so the Semantics(expanded: _isMenuExpanded) widget never rebuilds.

PopupMenuButton:

  • showButtonMenu() sets _isMenuExpanded = true without setState()
  • The .then() callback sets _isMenuExpanded = false without setState()
  • Has no setState() call anywhere in PopupMenuButtonState, so expanded never updates at all

DropdownButton:

  • Has the same pattern — _handleTap() and _removeDropdownRoute() set _isMenuExpanded without setState()
  • Currently masked by _handleFocusChanged, which happens to call setState() whenever focus changes on open/close, but should still be fixed to not rely on this side effect

Flutter Doctor output

Doctor output
[✓] Flutter (Channel stable, 3.41.2, on macOS 26.3.1 25D2128 darwin-arm64, locale en-EG)
    • Flutter version 3.41.2 on channel stable
    • Framework revision 90673a4eef (3 weeks ago), 2026-02-18 13:54:59 -0800
    • Engine revision 6c0baaebf7
    • Dart version 3.11.0
    • DevTools version 2.54.1

[✓] Android toolchain - develop for Android devices (Android SDK version 36.0.0)
    • Platform android-36, build-tools 36.0.0
    • Java version OpenJDK Runtime Environment JBR-21.0.6+9-895.97-nomod (build 21.0.6+9-b895.97)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 26.3)
    • Build 17C529
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Connected device (3 available)

[✓] Network resources
    • All expected network resources are available.

• No issues found!

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)f: material designflutter/packages/flutter/material repository.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework teamwaiting for PR to land (fixed)A fix is in flight

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions