Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 1f4f2000ed16188b1eecbfdd36bf58e623142390
      
https://github.com/WebKit/WebKit/commit/1f4f2000ed16188b1eecbfdd36bf58e623142390
  Author: Wenson Hsieh <wenson_hs...@apple.com>
  Date:   2025-03-25 (Tue, 25 Mar 2025)

  Changed paths:
    A 
LayoutTests/editing/selection/ios/caret-rect-after-inserting-newlines-in-textarea-expected.txt
    A 
LayoutTests/editing/selection/ios/caret-rect-after-inserting-newlines-in-textarea.html
    M Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h
    M Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.h
    M Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

  Log Message:
  -----------
  [iOS] [SelectionHonorsOverflowScrolling] Caret sometimes appears in the wrong 
place after inserting newline
https://bugs.webkit.org/show_bug.cgi?id=290393
rdar://147362685

Reviewed by Aditya Keerthi.

With SelectionHonorsOverflowScrolling enabled, inserting (or deleting) newlines 
inside a `textarea`
sometimes causes the caret to appear in the wrong place, if the editing command 
triggered
programmatic scrolling in the `textarea`'s content. This is due to 2 main 
causes:

1.  `-_reconcileEnclosingScrollViewContentOffset:` yields incorrect 
`EditorState` geometry in the
    case where scrolling is triggered by the web process itself (and the scroll 
position is being
    synced to the UI process through the same layer tree commit that contains 
this `EditorState`).
    From manually testing the scenario in 286537@main (i.e. composing an email 
in Outlook and Gmail)
    this logic is only needed in the case where the user begins scrolling a 
scroll view that
    contains the selection UI, such that the child scroller is in unstable 
state (and therefore, the
    UI-side `-contentOffset` holds the source of truth, regarding the scroll 
offset of the scroller
    containing the selection). To mitigate this, limit the codepath to trigger 
only when the scroll
    view is in unstable state.

2.  Add a mechanism to call into `-[UITextSelectionDisplayInteraction 
setNeedsSelectionUpdate]`
    (via `WKTextInteractionWrapper`) in the case where a subscroller containing 
the selection has
    been scrolled and the geometry of the `EditorState` in root view 
coordinates is still the same
    as it was during the previous update. Even ignoring (1), when inserting or 
removing a newline at
    the end of a `textarea`, it's possible for the caret rect to *immediately* 
become stale, if the
    caret view is installed before the `-contentOffset` of the subscroller 
changes after inserting
    or deleting at the end of the `textarea`. In this case, a subsequent 
`EditorState` update will
    not update the selection at all since the caret rect in root view 
coordinates is identical, even
    if the caret rect in the coordinate space of the view containing the 
selection changes.

    We can mitigate this by calling into `-setNeedsSelectionUpdate` in this 
case, which tells UIKit
    to remap root view coordinates into selection container coordinates and 
reposition managed
    selection views accordingly. Note that without this part, inserting and 
removing newlines
    *sometimes* still causes the caret to be positioned incorrectly (either one 
line too high or one
    line too low) when typing near the last line of a vertically scrollable 
`textarea`.

See below for more details.

* 
LayoutTests/editing/selection/ios/caret-rect-after-inserting-newlines-in-textarea-expected.txt:
 Added.
* 
LayoutTests/editing/selection/ios/caret-rect-after-inserting-newlines-in-textarea.html:
 Added.
* Source/WebKit/UIProcess/API/ios/WKWebViewIOS.h:
* Source/WebKit/UIProcess/API/ios/WKWebViewIOS.mm:
(-[WKWebView _isInStableState:]):

Expose a method to check whether a given `UIScrollView` is in stable state, 
using heuristics which
currently only apply to the main scroller (`WKScrollView`).

* Source/WebKit/UIProcess/ios/WKContentViewInteraction.h:
* Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm:
(-[WKContentView cleanUpInteraction]):
(-[WKContentView _scrollingNodeScrollingDidEnd:]):

Keep track of whether we've just ended scrolling inside a scroll view that 
contains the current
selection, but haven't received an editor state update yet that honors this new 
scroll position.
This flag (`_waitingForEditorStateAfterScrollingSelectionContainer`) allows us 
to bail from updating
the selection with stale geometry in 
`-_updateSelectionViewsInChildScrollViewIfNeeded`, in the case
where momentum scrolling ends in a subscrollable region containing the 
selection (undoing this
results in a 1-frame flicker of the selection when scrolling the compose window 
on Gmail).

(-[WKContentView _reconcileEnclosingScrollViewContentOffset:]):

See (1) above.

(-[WKContentView _updateChangedSelection:]):
(-[WKContentView _updateSelectionViewsInChildScrollViewIfNeeded]):

See (2) above.

Canonical link: https://commits.webkit.org/292677@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to