Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Loupe Android + iOS #107477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 81 commits into from
Aug 2, 2022
Merged

Loupe Android + iOS #107477

merged 81 commits into from
Aug 2, 2022

Conversation

antholeole
Copy link
Contributor

@antholeole antholeole commented Jul 12, 2022

Loupe! Design doc: https://flutter.dev/go/text-editing-magnifying-glass

List which issues are fixed by this PR. You must list at least one issue.

architecture in depth:

Prelude

This section is pretty long winded, but hopefully it acts as a future paper trail for architecture decisions made in this PR. Everything is a tradeoff, and this section is meant to hopefully allow future interested parties to be able to understand why certain sections were implemented the way they were.

I'm proud to say there are no dark corners in this PR and implementation; I'm happy with how every API turned out and am able to advocate for all decisions made here.

Why SelectionOverlay for the loupe entrypoint?

SelectionOverlay is the "entrypoint" for the loupe; it holds a MagnifierController and proxies calls to MagnifierController.show/hide in order to be able to orchestrate with the toolbar. Any consumers of SelectionOverlay need to tell SelectionOverlay when it should show/hide/update the loupe, to avoid coupling SelectionOverlay with gesture detectors and selection logic; it is almost uniquely a presentation class, and remains that way after this PR.

Motivation behind MagnifierOverlayInfoBearer and a ValueNotifier?

A helpful data class, MagnifierOverlayInfoBearer, was put in place to bundle all the data that a loupe needs to be able to position itself and its focal point. Consumers who choose to position a SelectionOverlay's magnifier must pass it a MagnifierOverlayInfoBearer. MagnifierOverlayInfoBearer also gets passed to the magnifier itself in a unique (to the current implementation of all the text selection overlay entries) way: it is wrapped with a ValueNotifier, and the magnifier listens to updates on that ValueNotifier. This solves two problems that would be very apparent with something that needs to be reactive:

  • the way we were passing data to Overlay prior was to repass to the OverlayEntry, and then call markNeedsBuild on the OverlayEntry. this means every action is one frame late, which would be unacceptable for a loupe.
  • This also means that any data passed needs to be proxied through some controller, adding a middleman (and complexity) because somewhere, markNeedsBuild must be called. This can lead to a class of bugs where an update has happened, but the call to markNeedsBuild happened too early/never happened and the UI skips the update.

MagnifierController

The MagnifierController is a helpful utility which eliminates another class of bugs where an OverlayEntry is removed without satisfying all preconditions (this mostly materializes as removing the overlayEntry before out animation is complete, which is a known bug for context menus). magnifierController.hide is asynchronous, and returns a future that completes when the hide is complete.

As a side note, this could have been generalized as a helpful controller for all overlay entries, not just magnifiers; it's a very useful and general API. This refactor was not done because @LongCatIsLooong work with portals is an even more useful and general API 😄 .

Who positions a Magnifier?

The magnifiers themselves are completely responsible for their own positioning; this eliminates coupling between the magnifierController and positioning. Each Magnifier implementation can position itself based on the data passed to it through MagnifierOverlayInfoBearer. This is the only feasible way to do positioning since Android + iOS handle positioning rules so differently.

How would a user build their own magnifier?

TextMagnifierConfiguration is passed in through the user-friendly text field API's. They have sensible defaults (building the right magnifier based on the platform), but in the Flutter spirit, can be fully disabled or customized. A configuration object was put into place for three reasons:

  1. If more configuration parameters will be needed in the future, spamming the text field constructor with these will pollute an already very heavy constructor. Instead, parameters can be added to the configuration object, acting as a sort of pseudo name-spacing.
  2. We can create a very user friendly, readable API through the use of a static constructor. If a user wants to disable their loupe, they would write:
TextField(
  loupeConfiguration: LoupeConfiguration.disabled
)

This also has the second bonus of being able to be used as a default parameter, for nested libraries with no access to the loupe implementations.

Finally, RawMagnifier is exposed through widgets.dart. The intention of RawMagnifier was to allow users to be able to create their own magnifiers, but also abstract all the footguns BackdropFilter adds.

NOTE: To see the Cupertino entry animations, you must have an engine with (this pull)[https://github.com/flutter/engine/pull/34435]. Otherwise, the Lens in the CupertinoLoupe will abruptly appear at the end of the animation.

TODOs:

  • Tests
  • SelectionArea & SelectableText
  • Make sure that we don't get loupe on floating cursor
  • Rename all loupe -> MagnifyingGlass?

Things to still do after this PR:

If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].

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.

@flutter-dashboard flutter-dashboard bot added a: text input Entering text in a text field or keyboard related problems f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels. labels Jul 12, 2022
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!).

If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix?

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #107477 at sha dc36aca

void didUpdateWidget(CupertinoTextMagnifier oldWidget) {
if (oldWidget.magnifierOverlayInfoBearer != widget.magnifierOverlayInfoBearer) {
oldWidget.magnifierOverlayInfoBearer.removeListener(_determineMagnifierPositionAndFocalPoint);
widget.magnifierOverlayInfoBearer.removeListener(_determineMagnifierPositionAndFocalPoint);
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be addListener right?

void didUpdateWidget(TextMagnifier oldWidget) {
if (oldWidget.magnifierInfo != widget.magnifierInfo) {
oldWidget.magnifierInfo.removeListener(_determineMagnifierPositionAndFocalPoint);
widget.magnifierInfo.removeListener(_determineMagnifierPositionAndFocalPoint);
Copy link
Contributor

Choose a reason for hiding this comment

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

Another one that should be addListener.

@@ -1099,6 +1099,75 @@ void main() {
final Map<String, dynamic> clipboardData = mockClipboard.clipboardData as Map<String, dynamic>;
expect(clipboardData['text'], 'thank');
}, skip: kIsWeb); // [intended] Web uses its native context menu.


Copy link
Contributor

Choose a reason for hiding this comment

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

Extra newline here.

@@ -11876,9 +12040,8 @@ void main() {
),
),
),
),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the trailing comma should still be there.

expect(find.byKey(fakeMagnifier.key!), findsNothing);
});

group('TapRegion integration', () {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the indentation wrong here?

)),
isNull);
},
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this variant block should be outdented by 2 spaces.

/// directly below it.
final Offset additionalFocalPointOffset;


Copy link
Contributor

Choose a reason for hiding this comment

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

Extra newline here.

static const double _borderRadius = 40;
static const double _magnification = 1.25;


Copy link
Contributor

Choose a reason for hiding this comment

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

Extra newline here too.

@flutter-dashboard
Copy link

Golden file changes are available for triage from new commit, Click here to view.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #107477 at sha 6606923

@antholeole antholeole merged commit f014c1e into flutter:master Aug 2, 2022
@Piinks Piinks added c: new feature Nothing broken; request for a new capability a: fidelity Matching the OEM platforms better a: quality A truly polished experience f: selection SelectableRegion, SelectionArea, SelectionContainer, Selectable, and related APIs labels Aug 2, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 3, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Aug 3, 2022
hannah-hyj added a commit that referenced this pull request Aug 4, 2022
* M3 counter error style

* polish

* Update text_field_template.dart

* Roll Flutter Engine from 3cba105 to cf0db3e (1 revision) (#108716)

* resolve comments

* Roll Plugins from 257eacb1e2aa to a6d42f1e01d3 (3 revisions) (#108738)

* Override PlaceholderDimensions equality operator to avoid unnecessary TextPainter re-layouts (#108623)

* Roll Flutter Engine from cf0db3e to aa90044 (1 revision) (#108734)

* Roll Flutter Engine from aa90044 to 6d2fd23 (5 revisions) (#108744)

* Fix lerp to eccentric circle. (#108743)

* Roll Flutter Engine from 6d2fd23 to f182794 (4 revisions) (#108749)

* Roll Flutter Engine from f182794 to 25e8021 (1 revision) (#108751)

* Sync with flutter/.github#13 (#108754)

* Roll Flutter Engine from 25e8021 to e771729 (2 revisions) (#108755)

* clean-up analysis_options.yaml (#108747)

* Fix ExpansionTile shows children background when expanded (#107834)

* Create `containsSemantics` to allow for partial matching of semantics in tests. (#108573)

* Roll Flutter Engine from e771729 to 7d0f6d2 (2 revisions) (#108757)

* Enable conditional_uri_does_not_exist (#108652)

* Roll Flutter Engine from 7d0f6d2 to b257966 (3 revisions) (#108763)

* Roll Flutter Engine from b257966 to 60e5eb6 (3 revisions) (#108766)

* Reland `Linux_samsung_a02 openpay_benchmarks__scroll_perf` (#108466) (#108769)

* [SelectionOverlay]Move the debug statement to the scope of the assertion. (#108508)

* Roll Flutter Engine from 60e5eb6 to 1c3b1b3 (11 revisions) (#108780)

* Roll Flutter Engine from 1c3b1b3 to b607811 (1 revision) (#108782)

* Roll Flutter Engine from b607811 to 3b2bd24 (1 revision) (#108784)

* Roll Flutter Engine from 3b2bd24 to 0e5392c (1 revision) (#108788)

* Roll Flutter Engine from 0e5392c to 4b19256 (1 revision) (#108793)

* Roll Flutter Engine from 4b19256 to e0b5edc (2 revisions) (#108798)

* Roll Flutter Engine from e0b5edc to b164c5c (1 revision) (#108814)

* Update text_field.dart

* Roll Flutter Engine from b164c5c to eb2b57b (4 revisions) (#108821)

* Roll Plugins from a6d42f1e01d3 to 0d6d03a94ed5 (1 revision) (#108822)

* Roll Flutter Engine from eb2b57b to 978d8e2 (2 revisions) (#108825)

* Loupe Android + iOS (#107477)

* added Magnifier for iOS and Android

* Mark `Mac_ios microbenchmarks_ios_flaky` flaky (#108820)

* Deprecate `toggleableActiveColor` (#97972)

* Roll Flutter Engine from 978d8e2 to 2b31732 (4 revisions) (#108830)

* [flutter_tools] Test that DAP process terminates at the end of a session (#108301)

* Roll Flutter Engine from 2b31732 to 4e9c869 (1 revision) (#108833)

* fix noop toString() diagnostics (#108836)

* [flutter_tools] Migrate more tool tests to null-safety (#108639)

* Revert "Fix ExpansionTile shows children background when expanded" (#108844)

* Roll Flutter Engine from 4e9c869 to 6724561 (2 revisions) (#108838)

* Marks Linux_android clipper_cache_perf__e2e_summary to be unflaky (#104088)

* Update documentation to match implementation (#108843)

* Reland "Add shadowColor and surfaceTintColor to Dialog and DialogTheme." #108718

* Roll Flutter Engine from 6724561 to f3deaba (8 revisions) (#108847)

* Roll Flutter Engine from f3deaba to c07e1ac (2 revisions) (#108849)

* Roll Flutter Engine from c07e1ac to a1e77ae (5 revisions) (#108850)

* Roll Flutter Engine from a1e77ae to c456476 (2 revisions) (#108853)

* Roll Flutter Engine from c456476 to 6cd744b (1 revision) (#108857)

* Roll Flutter Engine from 6cd744b to 51296a6 (1 revision) (#108860)

* Roll Flutter Engine from 51296a6 to 05228ad (1 revision) (#108862)

* Revert "Roll Flutter Engine from 51296a6 to 05228ad (1 revision) (#108862)" (#108882)

This reverts commit a880c4e.

* Roll Plugins from 0d6d03a94ed5 to e74c42028d39 (5 revisions) (#108887)

* Roll Flutter Engine from 51296a6 to 2c28298 (6 revisions) (#108899)

* [flutter_test] Add flag to send device pointer events to the framework (#108430)

* Roll Flutter Engine from 2c28298 to adba702 (2 revisions) (#108903)

* fix flutter not finding custom device (#108884)

* Force a11y services to off for complex_layout_semantics_perf test (#108906)

* Update `equalsIgnoringHashCodes` to take a list of Strings (#108507)

* [macOS] Use editing intents from engine (#105407)

* Added `IconButtonTheme` and apply it to `IconButton` in M3 (#108332)

* Created IconButtonTheme and apply it to IconButton

* [web] Add onEntrypointLoaded to FlutterLoader. (#108776)

* Roll pub packages (#108919)

* [flutter_test] perf: find.ancestor (#108868)

* Roll Flutter Engine from adba702 to 1188a80 (4 revisions) (#108922)

* Bump github/codeql-action from 2.1.17 to 2.1.18 (#108923)

* Remove some outdated ignores from framework (#108915)

* Roll Flutter Engine from 1188a80 to 1743d1d (1 revision) (#108925)

* Clean up ScrollbarPainter (#107179)

* Remove outdated ignores (#108924)

* Add more logs to diagnose Gold flake (#108930)

* M3 counter error style

* polish

* Update text_field_template.dart

* resolve comments

* Update text_field.dart

Co-authored-by: engine-flutter-autoroll <[email protected]>
Co-authored-by: Tomasz Gucio <[email protected]>
Co-authored-by: Greg Spencer <[email protected]>
Co-authored-by: Ian Hickson <[email protected]>
Co-authored-by: Michael Goderbauer <[email protected]>
Co-authored-by: Bruno Leroux <[email protected]>
Co-authored-by: pdblasi-google <[email protected]>
Co-authored-by: Kaushik Iska <[email protected]>
Co-authored-by: xubaolin <[email protected]>
Co-authored-by: Anthony Oleinik <[email protected]>
Co-authored-by: keyonghan <[email protected]>
Co-authored-by: Taha Tesser <[email protected]>
Co-authored-by: Danny Tuppeny <[email protected]>
Co-authored-by: Phil Quitslund <[email protected]>
Co-authored-by: Christopher Fujino <[email protected]>
Co-authored-by: Kate Lovett <[email protected]>
Co-authored-by: Flutter GitHub Bot <[email protected]>
Co-authored-by: parkershepherd <[email protected]>
Co-authored-by: Darren Austin <[email protected]>
Co-authored-by: Zachary Anderson <[email protected]>
Co-authored-by: Jia Hao <[email protected]>
Co-authored-by: Hannes Winkler <[email protected]>
Co-authored-by: Matej Knopp <[email protected]>
Co-authored-by: Qun Cheng <[email protected]>
Co-authored-by: David Iglesias <[email protected]>
Co-authored-by: Pascal Welsch <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
camsim99 pushed a commit to camsim99/flutter that referenced this pull request Aug 10, 2022
* added Magnifier for iOS and Android
camsim99 pushed a commit to camsim99/flutter that referenced this pull request Aug 10, 2022
* M3 counter error style

* polish

* Update text_field_template.dart

* Roll Flutter Engine from 3cba105 to cf0db3e (1 revision) (flutter#108716)

* resolve comments

* Roll Plugins from 257eacb1e2aa to a6d42f1e01d3 (3 revisions) (flutter#108738)

* Override PlaceholderDimensions equality operator to avoid unnecessary TextPainter re-layouts (flutter#108623)

* Roll Flutter Engine from cf0db3e to aa90044 (1 revision) (flutter#108734)

* Roll Flutter Engine from aa90044 to 6d2fd23 (5 revisions) (flutter#108744)

* Fix lerp to eccentric circle. (flutter#108743)

* Roll Flutter Engine from 6d2fd23 to f182794 (4 revisions) (flutter#108749)

* Roll Flutter Engine from f182794 to 25e8021 (1 revision) (flutter#108751)

* Sync with flutter/.github#13 (flutter#108754)

* Roll Flutter Engine from 25e8021 to e771729 (2 revisions) (flutter#108755)

* clean-up analysis_options.yaml (flutter#108747)

* Fix ExpansionTile shows children background when expanded (flutter#107834)

* Create `containsSemantics` to allow for partial matching of semantics in tests. (flutter#108573)

* Roll Flutter Engine from e771729 to 7d0f6d2 (2 revisions) (flutter#108757)

* Enable conditional_uri_does_not_exist (flutter#108652)

* Roll Flutter Engine from 7d0f6d2 to b257966 (3 revisions) (flutter#108763)

* Roll Flutter Engine from b257966 to 60e5eb6 (3 revisions) (flutter#108766)

* Reland `Linux_samsung_a02 openpay_benchmarks__scroll_perf` (flutter#108466) (flutter#108769)

* [SelectionOverlay]Move the debug statement to the scope of the assertion. (flutter#108508)

* Roll Flutter Engine from 60e5eb6 to 1c3b1b3 (11 revisions) (flutter#108780)

* Roll Flutter Engine from 1c3b1b3 to b607811 (1 revision) (flutter#108782)

* Roll Flutter Engine from b607811 to 3b2bd24 (1 revision) (flutter#108784)

* Roll Flutter Engine from 3b2bd24 to 0e5392c (1 revision) (flutter#108788)

* Roll Flutter Engine from 0e5392c to 4b19256 (1 revision) (flutter#108793)

* Roll Flutter Engine from 4b19256 to e0b5edc (2 revisions) (flutter#108798)

* Roll Flutter Engine from e0b5edc to b164c5c (1 revision) (flutter#108814)

* Update text_field.dart

* Roll Flutter Engine from b164c5c to eb2b57b (4 revisions) (flutter#108821)

* Roll Plugins from a6d42f1e01d3 to 0d6d03a94ed5 (1 revision) (flutter#108822)

* Roll Flutter Engine from eb2b57b to 978d8e2 (2 revisions) (flutter#108825)

* Loupe Android + iOS (flutter#107477)

* added Magnifier for iOS and Android

* Mark `Mac_ios microbenchmarks_ios_flaky` flaky (flutter#108820)

* Deprecate `toggleableActiveColor` (flutter#97972)

* Roll Flutter Engine from 978d8e2 to 2b31732 (4 revisions) (flutter#108830)

* [flutter_tools] Test that DAP process terminates at the end of a session (flutter#108301)

* Roll Flutter Engine from 2b31732 to 4e9c869 (1 revision) (flutter#108833)

* fix noop toString() diagnostics (flutter#108836)

* [flutter_tools] Migrate more tool tests to null-safety (flutter#108639)

* Revert "Fix ExpansionTile shows children background when expanded" (flutter#108844)

* Roll Flutter Engine from 4e9c869 to 6724561 (2 revisions) (flutter#108838)

* Marks Linux_android clipper_cache_perf__e2e_summary to be unflaky (flutter#104088)

* Update documentation to match implementation (flutter#108843)

* Reland "Add shadowColor and surfaceTintColor to Dialog and DialogTheme." flutter#108718

* Roll Flutter Engine from 6724561 to f3deaba (8 revisions) (flutter#108847)

* Roll Flutter Engine from f3deaba to c07e1ac (2 revisions) (flutter#108849)

* Roll Flutter Engine from c07e1ac to a1e77ae (5 revisions) (flutter#108850)

* Roll Flutter Engine from a1e77ae to c456476 (2 revisions) (flutter#108853)

* Roll Flutter Engine from c456476 to 6cd744b (1 revision) (flutter#108857)

* Roll Flutter Engine from 6cd744b to 51296a6 (1 revision) (flutter#108860)

* Roll Flutter Engine from 51296a6 to 05228ad (1 revision) (flutter#108862)

* Revert "Roll Flutter Engine from 51296a6 to 05228ad (1 revision) (flutter#108862)" (flutter#108882)

This reverts commit a880c4e.

* Roll Plugins from 0d6d03a94ed5 to e74c42028d39 (5 revisions) (flutter#108887)

* Roll Flutter Engine from 51296a6 to 2c28298 (6 revisions) (flutter#108899)

* [flutter_test] Add flag to send device pointer events to the framework (flutter#108430)

* Roll Flutter Engine from 2c28298 to adba702 (2 revisions) (flutter#108903)

* fix flutter not finding custom device (flutter#108884)

* Force a11y services to off for complex_layout_semantics_perf test (flutter#108906)

* Update `equalsIgnoringHashCodes` to take a list of Strings (flutter#108507)

* [macOS] Use editing intents from engine (flutter#105407)

* Added `IconButtonTheme` and apply it to `IconButton` in M3 (flutter#108332)

* Created IconButtonTheme and apply it to IconButton

* [web] Add onEntrypointLoaded to FlutterLoader. (flutter#108776)

* Roll pub packages (flutter#108919)

* [flutter_test] perf: find.ancestor (flutter#108868)

* Roll Flutter Engine from adba702 to 1188a80 (4 revisions) (flutter#108922)

* Bump github/codeql-action from 2.1.17 to 2.1.18 (flutter#108923)

* Remove some outdated ignores from framework (flutter#108915)

* Roll Flutter Engine from 1188a80 to 1743d1d (1 revision) (flutter#108925)

* Clean up ScrollbarPainter (flutter#107179)

* Remove outdated ignores (flutter#108924)

* Add more logs to diagnose Gold flake (flutter#108930)

* M3 counter error style

* polish

* Update text_field_template.dart

* resolve comments

* Update text_field.dart

Co-authored-by: engine-flutter-autoroll <[email protected]>
Co-authored-by: Tomasz Gucio <[email protected]>
Co-authored-by: Greg Spencer <[email protected]>
Co-authored-by: Ian Hickson <[email protected]>
Co-authored-by: Michael Goderbauer <[email protected]>
Co-authored-by: Bruno Leroux <[email protected]>
Co-authored-by: pdblasi-google <[email protected]>
Co-authored-by: Kaushik Iska <[email protected]>
Co-authored-by: xubaolin <[email protected]>
Co-authored-by: Anthony Oleinik <[email protected]>
Co-authored-by: keyonghan <[email protected]>
Co-authored-by: Taha Tesser <[email protected]>
Co-authored-by: Danny Tuppeny <[email protected]>
Co-authored-by: Phil Quitslund <[email protected]>
Co-authored-by: Christopher Fujino <[email protected]>
Co-authored-by: Kate Lovett <[email protected]>
Co-authored-by: Flutter GitHub Bot <[email protected]>
Co-authored-by: parkershepherd <[email protected]>
Co-authored-by: Darren Austin <[email protected]>
Co-authored-by: Zachary Anderson <[email protected]>
Co-authored-by: Jia Hao <[email protected]>
Co-authored-by: Hannes Winkler <[email protected]>
Co-authored-by: Matej Knopp <[email protected]>
Co-authored-by: Qun Cheng <[email protected]>
Co-authored-by: David Iglesias <[email protected]>
Co-authored-by: Pascal Welsch <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a: fidelity Matching the OEM platforms better a: quality A truly polished experience a: text input Entering text in a text field or keyboard related problems c: new feature Nothing broken; request for a new capability f: cupertino flutter/packages/flutter/cupertino repository f: material design flutter/packages/flutter/material repository. f: selection SelectableRegion, SelectionArea, SelectionContainer, Selectable, and related APIs framework flutter/packages/flutter repository. See also f: labels. will affect goldens Changes to golden files
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support magnify glass (loupe) feature for text selection in TextField in Android P EditableText should show a loupe on iOS when changing selection
8 participants