Unverified Commit 9707001c authored by hellohuanlin's avatar hellohuanlin Committed by GitHub

[floating_cursor_selection]add more comments on the tricky part (#127227)

Many parts of the floating cursor selection feature is pretty tricky. Some took me a while to figure out. So I added some comments to explain a bit for future readers.

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

https://github.com/flutter/flutter/issues/30476

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
parent 83af9433
...@@ -1269,7 +1269,9 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin, ...@@ -1269,7 +1269,9 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
// [assembleSemanticsNode] invocations. // [assembleSemanticsNode] invocations.
LinkedHashMap<Key, SemanticsNode>? _cachedChildNodes; LinkedHashMap<Key, SemanticsNode>? _cachedChildNodes;
/// Returns a list of rects that bound the given selection. /// Returns a list of rects that bound the given selection, and the text
/// direction. The text direction is used by the engine to calculate
/// the closest position to a given point.
/// ///
/// See [TextPainter.getBoxesForSelection] for more details. /// See [TextPainter.getBoxesForSelection] for more details.
List<TextBox> getBoxesForSelection(TextSelection selection) { List<TextBox> getBoxesForSelection(TextSelection selection) {
......
...@@ -2792,6 +2792,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -2792,6 +2792,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
if (_textInputConnection?.scribbleInProgress ?? false) { if (_textInputConnection?.scribbleInProgress ?? false) {
cause = SelectionChangedCause.scribble; cause = SelectionChangedCause.scribble;
} else if (_pointOffsetOrigin != null) { } else if (_pointOffsetOrigin != null) {
// For floating cursor selection when force pressing the space bar.
cause = SelectionChangedCause.forcePress; cause = SelectionChangedCause.forcePress;
} else { } else {
cause = SelectionChangedCause.keyboard; cause = SelectionChangedCause.keyboard;
...@@ -2941,8 +2942,22 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -2941,8 +2942,22 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
final Offset finalPosition = renderEditable.getLocalRectForCaret(_lastTextPosition!).centerLeft - _floatingCursorOffset; final Offset finalPosition = renderEditable.getLocalRectForCaret(_lastTextPosition!).centerLeft - _floatingCursorOffset;
if (_floatingCursorResetController!.isCompleted) { if (_floatingCursorResetController!.isCompleted) {
renderEditable.setFloatingCursor(FloatingCursorDragState.End, finalPosition, _lastTextPosition!); renderEditable.setFloatingCursor(FloatingCursorDragState.End, finalPosition, _lastTextPosition!);
// Only change if the current selection range is collapsed, to prevent // During a floating cursor's move gesture (1 finger), a cursor is
// overwriting the result of the iOS keyboard selection gesture. // animated only visually, without actually updating the selection.
// Only after move gesture is complete, this function will be called
// to actually update the selection to the new cursor location with
// zero selection length.
// However, During a floating cursor's selection gesture (2 fingers), the
// selection is constantly updated by the engine throughout the gesture.
// Thus when the gesture is complete, we should not update the selection
// to the cursor location with zero selection length, because that would
// overwrite the selection made by floating cursor selection.
// Here we use `isCollapsed` to distinguish between floating cursor's
// move gesture (1 finger) vs selection gesture (2 fingers), as
// the engine does not provide information other than notifying a
// new selection during with selection gesture (2 fingers).
if (renderEditable.selection!.isCollapsed) { if (renderEditable.selection!.isCollapsed) {
// The cause is technically the force cursor, but the cause is listed as tap as the desired functionality is the same. // The cause is technically the force cursor, but the cause is listed as tap as the desired functionality is the same.
_handleSelectionChanged(TextSelection.fromPosition(_lastTextPosition!), SelectionChangedCause.forcePress); _handleSelectionChanged(TextSelection.fromPosition(_lastTextPosition!), SelectionChangedCause.forcePress);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment