Skip to content

[152588] Fix Scrollable being too eager to respond to pointer signals#183302

Merged
auto-submit[bot] merged 5 commits intoflutter:masterfrom
O-Hannonen:152588-fix-scrollable-too-eager-response-to-pointer-signals
Mar 19, 2026
Merged

[152588] Fix Scrollable being too eager to respond to pointer signals#183302
auto-submit[bot] merged 5 commits intoflutter:masterfrom
O-Hannonen:152588-fix-scrollable-too-eager-response-to-pointer-signals

Conversation

@O-Hannonen
Copy link
Contributor

@O-Hannonen O-Hannonen commented Mar 6, 2026

This PR

Some history and reasoning

Root cause

The bug was introduced in PR #145500, which fixed issue #139263 by ensuring that the Web engine knows when a scroll event is not handled by Flutter. This allows the browser to perform default actions like page scrolling or back/forward navigation. Without this, Flutter might "swallow" events it doesn't use, leading to a "dead" feel on the web.

Why reverting is safe and won't regress Issue #139263

Reverting the manual respond(true) calls in Scrollable is safe because PointerSignalResolver (the centralized mediator for these events) already has the logic to notify the engine. More specifically, PointerSignalResolver.resolve calls event.respond(allowPlatformDefault: true) if and only if no widget in the hit-test tree registered interest in the event.

Moving this responsibility back to the PointerSignalResolver ensures that:

  1. If any widget handles the event: It registers with the resolver, and respond(true) is not called.
  2. If no widget handles the event: No one registers, and the resolver calls respond(true) at the end of the dispatch cycle.

The current bug exists because Scrollable was trying to be too helpful by calling respond(true) based only on its local state, which overrides any handling done by other widgets in the hierarchy.

Testing and verifying

A new regression test was created that highlight how the respond calls should work in nested Scrollable elements.

The "fallback" nature of PointerSignalResolver is already

  1. documented in pointer_signal_resolver.dart:
  void resolve(PointerSignalEvent event) {
    if (_firstRegisteredCallback == null) {
      assert(_currentEvent == null);
      // Nothing in the framework/app wants to handle the `event`. Allow the
      // platform to trigger any default native actions.
      event.respond(allowPlatformDefault: true);
      return;
    }
    // ... handles the registered callback ...
  }
  1. tested in pointer_signal_resolver_test.dart:
  test('Resolving with no entries should notify engine of no-op', () {
    var allowedPlatformDefault = false;
    final tester = PointerSignalTester();
    tester.event = PointerScrollEvent(
      onRespond: ({required bool allowPlatformDefault}) {
        allowedPlatformDefault = allowPlatformDefault;
      },
    );
    tester.resolver.resolve(tester.event);
    expect(
      allowedPlatformDefault,
      isTrue,
      reason: 'Should have called respond with allowPlatformDefault: true',
    );
  });

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Mar 6, 2026
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies the Scrollable widget's handling of pointer signals. The changes remove explicit calls to event.respond(allowPlatformDefault: true), which previously indicated that a pointer event was not handled. This responsibility is now fully delegated to the PointerSignalResolver. A new regression test is included to verify the corrected behavior in a nested scrollable scenario, ensuring events are correctly propagated and handled within the widget hierarchy.

Note: Security Review is unavailable for this PR.

@justinmc justinmc requested a review from Piinks March 10, 2026 22:34
Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this!

@O-Hannonen O-Hannonen requested a review from Piinks March 12, 2026 11:16
@Piinks Piinks added the CICD Run CI/CD label Mar 12, 2026
Piinks
Piinks previously approved these changes Mar 12, 2026
Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM, thank you again!

@Piinks Piinks added autosubmit Merge PR when tree becomes green via auto submit App and removed autosubmit Merge PR when tree becomes green via auto submit App labels Mar 12, 2026
@AbdeMohlbi AbdeMohlbi self-requested a review March 12, 2026 16:31
AbdeMohlbi
AbdeMohlbi previously approved these changes Mar 12, 2026
Copy link
Contributor

@AbdeMohlbi AbdeMohlbi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Piinks Piinks added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 12, 2026
@Piinks
Copy link
Contributor

Piinks commented Mar 17, 2026

Hey @O-Hannonen it looks like this ran into an issue with testing, can you rebase with the tip of tree?

@O-Hannonen O-Hannonen requested review from a team and jtmcdole as code owners March 18, 2026 16:03
@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems c: contributor-productivity Team-specific productivity, code health, technical debt. platform-android Android applications specifically platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. engine flutter/engine related. See also e: labels. f: material design flutter/packages/flutter/material repository. f: cupertino flutter/packages/flutter/cupertino repository and removed CICD Run CI/CD labels Mar 18, 2026
@github-actions github-actions bot removed platform-android Android applications specifically platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. engine flutter/engine related. See also e: labels. f: material design flutter/packages/flutter/material repository. f: cupertino flutter/packages/flutter/cupertino repository d: api docs Issues with https://api.flutter.dev/ d: examples Sample code and demos f: routes Navigator, Router, and related APIs. platform-web Web applications specifically platform-linux Building on or for Linux specifically a: desktop Running on desktop e: impeller Impeller rendering backend issues and features requests team-android Owned by Android platform team team-engine Owned by Engine team team-ios Owned by iOS platform team d: docs/ flutter/flutter/docs, for contributors team-macos Owned by the macOS platform team team-linux Owned by the Linux platform team platform-macos labels Mar 18, 2026
@O-Hannonen
Copy link
Contributor Author

Nevermind, the issue was that I did git pull before pushing, when I really should have force pushed. Now the git history and changes look correct again.

@O-Hannonen O-Hannonen requested a review from jtmcdole March 18, 2026 16:40

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're actively trying to remove dependencies on material from widgets as we are preparing to remove material from the framework. Can you update the test to not depend on material and remove this import?

Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thank you!

@Piinks Piinks dismissed jtmcdole’s stale review March 19, 2026 19:52

The issue has been resolved.

@Piinks Piinks added the CICD Run CI/CD label Mar 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scroll "back" on web causes browser back action (unless perfectly horizontal)

4 participants