Skip to content

Text selection vertical extent should be defined per line (not per glyph) #21997

Open

Description

@cbracken

As reported by @_mono on Twitter, the Flutter text selection highlight rect should be computed at the line level as opposed to per glyph. To see this effect, paste the sequence ( ´・‿・`) into a Flutter text field and select it.

Example images below:

Flutter selection:
flutter

iOS OEM selection:
ios

Android OEM selection:
android

Activity

  1. added
    a: text inputEntering text in a text field or keyboard related problems
    frameworkflutter/packages/flutter repository. See also f: labels.
    engineflutter/engine related. See also e: labels.
    a: fidelityMatching the OEM platforms better
    on Sep 18, 2018
  2. cbracken commented on Sep 18, 2018

    @cbracken
    MemberAuthor
  3. jason-simmons commented on Sep 18, 2018

    @jason-simmons
    Contributor

    The engine does this intentionally (see flutter-team-archive/engine@9f8cf7e)

    Is this a bug or a feature?

    @Hixie

  4. cbracken commented on Sep 18, 2018

    @cbracken
    MemberAuthor

    Based on the platform-specific behaviour, it looks like a bug to me. Both Android and iOS appear to use the line height.

    It seems potentially useful to expose the glyph-specific metrics (e.g. if you were interested in computing text metrics of a glyph independent from its context) but in terms of selection, I'd assume we should be using line-height.

  5. dnfield commented on Sep 18, 2018

    @dnfield
    Contributor

    Looks like the linked commit(s) were intended to support text spans being treated as a single block for Rich text, but is now treating each glyph as a separate block.

  6. garymm commented on Sep 18, 2018

    @garymm
  7. dnfield commented on Sep 18, 2018

    @dnfield
    Contributor

    Should've been @GaryQian

  8. GaryQian commented on Sep 21, 2018

    @GaryQian
    Contributor

    I think I originally implemented it so that the height is the max of each line to match native/blink behavior. I believe this is mainly so that multi-line highlights do not leave awkward gaps between lines due to differing heights (as seen below).

    image

    When spans of differing heights are stacked on top of each other, they always advance enough in the y direction to accommodate the tallest span

  9. GaryQian commented on Sep 21, 2018

    @GaryQian
    Contributor

    Also, @dnfield it seems that the ( ´・‿・`) text uses characters from different sets, so they are automatically broken into different spans. it just happens that they are alternating, making it look particularly strange.

  10. dnfield commented on Sep 21, 2018

    @dnfield
    Contributor

    So it sounds like we're treating it as different spans because of different sets.

    I think what a user would expect (and what Android/iOS do here), is that the text runs are styled the same, so they should be treated as the same height. In other words, this text run was built from a single ParagraphBuilder.addText with no intervening pushStyle or pop - or, could be generated using a single TextSpan class.

  11. GaryQian commented on Sep 21, 2018

    @GaryQian
    Contributor

    That makes sense to me, but to match native behavior (and therefore expected), I think we still should take the max of the line heights. We could also provide the glyph/span specific heights as a separate API, but not sure if that would be particularly useful.

    On native text, even if you have a font size 10 on the same line as a font size 150, the bounding boxes for that line are 150 high.

  12. GaryQian commented on Sep 26, 2018

    @GaryQian
    Contributor

    flutter-team-archive/engine#6335 begins to implement a new API for more advanced GetRectsForRange, which provides the boxes for text selection.

  13. 10 remaining items

  14. darshankawar commented on Sep 1, 2020

    @darshankawar
    Member

    Issue replicable on latest stable (1.20.2)

    21997

    flutter doctor -v
    [✓] Flutter (Channel stable, 1.20.2, on Mac OS X 10.15.2 19C57, locale en-US)
        • Flutter version 1.20.2 at
          /Users/deeptibelsare/Documents/Fluttersdk/flutter
        • Framework revision bbfbf1770c (3 weeks ago), 2020-08-13 08:33:09 -0700
        • Engine revision 9d5b21729f
        • Dart version 2.9.1
    
    [!] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
        • Android SDK at /Users/deeptibelsare/Library/Android/sdk
        • Platform android-30, build-tools 29.0.3
        • ANDROID_HOME = /Users/deeptibelsare/Library/Android/sdk
        • ANDROID_SDK_ROOT = /Users/deeptibelsare/Library/Android/sdk
        • Java binary at: /Applications/Android
          Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build
          1.8.0_212-release-1586-b4-5784211)
        ✗ Android license status unknown.
          Try re-installing or updating your Android SDK Manager.
          See https://developer.android.com/studio/#downloads or visit
          https://flutter.dev/docs/get-started/install/macos#android-setup for
          detailed instructions.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 11.6)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 11.6, Build version 11E708
        • CocoaPods version 1.9.3
    
    [✓] Android Studio (version 3.6)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin version 45.1.1
        • Dart plugin version 192.7761
        • Java version OpenJDK Runtime Environment (build
          1.8.0_212-release-1586-b4-5784211)
    
    [✓] Connected device (1 available)
        • SM A260G (mobile) • 5200763ebcfa861f • android-arm • Android 8.1.0 (API
          27)
    
    ! Doctor found issues in 1 category.
    
    code sample
    return MaterialApp(
          home: Scaffold(
            body: Center(
              child: TextField(
                decoration: InputDecoration(
                  hintText: 'Enter text'
                ),
              )
            )
          )
        );
    
  15. added
    P2Important issues not at the top of the work list
    on Dec 9, 2020
  16. exaby73 commented on Dec 2, 2022

    @exaby73
    Member

    This issue is mostly fixed. I cannot reproduce it with Android, MacOS or iOS. But when running on Linux, there is a slight vertical offset on one of the glyphs. Updating labels to reflect the same

    Linux

    image

    Android

    image

    Code Sample
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      final _controller = TextEditingController()..text = '( ´・‿・`)';
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SizedBox(
              width: 300,
              child: TextField(
                controller: _controller,
                style: Theme.of(context).textTheme.headlineMedium,
              ),
            ),
          ),
        );
      }
    }
  17. reidbaker commented on Feb 9, 2023

    @reidbaker
    Contributor

    Gary is no longer working on flutter issues. Removing him to correctly reflect bug status.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: fidelityMatching the OEM platforms bettera: qualityA truly polished experiencea: text inputEntering text in a text field or keyboard related problemsengineflutter/engine related. See also e: labels.found in release: 3.3Found to occur in 3.3found in release: 3.6Found to occur in 3.6frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions