Skip to content

ensureSemantics() breaks Tap*Details emitted from GestureDetector on mouse click on web #188859

Closed

Description

@JaffaKetchup

Steps to reproduce

Run the code sample below on the web (specifically I'm running in Chrome on Windows). Click around the screen with your mouse. Remove/add the ensureSemantics() invocation if required for comparison.

This is causing fleaflet/flutter_map#2176. There are some similarities to #146063 which has been open for 2 years and linked to flutter-team-archive/engine#47360 which has been closed.

Expected results

The position should be accurate, as is without running ensureSemantics().

Actual results

The printed information does not change depending on the cursor position (the position is always the center of the screen). Note that the kind is "unknown" rather than mouse.

Code sample

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

void main() {
  runApp(const MyApp());
  SemanticsBinding.instance.ensureSemantics();
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: GestureDetector(
          onTapDown: print,
          child: const SizedBox.expand(
            child: ColoredBox(color: Colors.black),
          ),
        ),
      ),
    );
  }
}

Flutter Doctor output

Doctor output
[√] Flutter (Channel beta, 3.46.0-0.2.pre, on Microsoft Windows [Version 10.0.26220.8754], locale en-GB) [518ms]
    • Flutter version 3.46.0-0.2.pre on channel beta at C:\Users\lukas\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 0f5a2c4694 (5 days ago), 2026-06-25 22:15:21 -0700
    • Engine revision a24b1ea55d
    • Dart version 3.13.0 (build 3.13.0-167.1.beta)
    • DevTools version 2.59.0
    • Feature flags: enable-web, no-enable-linux-desktop, no-enable-macos-desktop, enable-windows-desktop, enable-android, enable-ios, cli-animations, enable-native-assets, enable-swift-package-manager, omit-legacy-version-file, enable-lldb-debugging,
      enable-uiscene-migration

[√] Windows Version (11 Home Insider Preview 64-bit, 25H2, 2009) [1,614ms]

[!] Android toolchain - develop for Android devices (Android SDK version 36.0.0-rc3) [3.4s]
    • Android SDK at C:\Users\lukas\AppData\Local\Android\sdk
    • Emulator version 35.2.10.0 (build_id 12414864) (CL:N/A)
    • Platform android-36, build-tools 36.0.0-rc3
    • Java binary at: C:\Program Files\Android\Android Studio\jbr\bin\java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.5+-13047016-b750.29)
    ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses

[√] Chrome - develop for the web [162ms]
    • CHROME_EXECUTABLE = C:\Program Files\Google\Chrome Dev\Application\chrome.exe

[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.14.13 (August 2025)) [162ms]
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.14.36414.22
    • Windows 10 SDK version 10.0.26100.0

[√] Connected device (3 available) [341ms]
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [Version 10.0.26220.8754]
    • Chrome (web)      • chrome  • web-javascript • unknown
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 150.0.4078.42

[√] Network resources [320ms]
    • All expected network resources are available.

! Doctor found issues in 1 category.

Activity

  1. changed the title [-]`ensureSemantics()` breaks `TapDownDetails` emitted from `GestureDetector` on mouse click on web[/-] [+]`ensureSemantics()` breaks `Tap*Details` emitted from `GestureDetector` on mouse click on web[/+] on Jul 1, 2026
  2. mbcorona commented on Jul 1, 2026

    @mbcorona
    Member

    Hi @JaffaKetchup , thanks for reporting and providing a code sample.
    This appears closely related to #146063 (and its duplicate #177314), which likely shares the same root cause in the web engine's semantics/pointer path

    Routing to the web team to evaluate.

  3. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    a: accessibilityAccessibility, e.g. VoiceOver or TalkBack. (aka a11y)
    platform-webWeb applications specifically
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    team-webOwned by Web platform team
    on Jul 1, 2026
  4. self-assigned this
    on Jul 1, 2026
  5. added
    triaged-webTriaged by Web platform team
    P1High-priority issues at the top of the work list
    on Jul 1, 2026
  6. removed their assignment
    on Aug 7, 2026
  7. removed
    P1High-priority issues at the top of the work list
    on Aug 7, 2026
  8. flutter-triage-bot commented on Aug 15, 2026

    @flutter-triage-bot

    This issue is missing a priority label. Please set a priority label when adding the triaged-web label.

  9. added
    P2Important issues not at the top of the work list
    triaged-webTriaged by Web platform team
    on Aug 19, 2026
  10. kevmoo commented on Oct 8, 2026

    @kevmoo
    Contributor

    Closing #192641 unmerged and leaving notes here so the investigation isn't lost.

    Why the PR approach doesn't work. The fix forwarded pointerType == 'mouse' input past ClickDebouncer. On Chrome that also captures every screen-reader activation: Blink's simulated_event_util.cc hardcodes pointerType = "mouse", pointerId = kMouseId, isTrusted = true, and border-box-center coordinates for SimulatedClickCreationScope::kFromAccessibility, and event_dispatcher.cc emits the full pointerdown → mousedown → pointerup → mouseup → click sequence. There is no DOM-level discriminator between a real mouse click and AT activation on Chrome. (WebKit is different: AccessibilityObject::press() emits mousedown/mouseup/click only, with pointerType = "" on the lone click, so the debouncer is never entered on Safari.) Net effect of the PR on Chrome: Semantics(onTap:) nodes without a gesture recognizer under their centroid stop responding to screen readers. Not acceptable.

    Design direction from review (@yjbanov): keep debouncing, and instead attach the pointer position (and ideally device kind) to SemanticsAction.tap so the framework can synthesize Tap*Details with the real coordinates. That's a cross-cutting change — new action args in dart:ui SemanticsAction, SemanticsOwner.performAction → tap-detail synthesis in the framework, and web_ui ClickDebouncer populating them from the queued pointerdown/pointerup — with a decision needed for what non-web platforms send. It's bigger than a bug fix and I'm not pursuing it right now.

    Independent observation worth keeping: the debouncer imposes ~200ms press latency on every flt-tappable node under ensureSemantics() for mouse users, on every browser. That's a latency issue rather than an a11y correctness issue and could be tracked separately if someone wants it.

    Possibly same root cause, not reproduced: #146063, #177314.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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)frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions