Changeset 239573 in webkit


Ignore:
Timestamp:
Jan 2, 2019 12:28:24 PM (5 years ago)
Author:
Wenson Hsieh
Message:

REGRESSION (r239441): [iOS] Selection UI sometimes doesn't change after tapping "select all" in the callout bar
https://bugs.webkit.org/show_bug.cgi?id=193070
<rdar://problem/46921508>

Reviewed by Tim Horton.

Source/WebKit:

r239441 added logic to include an EditorState in the next layer tree commit when refocusing an element; this was
done to ensure that after tapping an element that has already been programmatically focused, we still send up-
to-date editor information to the UI process for the purposes of zooming to the selection rect, even if the
selection in the DOM is unchanged, since other aspects of the editor state may have changed since the element
was initially focused.

We currently try to flag the next layer tree commit by setting m_hasPendingEditorStateUpdate to true.
However, this is problematic since we aren't guaranteed in all cases that a compositing flush has been
scheduled. In the case where it hasn't, we'll end up in a state where the editor state update flag has been set,
yet the update will not make it over to the UI process until something happens that forces a layer tree commit
(e.g. scrolling, pinch zooming). Worse still, if the selection is then programmatically changed from the web
process, we will bail from sending a subsequent editor state update to the UI process because WebPage thinks
that a pending editor state has already been scheduled. This manifests in selection UI not updating after
tapping "Select All" in the callout bar, if the callout bar was brought up by tapping near the selection (since
this refocuses the element).

To fix this, we adjust this logic in WebPage::elementDidRefocus so that it sets the flag and then schedules a
compositing flush, but only if the user is actually interacting with the focused element (i.e., if the page
calls focus repeatedly, we won't continue to schedule compositing flushes).

Test: editing/selection/ios/change-selection-after-tapping-focused-element.html

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::elementDidRefocus):
(WebKit::WebPage::sendEditorStateUpdate):
(WebKit::WebPage::scheduleFullEditorStateUpdate):

