Skip to content

bug: M3 Dropdown on_select not fired on rapid consecutive selections (Web/CanvasKit) #6766

Description

@shi00

Duplicate Check


Describe the bug

ft.Dropdown (Material 3) on_select event is not fired when a menu option is selected immediately after a previous selection on the same control, in the Web/CanvasKit runtime. The first selection fires on_select normally, but a rapid second selection is silently dropped. Waiting a few seconds before the next selection makes on_select fire again. ft.DropdownM2 (on_change-based) does not exhibit this behavior and fires on every selection.


Code sample

Code ```python """Minimal reproduction: M3 ``ft.Dropdown`` ``on_select`` not fired on rapid consecutive selections.

How to reproduce (Web / CanvasKit, e.g. Chrome):
1. Run: python m3_dropdown_on_select_repro.py
2. In the opened browser page, click the dropdown and select "ERROR".
-> "on_select: ERROR" is appended to the event log.
3. Immediately click the dropdown again and select "DEBUG".
-> Expected: "on_select: DEBUG" | Actual: it is MISSING (the log still shows only ERROR).
4. Wait ~5s, then click the dropdown again and select "INFO".
-> "on_select: INFO" IS appended (menu state settled).

The same rapid second selection works fine with ft.DropdownM2 (on_change-based),
so this is specific to the Material 3 DropdownMenu event delivery in Web/CanvasKit.
"""

import logging

import flet as ft

logging.basicConfig(level=logging.INFO)

def main(page: ft.Page) -> None:
page.title = "M3 Dropdown on_select repro"
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER

event_log = ft.Column()

def log_evt(msg: str) -> None:
    logging.info(msg)
    event_log.controls.append(ft.Text(msg))
    page.update()

def on_select(e: ft.ControlEvent) -> None:
    log_evt(f"on_select: {getattr(e.control, 'value', None)}")

def on_change(e: ft.ControlEvent) -> None:
    log_evt(f"on_change: {getattr(e.control, 'value', None)}")

dropdown_m3 = ft.Dropdown(
    label="Log level (M3, on_select)",
    options=[
        ft.dropdown.Option("ERROR", "错误 (ERROR)"),
        ft.dropdown.Option("DEBUG", "调试 (DEBUG)"),
        ft.dropdown.Option("INFO", "报告 (INFO)"),
    ],
    on_select=on_select,  # M3: on_select never fires for the 2nd rapid selection
)

dropdown_m2 = ft.DropdownM2(
    label="Log level (M2, on_change)",
    options=[
        ft.dropdown.Option("ERROR", "错误 (ERROR)"),
        ft.dropdown.Option("DEBUG", "调试 (DEBUG)"),
        ft.dropdown.Option("INFO", "报告 (INFO)"),
    ],
    on_change=on_change,  # M2: on_change fires reliably on every selection
)

page.add(
    ft.Text("Reproduce: select ERROR, then immediately select DEBUG in the same M3 dropdown."),
    dropdown_m3,
    dropdown_m2,
    ft.Divider(),
    ft.Text("Event log:"),
    event_log,
)

ft.app(main)

</details>

---

**To reproduce**

1. Run the repro code: `python m3_dropdown_on_select_repro.py`
2. The app opens in the default browser (Web/CanvasKit).
3. Click the M3 dropdown ("Log level (M3, on_select)") and select "ERROR".
   - The event log shows `on_select: ERROR`.
4. Immediately click the same dropdown again and select "DEBUG".
   - Expected: `on_select: DEBUG` is appended.
   - Actual: nothing is appended (the second `on_select` is dropped).
5. Wait ~5 seconds, then click the same dropdown and select "INFO".
   - `on_select: INFO` IS appended.

---

**Expected behavior**

`on_select` should fire for every user selection, including rapid consecutive selections on the same dropdown.

---

**Screenshots / Videos**

<details open>
<summary>Captures</summary>
[Upload media here]
</details>

---

**Operating System**

Windows

---

**Operating system details**

Windows Server 2022 (GitHub Actions windows-latest); reproducible in Chrome latest.

---

**Flet version**

0.86.3 (flet-desktop 0.86.3)

---

**Regression**

No, it isn't

---

**Suggestions**

The M3 `DropdownMenu`/`MenuAnchor` event delivery in Web/CanvasKit appears to drop the selection event when the menu is reopened before the previous menu's teardown/animation completes. Please ensure the menu fully closes before the next selection event is accepted, or fire `on_select` based on the committed value change.

---

**Logs**

<details open><summary>Logs</summary>
```console
[Paste your logs here]

Additional details

Also reproduced in a real application: an E2E test that selects option A then immediately option B on the same ft.Dropdown intermittently never receives the second on_select event (the corresponding UI_ACTION log for the second selection is missing). ft.DropdownM2 with on_change works reliably in the same scenario.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions