Skip to content

Supports global selection for all devices - #95226

Merged
chunhtai merged 9 commits into
flutter:masterfrom
chunhtai:inherited-selection
May 24, 2022
Merged

chunhtai merged 9 commits into
flutter:masterfrom
chunhtai:inherited-selection

Conversation

@chunhtai

@chunhtai chunhtai commented Dec 14, 2021 •

Copy link
Copy Markdown
Contributor

Support for mouse drag selection and mobile selection

#81839

design doc: http://flutter.dev/go/global-selection

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.
  • All existing and new tests are passing.

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

@flutter-dashboard flutter-dashboard Bot added a: text input Entering text in a text field or keyboard related problems f: gestures flutter/packages/flutter/gestures repository. f: routes Navigator, Router, and related APIs. f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. labels Dec 14, 2021

@goderbauer goderbauer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Haven't reviewed it all, just some comments from an initial read-through.

Comment thread packages/flutter/lib/src/rendering/paragraph.dart Outdated
Comment thread packages/flutter/lib/src/rendering/paragraph.dart Outdated
Comment thread packages/flutter/lib/src/services/selection.dart Outdated
Comment thread packages/flutter/lib/src/services/selection.dart Outdated
Comment thread packages/flutter/lib/src/services/selection.dart Outdated

/// Called when the selectables this widget collected has changed.
///
/// Use this method to extract the collected selectables in the subtree.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

document that the selectables are given in screen order in the list?


DragSelectionStartEvent? _currentDragStart;

/// Updates the selectables this updater manages.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Document that it expects the selectables in screen order (I think?)

/// Gets the list selectables this updater is responsible for updating.
///
/// The subclasses is responsible for updating the selection when the
/// selectables in the list has changed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

document expected order?

}

/// Copies the selected contents of all the selectables.
Object? copy() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should this be typed String?? Seems to be the only possible return type?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It may not be the case if we support multimedia, but i guess we can change that later?


/// Initialize the selection of the selectable children.
///
/// The goal is to find which selectable child the selection starts on

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

missing .

@goderbauer

Copy link
Copy Markdown
Member

This looks pretty interesting. It's nice to see that we can do this without adding things to RenderObject.

What wasn't clear to me from my initial read-through is why we need SelectionResult.next/SelectionResult.previous. Why can that not just be determined based on the rect of a Selectable?

late final SelectionResult result;
if (event is DragSelectionEvent) {
if (event is DragSelectionStartEvent) {
_dragSelectionStartInGlobalCoordinate = event.offset;

@goderbauer goderbauer Dec 14, 2021 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wouldn't we want to hold on to the start point in local coordinates und use that for the calculations in _updateDragSelection?

I am thinking about a scenario where you start the selection with a pointer down in a large body of text and while the pointer is down you scroll a surrounding scrollable. I think that scroll needs to extend the selection and the selection needs to start at the letter that the pointer touched when it cam down first. Due to the scroll, that letter will have moved in the global coordinate system, though.

/// should start before all of its children. Returns [SelectionResult.next]
/// if the selection should start after all of its children.
SelectionResult _initSelection(DragSelectionUpdateEvent event) {
for (int index = 0; index < selectables.length; index += 1){

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: space before {

@chunhtai

chunhtai commented Dec 14, 2021 •

Copy link
Copy Markdown
Contributor Author

This looks pretty interesting. It's nice to see that we can do this without adding things to RenderObject.

What wasn't clear to me from my initial read-through is why we need SelectionResult.next/SelectionResult.previous. Why can that not just be determined based on the rect of a Selectable?

The biggest concern is select to scroll. Imagine a container with 3 child [A, B, C]. If B is scrollable and the drag selection goes to C, IMO we can't send update event to C until B finishes scrolling. We can also makes B returns some kind of flag to tell the container not to proceed and get rid of SelectionResult, but I think the current implementation is more systematic since there maybe more cases where selectable itself has opinion on the selection order.

The other concern is keyboard selection. Imagine developer press shit+ down, how does the container know which selectable should be the new selection edge. With SelectionResult, the selectable itself can tell the container whether the shift down should reach the next selectable or not.

@skia-gold

Copy link
Copy Markdown

Gold has detected about 1 new digest(s) on patchset 9.
View them at https://flutter-gold.skia.org/cl/github/95226

@chunhtai
chunhtai force-pushed the inherited-selection branch from 1387fce to bfab82c Compare December 30, 2021 23:23
@skia-gold

Copy link
Copy Markdown

Gold has detected about 2 new digest(s) on patchset 10.
View them at https://flutter-gold.skia.org/cl/github/95226

@skia-gold

Copy link
Copy Markdown

Gold has detected about 1 new digest(s) on patchset 11.
View them at https://flutter-gold.skia.org/cl/github/95226

@skia-gold

Copy link
Copy Markdown

Gold has detected about 1 new digest(s) on patchset 12.
View them at https://flutter-gold.skia.org/cl/github/95226

@chunhtai
chunhtai force-pushed the inherited-selection branch 6 times, most recently from 523b432 to 2cf4f8e Compare January 18, 2022 21:44
@chunhtai
chunhtai force-pushed the inherited-selection branch 2 times, most recently from 9425c57 to 01d68b6 Compare January 26, 2022 01:03
@chunhtai
chunhtai marked this pull request as ready for review January 27, 2022 01:14
@flutter-dashboard flutter-dashboard Bot added the p: material_ui material_ui package in flutter/packages label Jan 27, 2022
@chunhtai
chunhtai requested a review from goderbauer January 27, 2022 01:14
@chunhtai

Copy link
Copy Markdown
Contributor Author

please ignore the failing test for now, It is because I want to hide the selection specific logic in RenderParagraph by making a private subclass of it, and it failed the describe node test. I am thinking whether there is way around it or i will have to expose the API

@chunhtai

Copy link
Copy Markdown
Contributor Author

I will add more tests. This PR now supports both mouse selection and mobile selection. I figure i may need to tear up bunch of API in Selectable to separate both them into two PR, which may make it hard to comprehend. So I keep them in the same PR.

@chunhtai

Copy link
Copy Markdown
Contributor Author

also cc @jonahwilliams

@goderbauer goderbauer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Overall this LGTM after the last few comments are addressed.

Comment thread examples/api/lib/material/selection_area/disable_partial_selection.dart Outdated
Comment thread examples/api/lib/material/selection_area/selection_area.dart Outdated
Comment thread packages/flutter/lib/src/rendering/selection.dart Outdated
Comment thread packages/flutter/lib/src/widgets/selection_container.dart Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What if it changes from non-null to null?

@chunhtai chunhtai May 24, 2022 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It will be handled in didUpdateWidget

Comment thread packages/flutter/lib/src/widgets/selection_container.dart Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Let's add some TODO comments here explaining that.

@goderbauer goderbauer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@nilsreichardt

nilsreichardt commented May 24, 2022 •

Copy link
Copy Markdown
Contributor

Right clicking a word selects the word, but I think it shouldn't. In a TextField, right clicking just sets the cursor.

From #95226 (review)

@justinmc On macOS this not true for web (I don't know how Windows it handels):

Screen.Recording.2022-05-25.at.00.46.29.mov

(I used the flutter.dev website)

@justinmc

Copy link
Copy Markdown
Contributor

@nilsreichardt Good catch. I think we're doing those gestures in another PR so we'll have to get this right there.

@nilsreichardt

Copy link
Copy Markdown
Contributor

@justinmc Yes, I also opened a few issue for the SelectionArea widget which can be implemented in separated PRs 👍 My intention with the comment was the current selection behavior of SelectionArea is correct (right click and the word becomes selected) ✅

camsim99 pushed a commit to camsim99/flutter that referenced this pull request Aug 10, 2022
* Support global selection

* addressing comments

* add new test

* Addressing review comments

* update

* addressing comments

* addressing comments

* Addressing comments

* fix build
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 30, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Aug 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems f: gestures flutter/packages/flutter/gestures repository. f: routes Navigator, Router, and related APIs. f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants