Changeset 245902 in webkit


Ignore:
Timestamp:
May 30, 2019 1:06:38 PM (5 years ago)
Author:
Wenson Hsieh
Message:

Missing caret when focusing an editable field if the selection was set when WKWebView wasn't first responder
https://bugs.webkit.org/show_bug.cgi?id=198356
<rdar://problem/50798593>

Reviewed by Tim Horton.

Source/WebKit:

In this bug, the DOM selection is initially set by script in a web view that is not the first responder. Then,
either the user begins editing by tapping somewhere such that the selection does not change, or an editable
element is programmatically focused and the client allows programmatic focus to show the keyboard. This is
because the selection clipping rect used by the UI process when computing the bounds of the caret view is empty,
causing the entire caret to be clipped.

This is due to two related issues: first, no updated editor state is sent to the UI process after the element is
focused, if the selection has not also changed. This means that while the selection geometry is sent over to the
UI process, the selection clipping rect (a member of the EditorState's PostLayoutData called
"focusedElementRect") becomes stale in the UI process, since the there was no focused element when the
previously computed editor state was sent to the UI process. To fix this, we schedule a full editor state update
when an element is focused, to ensure that the selection is eventually updated in the UI process.

Secondly, even once the editor state update is sent to the UI process, we will actually avoid updating any text
selection views, since there is no change in WKSelectionDrawingInfo, which currently consists of a selection
type, and either a caret rect or a list of selection rects. However, since selection drawing is also affected by
the selection clipping rect, it seems reasonable to add the selection clipping rect to the drawing info, and
trigger a selection update if this selection clipping rect has changed.

  • UIProcess/ios/WKContentViewInteraction.h:
  • UIProcess/ios/WKContentViewInteraction.mm:

(WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):

Add selectionClippingRect to WKSelectionDrawingInfo, and check against it when comparing two drawing infos.

(WebKit::operator==):
(WebKit::operator<<):

  • WebProcess/WebPage/WebPage.cpp:

(WebKit::WebPage::elementDidFocus):

Schedule an editor state update when focusing an element. In many cases, an editor state update has already been
scheduled when focusing an element, so this becomes a no-op; however, in this scenario, it delivers updated
selection clipping rects (i.e. the focused element rect) and other updated information to the UI process.

LayoutTests:

Add a new layout test to exercise this scenario.

  • editing/selection/ios/caret-when-focusing-editable-element-with-selection-expected.txt: Added.
  • editing/selection/ios/caret-when-focusing-editable-element-with-selection.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r245900 r245902  
     12019-05-30  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Missing caret when focusing an editable field if the selection was set when WKWebView wasn't first responder
     4        https://bugs.webkit.org/show_bug.cgi?id=198356
     5        <rdar://problem/50798593>
     6
     7        Reviewed by Tim Horton.
     8
     9        Add a new layout test to exercise this scenario.
     10
     11        * editing/selection/ios/caret-when-focusing-editable-element-with-selection-expected.txt: Added.
     12        * editing/selection/ios/caret-when-focusing-editable-element-with-selection.html: Added.
     13
    1142019-05-30  Zalan Bujtas  <zalan@apple.com>
    215
  • trunk/Source/WebKit/ChangeLog

    r245901 r245902  
     12019-05-30  Wenson Hsieh  <wenson_hsieh@apple.com>
     2
     3        Missing caret when focusing an editable field if the selection was set when WKWebView wasn't first responder
     4        https://bugs.webkit.org/show_bug.cgi?id=198356
     5        <rdar://problem/50798593>
     6
     7        Reviewed by Tim Horton.
     8
     9        In this bug, the DOM selection is initially set by script in a web view that is not the first responder. Then,
     10        either the user begins editing by tapping somewhere such that the selection does not change, or an editable
     11        element is programmatically focused and the client allows programmatic focus to show the keyboard. This is
     12        because the selection clipping rect used by the UI process when computing the bounds of the caret view is empty,
     13        causing the entire caret to be clipped.
     14
     15        This is due to two related issues: first, no updated editor state is sent to the UI process after the element is
     16        focused, if the selection has not also changed. This means that while the selection geometry is sent over to the
     17        UI process, the selection clipping rect (a member of the EditorState's PostLayoutData called
     18        "focusedElementRect") becomes stale in the UI process, since the there was no focused element when the
     19        previously computed editor state was sent to the UI process. To fix this, we schedule a full editor state update
     20        when an element is focused, to ensure that the selection is eventually updated in the UI process.
     21
     22        Secondly, even once the editor state update is sent to the UI process, we will actually avoid updating any text
     23        selection views, since there is no change in WKSelectionDrawingInfo, which currently consists of a selection
     24        type, and either a caret rect or a list of selection rects. However, since selection drawing is also affected by
     25        the selection clipping rect, it seems reasonable to add the selection clipping rect to the drawing info, and
     26        trigger a selection update if this selection clipping rect has changed.
     27
     28        * UIProcess/ios/WKContentViewInteraction.h:
     29        * UIProcess/ios/WKContentViewInteraction.mm:
     30        (WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):
     31
     32        Add selectionClippingRect to WKSelectionDrawingInfo, and check against it when comparing two drawing infos.
     33
     34        (WebKit::operator==):
     35        (WebKit::operator<<):
     36        * WebProcess/WebPage/WebPage.cpp:
     37        (WebKit::WebPage::elementDidFocus):
     38
     39        Schedule an editor state update when focusing an element. In many cases, an editor state update has already been
     40        scheduled when focusing an element, so this becomes a no-op; however, in this scenario, it delivers updated
     41        selection clipping rects (i.e. the focused element rect) and other updated information to the UI process.
     42
    1432019-05-30  David Quesada  <david_quesada@apple.com>
    244
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.h

    r245882 r245902  
    176176    WebCore::IntRect caretRect;
    177177    Vector<WebCore::SelectionRect> selectionRects;
     178    WebCore::IntRect selectionClipRect;
    178179};
    179180
  • trunk/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm

    r245882 r245902  
    196196    caretRect = postLayoutData.caretRectAtEnd;
    197197    selectionRects = postLayoutData.selectionRects;
     198    selectionClipRect = postLayoutData.focusedElementRect;
    198199}
    199200
     
    216217    }
    217218
     219    if (a.type != WKSelectionDrawingInfo::SelectionType::None && a.selectionClipRect != b.selectionClipRect)
     220        return false;
     221
    218222    return true;
    219223}
     
    241245    stream.dumpProperty("caret rect", info.caretRect);
    242246    stream.dumpProperty("selection rects", info.selectionRects);
     247    stream.dumpProperty("selection clip rect", info.selectionClipRect);
    243248    return stream;
    244249}
  • trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp

    r245807 r245902  
    54685468#endif
    54695469        m_recentlyBlurredElement = nullptr;
     5470
     5471        scheduleFullEditorStateUpdate();
    54705472    }
    54715473}
Note: See TracChangeset for help on using the changeset viewer.