Skip to content

☔️ Automatic Pointer Interceptors for Platform Views on Web #190574

Open
1 of 2 issues completed
Open

Description

@harryterkelsen

Background

Because of how pointer events are handled by the browser when interacting with platform views (HtmlElementView), Flutter web apps currently rely on the PointerInterceptor widget (from package:pointer_interceptor) when Flutter UI overlaps a platform view.

Developers must manually wrap widgets such as ModalBarrier, ListView, menus, or navigation drawers in a PointerInterceptor to prevent an underlying platform view (especially <iframe>s, maps, or video) from swallowing pointer events (see #144354 and #93887). In large apps, tracking every widget that might paint above a platform view is error-prone and does not scale.

The Solution

Instead of requiring manual widget wrapping, we are building Automatic Pointer Interception across the Flutter framework and Web Engine (RFC: flutter/rfc#39, tracked in #179806):

  1. Platform-View-Gated Hit-Region Pass (packages/flutter): After compositing each frame on the web, PipelineOwner.flushHitTestRegions walks render objects in paint order (visitChildrenInPaintOrder)—gated so it runs only when at least one platform view is attached (zero overhead for apps or screens without platform views) and skips platform-view-free subtrees via a subtree count index. Render objects describe their own hit-testing behavior via hitTestsChildren, hitTestsChildrenOutsideBounds, and visitHitTestRegions without hard-coded widget lists.
  2. Per-View Region Delivery (dart:ui): The framework dispatches paint-ordered groups of physical-pixel rects per view via FlutterView.updateHitTestRegions(Float64List), synchronized with frame scene rendering.
  3. Web Engine Hit-Test Proxies (lib/web_ui): During scene composition, PlatformViewEmbedder interleaves <flt-hit-test-proxy> groups immediately after each platform view's DOM slot. Because DOM order matches Flutter paint order, an overlay barrier blocks a background platform view without blocking a second platform view rendered inside a foreground dialog. Intercepted browser events bubble naturally to the view root's PointerBinding.
  4. Pointer Capture Across <iframe>s: Active pointer drags originating on Flutter content or hit-test proxies capture the pointer on <flutter-view> ([web] Capture pointers to the Flutter view so drags survive platform view iframes #195187) so mouse and stylus drags are not swallowed mid-gesture when crossing an <iframe>.

(Note: This supersedes the framework-level proposals in #144354 and #93887, as well as the initial "No-DOM Semantics" prototype in #190576, which was dropped after benchmarking showed 30–100% drawFrameDuration regressions from running flushSemantics by default and semantics coverage gaps on desktop ModalBarriers.)

Roadmap

Activity

  1. added
    c: new featureNothing broken; request for a new capability
    c: proposalA detailed proposal for a change to Flutter
    frameworkflutter/packages/flutter repository. See also f: labels.
    P1High-priority issues at the top of the work list
    team-webOwned by Web platform team
    triaged-webTriaged by Web platform team
    on Aug 4, 2026
  2. changed the title [-][Umbrella] Automatic Pointer Interceptors for Platform Views on Web[/-] [+]☔️ Automatic Pointer Interceptors for Platform Views on Web[/+] on Aug 4, 2026
  3. harryterkelsen commented on Oct 28, 2026

    @harryterkelsen
    ContributorAuthor

    Update on architecture and implementation roadmap:

    We've completed performance benchmarking of the initial "No-DOM Semantics" prototype (sub-issue #190576) and found that enabling framework semantics by default introduces a 30–100% drawFrameDuration regression across widget-heavy benchmarks, alongside accessibility edge cases where ModalBarrier is omitted on desktop platforms. Consequently, #190576 has been closed and the semantics-by-default approach has been dropped.

    Instead, we are proceeding with a dedicated, platform-view-gated hit-region pass:

    1. Framework Hit-Region Pass: An opt-in pass (PipelineOwner.flushHitTestRegions) that walks render objects in paint order only when platform views are active, generating hit-test rects for widgets painted above platform views.
    2. Web Engine Hit-Test Proxies: The framework dispatches rects per-view via FlutterView.updateHitTestRegions, and the Web Engine interleaves <flt-hit-test-proxy> elements with platform views in <flt-scene> to route browser pointer events back to the Flutter view.
    3. Pointer Capture: Pointer capture to <flutter-view> landed in [web] Capture pointers to the Flutter view so drags survive platform view iframes #195187 to ensure drags survive over <iframe> platform views.

    Implementation of the hit-region pass and proxies is staged in draft PRs and being prepared for upstream review. Sub-issue #190577 will be updated to reflect the new hit-region integration.

  4. harryterkelsen commented on Oct 29, 2026

    @harryterkelsen
    ContributorAuthor

    The design, and the alternatives we considered (inlining pointer_interceptor, semantics, and recording regions during paint), are now written up as an RFC: flutter/rfc#39 (tracked in #179806)

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

Metadata

Metadata

Labels

P1High-priority issues at the top of the work listc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Fluttercustomer: acdccustomer: googleVarious Google teamsframeworkflutter/packages/flutter repository. See also f: labels.team-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