Changeset 244388 in webkit


Ignore:
Timestamp:
Apr 17, 2019 11:04:29 AM (5 years ago)
Author:
Wenson Hsieh
Message:

REGRESSION (r243926): [iOS] Release assertion when computing editor state during an overflow scroll triggered by layout
https://bugs.webkit.org/show_bug.cgi?id=197012
<rdar://problem/49908848>

Reviewed by Simon Fraser.

Source/WebKit:

We hit the release assertion due to the following sequence of events:

  • Dispatch a queued event (in this case, a scroll event)
  • Invoke the scroll event listener, which modifies layout in some way
  • This scrolls an overflow scrollable container under the scope of layout
  • Overflow scrolling then calls didChangeSelection and triggers an editor state update, which updates layout

In the case where the selection is in the main frame, we bail early due to the check for recursive layout (i.e.
frameView->layoutContext().isInRenderTreeLayout()). However, in the case where the selection is inside a
subframe, we end up skipping past this check, since the subframe's FrameView isn't currently laying out, and so
we end up hitting the release assertion underneath the early return.

To fix this, simply defer editor state updates due to overflow scrolling until the next remote layer tree commit
instead of computing and sending the information immediately. While this only defers editor state updates during
overflow scrolling, <rdar://problem/47258878> tracks making editor state updates deferred in the general case.

Test: editing/selection/overflow-scroll-while-selecting-text.html

  • WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:

(WebKit::WebEditorClient::overflowScrollPositionChanged):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::didChangeOverflowScrollPosition):
(WebKit::WebPage::didChangeSelection):
(WebKit::WebPage::didChangeSelectionOrOverflowScrollPosition):

  • WebProcess/WebPage/WebPage.h:

LayoutTests:

Adds a new layout test to exercise the crash.

  • editing/selection/overflow-scroll-while-selecting-text-expected.txt: Added.
  • editing/selection/overflow-scroll-while-selecting-text.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244383 r244388  
     12019-04-17  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r243926): [iOS] Release assertion when computing editor state during an overflow scroll triggered by layout
     4        https://bugs.webkit.org/show_bug.cgi?id=197012
     5        <rdar://problem/49908848>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Adds a new layout test to exercise the crash.
     10
     11        * editing/selection/overflow-scroll-while-selecting-text-expected.txt: Added.
     12        * editing/selection/overflow-scroll-while-selecting-text.html: Added.
     13
    1142019-04-17  Alex Christensen  <achristensen@webkit.org>
    215
  • trunk/Source/WebKit/ChangeLog

    r244382 r244388  
     12019-04-17  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r243926): [iOS] Release assertion when computing editor state during an overflow scroll triggered by layout
     4        https://bugs.webkit.org/show_bug.cgi?id=197012
     5        <rdar://problem/49908848>
     6
     7        Reviewed by Simon Fraser.
     8
     9        We hit the release assertion due to the following sequence of events:
     10        - Dispatch a queued event (in this case, a scroll event)
     11        - Invoke the scroll event listener, which modifies layout in some way
     12        - This scrolls an overflow scrollable container under the scope of layout
     13        - Overflow scrolling then calls didChangeSelection and triggers an editor state update, which updates layout
     14
     15        In the case where the selection is in the main frame, we bail early due to the check for recursive layout (i.e.
     16        frameView->layoutContext().isInRenderTreeLayout()). However, in the case where the selection is inside a
     17        subframe, we end up skipping past this check, since the subframe's FrameView isn't currently laying out, and so
     18        we end up hitting the release assertion underneath the early return.
     19
     20        To fix this, simply defer editor state updates due to overflow scrolling until the next remote layer tree commit
     21        instead of computing and sending the information immediately. While this only defers editor state updates during
     22        overflow scrolling, <rdar://problem/47258878> tracks making editor state updates deferred in the general case.
     23
     24        Test: editing/selection/overflow-scroll-while-selecting-text.html
     25
     26        * WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm:
     27        (WebKit::WebEditorClient::overflowScrollPositionChanged):
     28        * WebProcess/WebPage/WebPage.cpp:
     29        (WebKit::WebPage::didChangeOverflowScrollPosition):
     30        (WebKit::WebPage::didChangeSelection):
     31        (WebKit::WebPage::didChangeSelectionOrOverflowScrollPosition):
     32        * WebProcess/WebPage/WebPage.h:
     33
    1342019-04-17  Chris Dumez  <cdumez@apple.com>
    235
  • trunk/Source/WebKit/WebProcess/WebCoreSupport/ios/WebEditorClientIOS.mm

    r239584 r244388  
    9494void WebEditorClient::overflowScrollPositionChanged()
    9595{
    96     m_page->didChangeSelection();
     96    m_page->didChangeOverflowScrollPosition();
    9797}
    9898
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r244382 r244388  
    52855285}
    52865286
     5287void WebPage::didChangeOverflowScrollPosition()
     5288{
     5289    didChangeSelectionOrOverflowScrollPosition(EditorStateUpdateScheduling::Deferred);
     5290}
     5291
    52875292void WebPage::didChangeSelection()
     5293{
     5294    didChangeSelectionOrOverflowScrollPosition(EditorStateUpdateScheduling::Immediate);
     5295}
     5296
     5297void WebPage::didChangeSelectionOrOverflowScrollPosition(EditorStateUpdateScheduling editorStateScheduling)
    52885298{
    52895299    Frame& frame = m_page->focusController().focusedOrMainFrame();
     
    53285338#endif
    53295339
    5330     sendPartialEditorStateAndSchedulePostLayoutUpdate();
     5340    if (editorStateScheduling == EditorStateUpdateScheduling::Immediate)
     5341        sendPartialEditorStateAndSchedulePostLayoutUpdate();
     5342    else
     5343        scheduleFullEditorStateUpdate();
    53315344}
    53325345
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r244382 r244388  
    765765    void didApplyStyle();
    766766    void didChangeSelection();
     767    void didChangeOverflowScrollPosition();
    767768    void didChangeContents();
    768769    void discardedComposition();
     
    12721273    void setEditable(bool);
    12731274
     1275    enum class EditorStateUpdateScheduling { Deferred, Immediate };
     1276    void didChangeSelectionOrOverflowScrollPosition(EditorStateUpdateScheduling);
     1277
    12741278    void increaseListLevel();
    12751279    void decreaseListLevel();
Note: See TracChangeset for help on using the changeset viewer.