Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Multiple touches of a stylus should be considered from the same device #56075

Merged
merged 9 commits into from
Nov 2, 2024

Conversation

dkwingsmt
Copy link
Contributor

@dkwingsmt dkwingsmt commented Oct 24, 2024

This PR fixes flutter/flutter#156223.

Problem: The issue above only occurred when using stylus on Web. Multiple touches were treated as different devices: new devices were added and former devices that had the pointer lifted were never removed. This was further caused by the design that Flutter uses JS's PointerEvent.pointerId as the device ID, which increases for each touch.

Flutter had to use PointerEvent.pointerId because JS doesn't provide a way to distinguish between multiple styluses. This PR fixes this issue by simply supporting only one stylus, since support for multi-stylus can be really hard. How multi-stylus should be supported can be discussed upon such demands in the future, but at least for now, iPad doesn't support multi-stylus and it's not something I can test.

This PR also rewrote some comments that I got confused by while reading the code.

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 and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added the platform-web Code specifically for the web engine label Oct 24, 2024
@dkwingsmt dkwingsmt requested a review from ditman October 24, 2024 18:16
Copy link
Member

@ditman ditman left a comment

Choose a reason for hiding this comment

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

LGTM! Small question about the switch returned in _getPointerId.

return switch(_pointerTypeToDeviceKind(event.pointerType!)) {
ui.PointerDeviceKind.mouse => _mouseDeviceId,
ui.PointerDeviceKind.stylus => _stylusDeviceId,
_ => event.pointerId!.toInt(),
Copy link
Member

Choose a reason for hiding this comment

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

I guess _ case covers the multi-tapping with fingers or in the trackpad?

(Should we make this switch exhaustive, for clarity?)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The switch case as well as _ is just a refactor of what was before the PR, except that I added a branch for stylus. I don't think it changes how it behaves for trackpad.

Also, AFAIK, trackpad events are handled as wheel events in _convertWheelEventToPointerData, which does not call _getPointerId, but always use _mouseDeviceId instead.

@ditman
Copy link
Member

ditman commented Oct 24, 2024

This PR also rewrote some comments that I got confused by while reading the code.

(PS: Thanks for this!)

@dkwingsmt
Copy link
Contributor Author

@ditman Thanks for your suggestion of making the switch exhaustive. I've made the change, during which I found out that I didn't include invertedStylus. :)

I've made it clear that trackpad isn't reachable in the switch statement.

Copy link
Member

@ditman ditman left a comment

Choose a reason for hiding this comment

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

Small question about multi-touching on a "trackpad" (those shouldn't be "wheel" events, I think?

Comment on lines +1022 to +1025
// Move event listeners should be added to `_globalTarget` instead of
// `_viewTarget`. This is because `_viewTarget` (the root) captures pointers
// by default, meaning a pointer that starts within `_viewTarget` continues
// sending move events to its listener even when dragged outside.
Copy link
Member

Choose a reason for hiding this comment

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

I haven't revisited this yet, BUT, there's a way to have the behavior that we needed _globalTarget for from the _viewTarget!!

See this: https://developer.mozilla.org/en-US/docs/Web/API/Element/setPointerCapture

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's what I thought as well. Maybe you can change it in a future PR :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added a TODO with issue flutter/flutter#157968

@dkwingsmt dkwingsmt added the autosubmit Merge PR when tree becomes green via auto submit App label Nov 2, 2024
@auto-submit auto-submit bot merged commit 114f7dd into flutter:main Nov 2, 2024
30 checks passed
@dkwingsmt dkwingsmt deleted the stylus-touches branch November 2, 2024 07:11
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 2, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 2, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 2, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 4, 2024
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Nov 4, 2024
…158127)

flutter/engine@05cb5d7...25c7e47

2024-11-04 [email protected] Retry mac_unopt one time in presubmit (flutter/engine#56319)
2024-11-04 [email protected] [Impeller] faster descriptor type mapping. (flutter/engine#56351)
2024-11-04 [email protected] Roll Skia from 75740b68a282 to e2ad60ea8039 (8 revisions) (flutter/engine#56354)
2024-11-04 [email protected] Move detection of cutouts in Android engine to `onApplyWindowInsets` (flutter/engine#55992)
2024-11-04 [email protected] Roll Dart SDK from 69cec5dc51f9 to f238183cf168 (1 revision) (flutter/engine#56353)
2024-11-04 [email protected] Roll Skia from bab7d954758b to 75740b68a282 (1 revision) (flutter/engine#56349)
2024-11-04 [email protected] Roll Fuchsia Linux SDK from 07KmbdEtnhkg_tUhe... to amgHXcqtplha8LuI_... (flutter/engine#56348)
2024-11-03 [email protected] Roll Skia from 6944cd128603 to bab7d954758b (2 revisions) (flutter/engine#56346)
2024-11-02 [email protected] Roll Dart SDK from 61bf0877807e to 69cec5dc51f9 (2 revisions) (flutter/engine#56335)
2024-11-02 [email protected] Multiple touches of a stylus should be considered from the same device (flutter/engine#56075)
2024-11-02 [email protected] Roll Skia from 89ac72bb4922 to 6944cd128603 (2 revisions) (flutter/engine#56331)
2024-11-02 [email protected] [web] Transfer focus to view rootElement on blur/remove. (flutter/engine#55045)

Also rolling transitive DEPS:
  fuchsia/sdk/core/linux-amd64 from 07KmbdEtnhkg to amgHXcqtplha

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
nick9822 pushed a commit to nick9822/flutter that referenced this pull request Dec 18, 2024
flutter/engine#56075)

This PR fixes flutter#156223.

**Problem:** The issue above only occurred when using stylus on Web. Multiple touches were treated as different devices: new devices were added and former devices that had the pointer lifted were never removed. This was further caused by the design that Flutter uses JS's `PointerEvent.pointerId` as the device ID, which increases for each touch.

Flutter had to use `PointerEvent.pointerId` because JS doesn't provide a way to distinguish between multiple styluses. This PR fixes this issue by simply supporting only one stylus, since support for multi-stylus can be really hard. How multi-stylus should be supported can be discussed upon such demands in the future, but at least for now, iPad doesn't support multi-stylus and it's not something I can test.

This PR also rewrote some comments that I got confused by while reading the code.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
autosubmit Merge PR when tree becomes green via auto submit App platform-web Code specifically for the web engine
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MouseRegion has inconsistent behavior using stylus and touch
2 participants