Title: [179578] trunk/Source/WebKit2
Revision
179578
Author
[email protected]
Date
2015-02-03 16:18:40 -0800 (Tue, 03 Feb 2015)

Log 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 <[email protected]> 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.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (179577 => 179578)


--- trunk/Source/WebKit2/ChangeLog	2015-02-04 00:07:49 UTC (rev 179577)
+++ trunk/Source/WebKit2/ChangeLog	2015-02-04 00:18:40 UTC (rev 179578)
@@ -1,3 +1,38 @@
+2015-02-03  Joseph Pecoraro  <[email protected]>
+
+        [iOS] Selection Callout should not immediately disappear on pages with frequent layouts
+        https://bugs.webkit.org/show_bug.cgi?id=141210
+
+        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.
+
 2015-02-03  Jeremy Jones  <[email protected]>
 
         Prevent flicker when exiting fullscreen by synchronizing transactions.

Modified: trunk/Source/WebKit2/Shared/EditorState.cpp (179577 => 179578)


--- trunk/Source/WebKit2/Shared/EditorState.cpp	2015-02-04 00:07:49 UTC (rev 179577)
+++ trunk/Source/WebKit2/Shared/EditorState.cpp	2015-02-04 00:18:40 UTC (rev 179578)
@@ -29,10 +29,6 @@
 #include "Arguments.h"
 #include "WebCoreArgumentCoders.h"
 
-#if PLATFORM(IOS)
-#include <WebCore/SelectionRect.h>
-#endif
-
 namespace WebKit {
 
 void EditorState::encode(IPC::ArgumentEncoder& encoder) const

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h (179577 => 179578)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2015-02-04 00:07:49 UTC (rev 179577)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.h	2015-02-04 00:18:40 UTC (rev 179578)
@@ -28,6 +28,7 @@
 #import "WKContentView.h"
 
 #import "AssistedNodeInformation.h"
+#import "EditorState.h"
 #import "GestureTypes.h"
 #import "InteractionInformationAtPosition.h"
 #import "UIKitSPI.h"
@@ -71,6 +72,14 @@
 typedef void (^UIWKSelectionWithDirectionCompletionHandler)(BOOL selectionEndIsMoving);
 
 namespace WebKit {
+struct WKSelectionDrawingInfo {
+    enum class SelectionType { None, Plugin, Range };
+    WKSelectionDrawingInfo();
+    explicit WKSelectionDrawingInfo(const EditorState&);
+    SelectionType type;
+    WebCore::IntRect caretRect;
+    Vector<WebCore::SelectionRect> selectionRects;
+};
 struct WKAutoCorrectionData {
     String fontName;
     CGFloat fontSize;
@@ -129,6 +138,8 @@
 
     CGPoint _lastInteractionLocation;
 
+    WebKit::WKSelectionDrawingInfo _lastSelectionDrawingInfo;
+
     BOOL _isEditable;
     BOOL _showingTextStyleOptions;
     BOOL _hasValidPositionInformation;

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (179577 => 179578)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2015-02-04 00:07:49 UTC (rev 179577)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm	2015-02-04 00:18:40 UTC (rev 179578)
@@ -65,6 +65,58 @@
 using namespace WebCore;
 using namespace WebKit;
 
+namespace WebKit {
+
+WKSelectionDrawingInfo::WKSelectionDrawingInfo()
+    : type(SelectionType::None)
+{
+}
+
+WKSelectionDrawingInfo::WKSelectionDrawingInfo(const EditorState& editorState)
+{
+    if (editorState.selectionIsNone) {
+        type = SelectionType::None;
+        return;
+    }
+
+    if (editorState.isInPlugin) {
+        type = SelectionType::Plugin;
+        return;
+    }
+
+    type = SelectionType::Range;
+    caretRect = editorState.caretRectAtEnd;
+    selectionRects = editorState.selectionRects;
+}
+
+inline bool operator==(const WKSelectionDrawingInfo& a, const WKSelectionDrawingInfo& b)
+{
+    if (a.type != b.type)
+        return false;
+
+    if (a.type == WKSelectionDrawingInfo::SelectionType::Range) {
+        if (a.caretRect != b.caretRect)
+            return false;
+
+        if (a.selectionRects.size() != b.selectionRects.size())
+            return false;
+
+        for (unsigned i = 0; i < a.selectionRects.size(); ++i) {
+            if (a.selectionRects[i].rect() != b.selectionRects[i].rect())
+                return false;
+        }
+    }
+
+    return true;
+}
+
+inline bool operator!=(const WKSelectionDrawingInfo& a, const WKSelectionDrawingInfo& b)
+{
+    return !(a == b);
+}
+
+} // namespace WebKit
+
 static const float highlightDelay = 0.12;
 static const float tapAndHoldDelay  = 0.75;
 const CGFloat minimumTapHighlightRadius = 2.0;
@@ -382,7 +434,7 @@
     }
 
     _selectionNeedsUpdate = YES;
-    [self _updateChangedSelection];
+    [self _updateChangedSelection:YES];
     [self _updateTapHighlight];
 }
 
@@ -2755,9 +2807,20 @@
 
 - (void)_updateChangedSelection
 {
+    [self _updateChangedSelection:NO];
+}
+
+- (void)_updateChangedSelection:(BOOL)force
+{
     if (!_selectionNeedsUpdate)
         return;
 
+    WKSelectionDrawingInfo selectionDrawingInfo(_page->editorState());
+    if (!force && selectionDrawingInfo == _lastSelectionDrawingInfo)
+        return;
+
+    _lastSelectionDrawingInfo = selectionDrawingInfo;
+
     // FIXME: We need to figure out what to do if the selection is changed by _javascript_.
     if (_textSelectionAssistant) {
         _markedText = (_page->editorState().hasComposition) ? _page->editorState().markedText : String();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to