⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 179578 in webkit


Ignore:
Timestamp:
Feb 3, 2015, 4:18:40 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

[iOS] Selection Callout should not immediately disappear on pages with frequent layouts
https://bugs.webkit.org/show_bug.cgi?id=141210

Patch by Joseph Pecoraro <Joseph Pecoraro> on 2015-02-03
Reviewed by Enrica Casucci.

In iOS WebKit2 in order to keep caret refreshes in sync with WebCore layouts
the selection assistant is told to update whenever WebKit's layer tree
commits. Unfortunately, for pages with JavaScript animation that are
frequently doing a layout / layer tree update, this would trigger very
frequent selection updates that would keep the caret from blinking and
dismiss any selection callouts.

This change tracks the last selection drawing information so that we can
avoid informing the assistant of a selection updates unless it has changed
visually or needs to redraw (zoom).

  • Shared/EditorState.cpp:

Remove include already in header.

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

(WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):
(WebKit::operator==):
(WebKit::operator!=):
(-[WKContentView observeValueForKeyPath:ofObject:change:context:]):
When zooming, force the selection update, even though the drawing
information hasn't changed, the views will need to be updated.

(-[WKContentView _updateChangedSelection]):
(-[WKContentView _updateChangedSelection:]):
Monitor EditorState for changes in selection drawing and avoid
informing the selection assistant unless necessary.

Location:
trunk/Source/WebKit2
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r179574 r179578  
     12015-02-03  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        [iOS] Selection Callout should not immediately disappear on pages with frequent layouts
     4        https://bugs.webkit.org/show_bug.cgi?id=141210
     5
     6        Reviewed by Enrica Casucci.
     7
     8        In iOS WebKit2 in order to keep caret refreshes in sync with WebCore layouts
     9        the selection assistant is told to update whenever WebKit's layer tree
     10        commits. Unfortunately, for pages with JavaScript animation that are
     11        frequently doing a layout / layer tree update, this would trigger very
     12        frequent selection updates that would keep the caret from blinking and
     13        dismiss any selection callouts.
     14
     15        This change tracks the last selection drawing information so that we can
     16        avoid informing the assistant of a selection updates unless it has changed
     17        visually or needs to redraw (zoom).
     18
     19        * Shared/EditorState.cpp:
     20        Remove include already in header.
     21
     22        * UIProcess/ios/WKContentViewInteraction.h:
     23        * UIProcess/ios/WKContentViewInteraction.mm:
     24        (WebKit::WKSelectionDrawingInfo::WKSelectionDrawingInfo):
     25        (WebKit::operator==):
     26        (WebKit::operator!=):
     27        (-[WKContentView observeValueForKeyPath:ofObject:change:context:]):
     28        When zooming, force the selection update, even though the drawing
     29        information hasn't changed, the views will need to be updated.
     30
     31        (-[WKContentView _updateChangedSelection]):
     32        (-[WKContentView _updateChangedSelection:]):
     33        Monitor EditorState for changes in selection drawing and avoid
     34        informing the selection assistant unless necessary.
     35
    1362015-02-03  Jeremy Jones  <jeremyj@apple.com>
    237
  • trunk/Source/WebKit2/Shared/EditorState.cpp

    r171203 r179578  
    2929#include "Arguments.h"
    3030#include "WebCoreArgumentCoders.h"
    31 
    32 #if PLATFORM(IOS)
    33 #include <WebCore/SelectionRect.h>
    34 #endif
    3531
    3632namespace WebKit {
  • trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h

    r178080 r179578  
    2929
    3030#import "AssistedNodeInformation.h"
     31#import "EditorState.h"
    3132#import "GestureTypes.h"
    3233#import "InteractionInformationAtPosition.h"
     
    7273
    7374namespace WebKit {
     75struct WKSelectionDrawingInfo {
     76    enum class SelectionType { None, Plugin, Range };
     77    WKSelectionDrawingInfo();
     78    explicit WKSelectionDrawingInfo(const EditorState&);
     79    SelectionType type;
     80    WebCore::IntRect caretRect;
     81    Vector<WebCore::SelectionRect> selectionRects;
     82};
    7483struct WKAutoCorrectionData {
    7584    String fontName;
     
    129138
    130139    CGPoint _lastInteractionLocation;
     140
     141    WebKit::WKSelectionDrawingInfo _lastSelectionDrawingInfo;
    131142
    132143    BOOL _isEditable;
  • trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm

    r178980 r179578  
    6666using namespace WebKit;
    6767
     68namespace WebKit {
     69
     70WKSelectionDrawingInfo::WKSelectionDrawingInfo()
     71    : type(SelectionType::None)
     72{
     73}
     74
     75WKSelectionDrawingInfo::WKSelectionDrawingInfo(const EditorState& editorState)
     76{
     77    if (editorState.selectionIsNone) {
     78        type = SelectionType::None;
     79        return;
     80    }
     81
     82    if (editorState.isInPlugin) {
     83        type = SelectionType::Plugin;
     84        return;
     85    }
     86
     87    type = SelectionType::Range;
     88    caretRect = editorState.caretRectAtEnd;
     89    selectionRects = editorState.selectionRects;
     90}
     91
     92inline bool operator==(const WKSelectionDrawingInfo& a, const WKSelectionDrawingInfo& b)
     93{
     94    if (a.type != b.type)
     95        return false;
     96
     97    if (a.type == WKSelectionDrawingInfo::SelectionType::Range) {
     98        if (a.caretRect != b.caretRect)
     99            return false;
     100
     101        if (a.selectionRects.size() != b.selectionRects.size())
     102            return false;
     103
     104        for (unsigned i = 0; i < a.selectionRects.size(); ++i) {
     105            if (a.selectionRects[i].rect() != b.selectionRects[i].rect())
     106                return false;
     107        }
     108    }
     109
     110    return true;
     111}
     112
     113inline bool operator!=(const WKSelectionDrawingInfo& a, const WKSelectionDrawingInfo& b)
     114{
     115    return !(a == b);
     116}
     117
     118} // namespace WebKit
     119
    68120static const float highlightDelay = 0.12;
    69121static const float tapAndHoldDelay  = 0.75;
     
    383435
    384436    _selectionNeedsUpdate = YES;
    385     [self _updateChangedSelection];
     437    [self _updateChangedSelection:YES];
    386438    [self _updateTapHighlight];
    387439}
     
    27562808- (void)_updateChangedSelection
    27572809{
     2810    [self _updateChangedSelection:NO];
     2811}
     2812
     2813- (void)_updateChangedSelection:(BOOL)force
     2814{
    27582815    if (!_selectionNeedsUpdate)
    27592816        return;
     2817
     2818    WKSelectionDrawingInfo selectionDrawingInfo(_page->editorState());
     2819    if (!force && selectionDrawingInfo == _lastSelectionDrawingInfo)
     2820        return;
     2821
     2822    _lastSelectionDrawingInfo = selectionDrawingInfo;
    27602823
    27612824    // FIXME: We need to figure out what to do if the selection is changed by Javascript.
Note: See TracChangeset for help on using the changeset viewer.