Skip to content

[EditableText] preserve selection/composition range on unfocus - #86796

Merged
fluttergithubbot merged 11 commits into
flutter:masterfrom
LongCatIsLooong:dont-drop-selection-on-unfocus
Aug 7, 2021
Merged

fluttergithubbot merged 11 commits into
flutter:masterfrom
LongCatIsLooong:dont-drop-selection-on-unfocus

Conversation

@LongCatIsLooong

Copy link
Copy Markdown
Contributor

Related Issue: #79982
Fixes #86752

Let the selection/composition range of an EditableText survive through
unfocus, and allows the original selection/composition range to be
restored when the field regains focus.

Demo

Unfortunately the selection handle (and the context menu) is gone when a text field regains focus. This probably needs a new issue since the current implementation of _handleSelectionChanged (and the corresponding logic in the gesture detector callbacks) is really convoluted.

ezgif.com-gif-maker.mp4

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 feature I am adding, or Hixie said the 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.

Related Issue: flutter#79982

Let the selection/composition range of an `EditableText` survive through
unfocus, and allows the original selection/composition range to be
restored when the field regains focus.
@flutter-dashboard flutter-dashboard Bot added p: material_ui material_ui package in flutter/packages framework flutter/packages/flutter repository. See also f: labels. labels Jul 21, 2021
@google-cla google-cla Bot added the cla: yes label Jul 21, 2021
@LongCatIsLooong

LongCatIsLooong commented Jul 21, 2021 •

Copy link
Copy Markdown
Contributor Author

@chunhtai I think you mentioned the desktop accessibility implementation specifically use (-1, -1) for something. Is that going to be a problem if we don't remove the selection and the composing range upon unfocus?

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.

The buildTextSpan method has something similar (the composing region is not painted if the widget is readOnly). But this is a little bit too magical for a low level widget.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it ever possible for a SelectableText to show its selection while another EditableText has focus?

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.

Doesn't seem possible, when a SelectableText loses focus the selection is set to TextRange.empty. Unless there's a SelectableText that initially has a non-empty selection and is not focused.

@LongCatIsLooong
LongCatIsLooong force-pushed the dont-drop-selection-on-unfocus branch from 8f7fa0b to 03aede3 Compare July 21, 2021 18:08

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.

Before the change the underline was shown even when the text field is not focused. That's why this test was passing without the additional pump.

@LongCatIsLooong
LongCatIsLooong force-pushed the dont-drop-selection-on-unfocus branch from 03aede3 to 7303e34 Compare July 21, 2021 18:17
@chunhtai

Copy link
Copy Markdown
Contributor

@chunhtai I think you mentioned the desktop accessibility implementation specifically use (-1, -1) for something. Is that going to be a problem if we don't move the selection and the composing range upon unfocus?

That should be fine.

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM 👍 Just one question and some nits.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess the caret was blinking when the field had a selection even when it wasn't focused.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Any suggestions on process of recovering data with this issue

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.

EditableTextState does call _stopCursorTimer when the widget is unfocused. Reverting this change does not seem to break any tests so I undid the change.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it ever possible for a SelectableText to show its selection while another EditableText has focus?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: Extra newline here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: "an" => "a"

@LongCatIsLooong
LongCatIsLooong force-pushed the dont-drop-selection-on-unfocus branch from 7303e34 to dfdf9fd Compare August 3, 2021 00:37
@flutter-dashboard

Copy link
Copy Markdown

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

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 #86796 at sha dfdf9fd

@flutter-dashboard flutter-dashboard Bot added the will affect goldens Changes to golden files label Aug 3, 2021
@LongCatIsLooong
LongCatIsLooong force-pushed the dont-drop-selection-on-unfocus branch from 13c421d to 6dc779a Compare August 3, 2021 19:08

@LongCatIsLooong LongCatIsLooong left a comment

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.

@justinmc I moved the focus selection highlight logic to high-level text fields. Could you take a look again?

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.

Doesn't seem possible, when a SelectableText loses focus the selection is set to TextRange.empty. Unless there's a SelectableText that initially has a non-empty selection and is not focused.

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.

EditableTextState does call _stopCursorTimer when the widget is unfocused. Reverting this change does not seem to break any tests so I undid the change.

@justinmc justinmc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes LGTM minus a potential scuba failure, happy to look again when that's fixed.

Comment on lines +888 to +890
if (widget.focusNode != oldWidget.focusNode) {
(oldWidget.focusNode ?? _focusNode)?.removeListener(_handleFocusChanged);
(widget.focusNode ?? _focusNode)?.addListener(_handleFocusChanged);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess we weren't swapping these properly before 😁

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.

The _handleFocusChange listener is added in this PR. We didn't have to remove/add listeners before.

minLines: widget.minLines,
expands: widget.expands,
selectionColor: selectionColor,
// Only show the selection highlight when the text field is focused.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Super nit: There was no corresponding comment in CupertinoTextField here.

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

Labels

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.

Preserve text field's caret position across focus changes

5 participants