Changeset 246948 in webkit


Ignore:
Timestamp:
Jun 28, 2019, 8:48:18 PM (6 years ago)
Author:
[email protected]
Message:

iOS WebKit2 find-in-page indicator doesn't move with 'overflow: scroll'
https://bugs.webkit.org/show_bug.cgi?id=175032
<rdar://problem/29346482>

Reviewed by Wenson Hsieh.

Source/WebCore:

  • editing/FrameSelection.cpp:

(WebCore::FrameSelection::selectionBounds const):
(WebCore::FrameSelection::revealSelection):

  • editing/FrameSelection.h:

Make selectionBounds' clipToVisibleContent param an enum class.

  • page/TextIndicator.cpp:

(WebCore::initializeIndicator):
Save the un-clipped selection rect; otherwise we'll frequently save 0, 0
here when finding a match that is off-screen.

Source/WebKit:

  • WebProcess/WebPage/FindController.cpp:

(WebKit::FindController::drawRect):
(WebKit::FindController::didScrollAffectingFindIndicatorPosition):
Adopt the macOS code that notices that the find highlight doesn't match
its original position, but instead of hiding the highlight like we do on macOS,
update it. We do this asynchronously to avoid mutating the layer tree
in the middle of painting, which is not /truly/ unsafe, but definitely
non-ideal and causes fun flashes.

  • WebProcess/WebPage/FindController.h:
  • WebProcess/WebPage/ios/FindControllerIOS.mm:

(WebKit::FindController::updateFindIndicator):
Store m_findIndicatorRect when updating the indicator, just like we do on macOS.

Location:
trunk/Source
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r246943 r246948  
     12019-06-28  Tim Horton  <[email protected]>
     2
     3        iOS WebKit2 find-in-page indicator doesn't move with 'overflow: scroll'
     4        https://bugs.webkit.org/show_bug.cgi?id=175032
     5        <rdar://problem/29346482>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * editing/FrameSelection.cpp:
     10        (WebCore::FrameSelection::selectionBounds const):
     11        (WebCore::FrameSelection::revealSelection):
     12        * editing/FrameSelection.h:
     13        Make selectionBounds' clipToVisibleContent param an enum class.
     14
     15        * page/TextIndicator.cpp:
     16        (WebCore::initializeIndicator):
     17        Save the un-clipped selection rect; otherwise we'll frequently save 0, 0
     18        here when finding a match that is off-screen.
     19
    1202019-06-28  Zalan Bujtas  <[email protected]>
    221
  • trunk/Source/WebCore/editing/FrameSelection.cpp

    r245716 r246948  
    22892289}
    22902290
    2291 FloatRect FrameSelection::selectionBounds(bool clipToVisibleContent) const
     2291FloatRect FrameSelection::selectionBounds(ClipToVisibleContent clipToVisibleContent) const
    22922292{
    22932293    if (!m_frame->document())
     
    23002300
    23012301    auto& selection = renderView->selection();
    2302     auto selectionRect = clipToVisibleContent ? selection.boundsClippedToVisibleContent() : selection.bounds();
    2303     return clipToVisibleContent ? intersection(selectionRect, renderView->frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect)) : selectionRect;
     2302
     2303    if (clipToVisibleContent == ClipToVisibleContent::Yes) {
     2304        auto selectionRect = selection.boundsClippedToVisibleContent();
     2305        return intersection(selectionRect, renderView->frameView().visibleContentRect(ScrollableArea::LegacyIOSDocumentVisibleRect));
     2306    }
     2307
     2308    return selection.bounds();
    23042309}
    23052310
     
    23922397        break;
    23932398    case VisibleSelection::RangeSelection:
    2394         rect = revealExtentOption == RevealExtent ? VisiblePosition(m_selection.extent()).absoluteCaretBounds() : enclosingIntRect(selectionBounds(false));
     2399        rect = revealExtentOption == RevealExtent ? VisiblePosition(m_selection.extent()).absoluteCaretBounds() : enclosingIntRect(selectionBounds(ClipToVisibleContent::No));
    23952400        break;
    23962401    }
  • trunk/Source/WebCore/editing/FrameSelection.h

    r245565 r246948  
    270270    void clearTypingStyle();
    271271
    272     WEBCORE_EXPORT FloatRect selectionBounds(bool clipToVisibleContent = true) const;
     272    enum class ClipToVisibleContent : uint8_t { No, Yes };
     273    WEBCORE_EXPORT FloatRect selectionBounds(ClipToVisibleContent = ClipToVisibleContent::Yes) const;
    273274
    274275    enum class TextRectangleHeight { TextHeight, SelectionHeight };
  • trunk/Source/WebCore/page/TextIndicator.cpp

    r246695 r246948  
    381381    // Store the selection rect in window coordinates, to be used subsequently
    382382    // to determine if the indicator and selection still precisely overlap.
    383     data.selectionRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(frame.selection().selectionBounds()));
     383    data.selectionRectInRootViewCoordinates = frame.view()->contentsToRootView(enclosingIntRect(frame.selection().selectionBounds(FrameSelection::ClipToVisibleContent::No)));
    384384    data.textBoundingRectInRootViewCoordinates = textBoundingRectInRootViewCoordinates;
    385385    data.textRectsInBoundingRectCoordinates = textRectsInBoundingRectCoordinates;
  • trunk/Source/WebKit/ChangeLog

    r246947 r246948  
     12019-06-28  Tim Horton  <[email protected]>
     2
     3        iOS WebKit2 find-in-page indicator doesn't move with 'overflow: scroll'
     4        https://bugs.webkit.org/show_bug.cgi?id=175032
     5        <rdar://problem/29346482>
     6
     7        Reviewed by Wenson Hsieh.
     8
     9        * WebProcess/WebPage/FindController.cpp:
     10        (WebKit::FindController::drawRect):
     11        (WebKit::FindController::didScrollAffectingFindIndicatorPosition):
     12        Adopt the macOS code that notices that the find highlight doesn't match
     13        its original position, but instead of hiding the highlight like we do on macOS,
     14        update it. We do this asynchronously to avoid mutating the layer tree
     15        in the middle of painting, which is not /truly/ unsafe, but definitely
     16        non-ideal and causes fun flashes.
     17
     18        * WebProcess/WebPage/FindController.h:
     19        * WebProcess/WebPage/ios/FindControllerIOS.mm:
     20        (WebKit::FindController::updateFindIndicator):
     21        Store m_findIndicatorRect when updating the indicator, just like we do on macOS.
     22
    1232019-06-28  Ryan Haddad  <[email protected]>
    224
  • trunk/Source/WebKit/WebProcess/WebPage/FindController.cpp

    r239535 r246948  
    500500        graphicsContext.fillPath(path);
    501501
    502     if (!m_isShowingFindIndicator || !shouldHideFindIndicatorOnScroll())
     502    if (!m_isShowingFindIndicator)
    503503        return;
    504504
    505505    if (Frame* selectedFrame = frameWithSelection(m_webPage->corePage())) {
    506         IntRect findIndicatorRect = selectedFrame->view()->contentsToRootView(enclosingIntRect(selectedFrame->selection().selectionBounds()));
    507 
    508         if (findIndicatorRect != m_findIndicatorRect)
    509             hideFindIndicator();
    510     }
     506        IntRect findIndicatorRect = selectedFrame->view()->contentsToRootView(enclosingIntRect(selectedFrame->selection().selectionBounds(FrameSelection::ClipToVisibleContent::No)));
     507
     508        if (findIndicatorRect != m_findIndicatorRect) {
     509            // We are underneath painting, so it's not safe to mutate the layer tree synchronously.
     510            callOnMainThread([weakWebPage = makeWeakPtr(m_webPage)] {
     511                if (!weakWebPage)
     512                    return;
     513                weakWebPage->findController().didScrollAffectingFindIndicatorPosition();
     514            });
     515        }
     516    }
     517}
     518
     519void FindController::didScrollAffectingFindIndicatorPosition()
     520{
     521    if (shouldHideFindIndicatorOnScroll())
     522        hideFindIndicator();
     523    else if (Frame *selectedFrame = frameWithSelection(m_webPage->corePage()))
     524        updateFindIndicator(*selectedFrame, true, false);
    511525}
    512526
  • trunk/Source/WebKit/WebProcess/WebPage/FindController.h

    r238454 r246948  
    9393    unsigned findIndicatorRadius() const;
    9494    bool shouldHideFindIndicatorOnScroll() const;
     95    void didScrollAffectingFindIndicatorPosition();
    9596
    9697    WebPage* m_webPage;
  • trunk/Source/WebKit/WebProcess/WebPage/ios/FindControllerIOS.mm

    r241323 r246948  
    100100
    101101    m_findIndicatorOverlayClient = std::make_unique<FindIndicatorOverlayClientIOS>(selectedFrame, textIndicator.get());
     102    m_findIndicatorRect = enclosingIntRect(textIndicator->selectionRectInRootViewCoordinates());
    102103    m_findIndicatorOverlay = PageOverlay::create(*m_findIndicatorOverlayClient, PageOverlay::OverlayType::Document);
    103104    m_webPage->corePage()->pageOverlayController().installPageOverlay(*m_findIndicatorOverlay, PageOverlay::FadeMode::DoNotFade);
Note: See TracChangeset for help on using the changeset viewer.