Add a private helper method to schedule an editor state update by setting m_hasPendingEditorStateUpdate to
true and then scheduling a compositing layer flush. Also, add a FIXME aluding to the fact that scheduling an
entire compositing layer flush to send an editor state update is somewhat wasteful, and should be replaced by
just scheduling this work to be done before the next frame (see: <rdar://problem/36523583> for more detail).

We also use this helper method in a few places where we currently turn on the editor state flag and schedule a
subsequent compositing flush.

(WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate):

  • WebProcess/WebPage/WebPage.h:

LayoutTests:

Add a test to ensure that selection UI is shown after tapping on a focused element and then changing the
selection programmatically.

  • editing/selection/ios/change-selection-after-tapping-focused-element-expected.txt: Added.
  • editing/selection/ios/change-selection-after-tapping-focused-element.html: Added.
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r239571 r239573  
     12019-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r239441): [iOS] Selection UI sometimes doesn't change after tapping "select all" in the callout bar
     4        https://bugs.webkit.org/show_bug.cgi?id=193070
     5        <rdar://problem/46921508>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add a test to ensure that selection UI is shown after tapping on a focused element and then changing the
     10        selection programmatically.
     11
     12        * editing/selection/ios/change-selection-after-tapping-focused-element-expected.txt: Added.
     13        * editing/selection/ios/change-selection-after-tapping-focused-element.html: Added.
     14
    1152019-01-02  Simon Fraser  <simon.fraser@apple.com>
    216
  • trunk/Source/WebKit/ChangeLog

    r239572 r239573  
     12019-01-02  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        REGRESSION (r239441): [iOS] Selection UI sometimes doesn't change after tapping "select all" in the callout bar
     4        https://bugs.webkit.org/show_bug.cgi?id=193070
     5        <rdar://problem/46921508>
     6
     7        Reviewed by Tim Horton.
     8
     9        r239441 added logic to include an EditorState in the next layer tree commit when refocusing an element; this was
     10        done to ensure that after tapping an element that has already been programmatically focused, we still send up-
     11        to-date editor information to the UI process for the purposes of zooming to the selection rect, even if the
     12        selection in the DOM is unchanged, since other aspects of the editor state may have changed since the element
     13        was initially focused.
     14
     15        We currently try to flag the next layer tree commit by setting `m_hasPendingEditorStateUpdate` to `true`.
     16        However, this is problematic since we aren't guaranteed in all cases that a compositing flush has been
     17        scheduled. In the case where it hasn't, we'll end up in a state where the editor state update flag has been set,
     18        yet the update will not make it over to the UI process until something happens that forces a layer tree commit
     19        (e.g. scrolling, pinch zooming). Worse still, if the selection is then programmatically changed from the web
     20        process, we will bail from sending a subsequent editor state update to the UI process because `WebPage` thinks
     21        that a pending editor state has already been scheduled. This manifests in selection UI not updating after
     22        tapping "Select All" in the callout bar, if the callout bar was brought up by tapping near the selection (since
     23        this refocuses the element).
     24
     25        To fix this, we adjust this logic in `WebPage::elementDidRefocus` so that it sets the flag and then schedules a
     26        compositing flush, but only if the user is actually interacting with the focused element (i.e., if the page
     27        calls `focus` repeatedly, we won't continue to schedule compositing flushes).
     28
     29        Test: editing/selection/ios/change-selection-after-tapping-focused-element.html
     30
     31        * WebProcess/WebPage/WebPage.cpp:
     32        (WebKit::WebPage::elementDidRefocus):
     33        (WebKit::WebPage::sendEditorStateUpdate):
     34        (WebKit::WebPage::scheduleFullEditorStateUpdate):
     35
     36        Add a private helper method to schedule an editor state update by setting `m_hasPendingEditorStateUpdate` to
     37        `true` and then scheduling a compositing layer flush. Also, add a FIXME aluding to the fact that scheduling an
     38        entire compositing layer flush to send an editor state update is somewhat wasteful, and should be replaced by
     39        just scheduling this work to be done before the next frame (see: <rdar://problem/36523583> for more detail).
     40
     41        We also use this helper method in a few places where we currently turn on the editor state flag and schedule a
     42        subsequent compositing flush.
     43
     44        (WebKit::WebPage::sendPartialEditorStateAndSchedulePostLayoutUpdate):
     45        * WebProcess/WebPage/WebPage.h:
     46
    1472019-01-02  Commit Queue  <commit-queue@webkit.org>
    248
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r239535 r239573  
    52825282{
    52835283    elementDidFocus(element);
    5284     m_hasPendingEditorStateUpdate = true;
     5284
     5285    if (m_isFocusingElementDueToUserInteraction)
     5286        scheduleFullEditorStateUpdate();
    52855287}
    52865288
     
    58755877    send(Messages::WebPageProxy::EditorStateChanged(state), pageID());
    58765878
    5877     if (state.isMissingPostLayoutData) {
    5878         m_hasPendingEditorStateUpdate = true;
    5879         m_drawingArea->scheduleCompositingLayerFlush();
    5880     }
     5879    if (state.isMissingPostLayoutData)
     5880        scheduleFullEditorStateUpdate();
     5881}
     5882
     5883void WebPage::scheduleFullEditorStateUpdate()
     5884{
     5885    if (m_hasPendingEditorStateUpdate)
     5886        return;
     5887
     5888    m_hasPendingEditorStateUpdate = true;
     5889    // FIXME: Scheduling a compositing layer flush here can be more expensive than necessary.
     5890    // Instead, we should just compute and send post-layout editor state during the next frame.
     5891    m_drawingArea->scheduleCompositingLayerFlush();
    58815892}
    58825893
     
    59105921
    59115922    send(Messages::WebPageProxy::EditorStateChanged(editorState(IncludePostLayoutDataHint::No)), pageID());
    5912 
    5913     if (m_hasPendingEditorStateUpdate)
    5914         return;
    5915 
    5916     // Flag the next layer flush to compute and propagate an EditorState to the UI process.
    5917     m_hasPendingEditorStateUpdate = true;
    5918     m_drawingArea->scheduleCompositingLayerFlush();
     5923    scheduleFullEditorStateUpdate();
    59195924}
    59205925
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.h

    r239454 r239573  
    11481148    void platformEditorState(WebCore::Frame&, EditorState& result, IncludePostLayoutDataHint) const;
    11491149    void sendEditorStateUpdate();
     1150    void scheduleFullEditorStateUpdate();
    11501151
    11511152#if PLATFORM(COCOA)
Note: See TracChangeset for help on using the changeset viewer.