diff options
| author | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-15 16:08:57 +0200 |
| commit | 5466563f4b5b6b86523e3f89bb7f77e5b5270c78 (patch) | |
| tree | 8caccf7cd03a15207cde3ba282c88bf132482a91 /Source/WebKit/chromium/src/WebViewImpl.cpp | |
| parent | 33b26980cb24288b5a9f2590ccf32a949281bb79 (diff) | |
| download | qtwebkit-5466563f4b5b6b86523e3f89bb7f77e5b5270c78.tar.gz | |
Imported WebKit commit 0dc6cd75e1d4836eaffbb520be96fac4847cc9d2 (http://svn.webkit.org/repository/webkit/trunk@131300)
WebKit update which introduces the QtWebKitWidgets module that contains the WK1
widgets based API. (In fact it renames QtWebKit to QtWebKitWidgets while we're
working on completing the entire split as part of
https://bugs.webkit.org/show_bug.cgi?id=99314
Diffstat (limited to 'Source/WebKit/chromium/src/WebViewImpl.cpp')
| -rw-r--r-- | Source/WebKit/chromium/src/WebViewImpl.cpp | 400 |
1 files changed, 250 insertions, 150 deletions
diff --git a/Source/WebKit/chromium/src/WebViewImpl.cpp b/Source/WebKit/chromium/src/WebViewImpl.cpp index 261f7c357..d6bf94b96 100644 --- a/Source/WebKit/chromium/src/WebViewImpl.cpp +++ b/Source/WebKit/chromium/src/WebViewImpl.cpp @@ -92,7 +92,6 @@ #include "PageGroupLoadDeferrer.h" #include "PagePopupClient.h" #include "PageWidgetDelegate.h" -#include "Pasteboard.h" #include "PlatformContextSkia.h" #include "PlatformKeyboardEvent.h" #include "PlatformMouseEvent.h" @@ -192,13 +191,19 @@ using namespace std; // (such as due to a double tap gesture or find in page etc.). These are // experimentally determined. static const int touchPointPadding = 32; +static const int nonUserInitiatedPointPadding = 11; static const float minScaleDifference = 0.01f; static const float doubleTapZoomContentDefaultMargin = 5; static const float doubleTapZoomContentMinimumMargin = 2; static const double doubleTapZoomAnimationDurationInSeconds = 0.25; +static const float doubleTapZoomAlreadyLegibleRatio = 1.2f; // Constants for zooming in on a focused text field. static const double scrollAndScaleAnimationDurationInSeconds = 0.2; +static const int minReadableCaretHeight = 18; +static const float minScaleChangeToTriggerZoom = 1.05f; +static const float leftBoxRatio = 0.3f; +static const int caretPadding = 10; namespace WebKit { @@ -209,8 +214,8 @@ namespace WebKit { const double WebView::textSizeMultiplierRatio = 1.2; const double WebView::minTextSizeMultiplier = 0.5; const double WebView::maxTextSizeMultiplier = 3.0; -const float WebView::minPageScaleFactor = 0.25; -const float WebView::maxPageScaleFactor = 4.0; +const float WebView::minPageScaleFactor = 0.25f; +const float WebView::maxPageScaleFactor = 4.0f; // The group name identifies a namespace of pages. Page group is used on PLATFORM(MAC) @@ -392,6 +397,8 @@ WebViewImpl::WebViewImpl(WebViewClient* client) , m_ignoreViewportTagMaximumScale(false) , m_pageScaleFactorIsSet(false) , m_savedPageScaleFactor(0) + , m_doubleTapZoomInEffect(false) + , m_shouldUseDoubleTapTimeZero(false) , m_contextMenuAllowed(false) , m_doingDragAndDrop(false) , m_ignoreInputEvents(false) @@ -622,39 +629,6 @@ void WebViewImpl::mouseContextMenu(const WebMouseEvent& event) void WebViewImpl::handleMouseUp(Frame& mainFrame, const WebMouseEvent& event) { -#if OS(UNIX) && !OS(DARWIN) - // If the event was a middle click, attempt to copy text into the focused - // frame. We execute this before we let the page have a go at the event - // because the page may change what is focused during in its event handler. - // - // This code is in the mouse up handler. There is some debate about putting - // this here, as opposed to the mouse down handler. - // xterm: pastes on up. - // GTK: pastes on down. - // Firefox: pastes on up. - // Midori: couldn't paste at all with 0.1.2 - // - // There is something of a webcompat angle to this well, as highlighted by - // crbug.com/14608. Pages can clear text boxes 'onclick' and, if we paste on - // down then the text is pasted just before the onclick handler runs and - // clears the text box. So it's important this happens after the - // handleMouseReleaseEvent() earlier in this function - if (event.button == WebMouseEvent::ButtonMiddle) { - Frame* focused = focusedWebCoreFrame(); - FrameView* view = m_page->mainFrame()->view(); - IntPoint clickPoint(m_lastMouseDownPoint.x, m_lastMouseDownPoint.y); - IntPoint contentPoint = view->windowToContents(clickPoint); - HitTestResult hitTestResult = focused->eventHandler()->hitTestResultAtPoint(contentPoint, false, false, ShouldHitTestScrollbars); - // We don't want to send a paste when middle clicking a scroll bar or a - // link (which will navigate later in the code). The main scrollbars - // have to be handled separately. - if (!hitTestResult.scrollbar() && !hitTestResult.isLiveLink() && focused && !view->scrollbarAtPoint(clickPoint)) { - Editor* editor = focused->editor(); - editor->command(AtomicString("PasteGlobalSelection")).execute(); - } - } -#endif - PageWidgetEventHandler::handleMouseUp(mainFrame, event); #if OS(WINDOWS) @@ -689,6 +663,29 @@ void WebViewImpl::scrollBy(const WebCore::IntPoint& delta) bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event) { bool eventSwallowed = false; + + // Handle link highlighting outside the main switch to avoid getting lost in the + // complicated set of cases handled below. + switch (event.type) { + case WebInputEvent::GestureTapDown: + // Queue a highlight animation, then hand off to regular handler. +#if OS(LINUX) + if (settingsImpl()->gestureTapHighlightEnabled()) + enableTouchHighlight(IntPoint(event.x, event.y)); +#endif + break; + case WebInputEvent::GestureTapCancel: + if (m_linkHighlight) + m_linkHighlight->startHighlightAnimationIfNeeded(); + break; + case WebInputEvent::GestureTap: + // If a link highlight is active, kill it. + m_linkHighlight.clear(); + break; + default: + break; + } + switch (event.type) { case WebInputEvent::GestureFlingStart: { m_client->cancelScheduledContentIntents(); @@ -710,7 +707,7 @@ bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event) break; case WebInputEvent::GestureTap: { m_client->cancelScheduledContentIntents(); - if (detectContentOnTouch(WebPoint(event.x, event.y), event.type)) { + if (detectContentOnTouch(WebPoint(event.x, event.y))) { eventSwallowed = true; break; } @@ -745,37 +742,42 @@ bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event) break; } - case WebInputEvent::GestureTwoFingerTap: - case WebInputEvent::GestureLongPress: { + case WebInputEvent::GestureTwoFingerTap: { if (!mainFrameImpl() || !mainFrameImpl()->frameView()) break; - m_client->cancelScheduledContentIntents(); - if (detectContentOnTouch(WebPoint(event.x, event.y), event.type)) { - eventSwallowed = true; + m_page->contextMenuController()->clearContextMenu(); + m_contextMenuAllowed = true; + PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event); + eventSwallowed = mainFrameImpl()->frame()->eventHandler()->sendContextMenuEventForGesture(platformEvent); + m_contextMenuAllowed = false; + + break; + } + case WebInputEvent::GestureLongPress: { + if (!mainFrameImpl() || !mainFrameImpl()->frameView()) break; - } + m_client->cancelScheduledContentIntents(); m_page->contextMenuController()->clearContextMenu(); m_contextMenuAllowed = true; PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event); - eventSwallowed = mainFrameImpl()->frame()->eventHandler()->sendContextMenuEventForGesture(platformEvent); + eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGestureEvent(platformEvent); m_contextMenuAllowed = false; break; } case WebInputEvent::GestureTapDown: { m_client->cancelScheduledContentIntents(); - // Queue a highlight animation, then hand off to regular handler. -#if OS(LINUX) - if (settingsImpl()->gestureTapHighlightEnabled()) - enableTouchHighlight(IntPoint(event.x, event.y)); -#endif PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event); eventSwallowed = mainFrameImpl()->frame()->eventHandler()->handleGestureEvent(platformEvent); break; } case WebInputEvent::GestureDoubleTap: + m_client->cancelScheduledContentIntents(); + animateZoomAroundPoint(WebPoint(event.x, event.y), DoubleTap); + eventSwallowed = true; + break; case WebInputEvent::GestureScrollBegin: case WebInputEvent::GesturePinchBegin: m_client->cancelScheduledContentIntents(); @@ -815,17 +817,15 @@ void WebViewImpl::renderingStats(WebRenderingStats& stats) const void WebViewImpl::startPageScaleAnimation(const IntPoint& targetPosition, bool useAnchor, float newScale, double durationInSeconds) { - if (!m_layerTreeView) - return; - - IntPoint clampedPoint = targetPosition; + WebPoint clampedPoint = targetPosition; if (!useAnchor) clampedPoint = clampOffsetAtScale(targetPosition, newScale); - - if (!durationInSeconds && !useAnchor) { + if ((!durationInSeconds && !useAnchor) || m_shouldUseDoubleTapTimeZero) { setPageScaleFactor(newScale, clampedPoint); return; } + if (!m_layerTreeView) + return; m_layerTreeView->startPageScaleAnimation(targetPosition, useAnchor, newScale, durationInSeconds); } @@ -1075,24 +1075,37 @@ WebRect WebViewImpl::widenRectWithinPageBounds(const WebRect& source, int target return WebRect(newX, source.y, newWidth, source.height); } -void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZoomType zoomType, float& scale, WebPoint& scroll) +void WebViewImpl::shouldUseAnimateDoubleTapTimeZeroForTesting(bool setToZero) +{ + m_shouldUseDoubleTapTimeZero = setToZero; +} + +void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZoomType zoomType, float& scale, WebPoint& scroll, bool& isAnchor) { scale = pageScaleFactor(); scroll.x = scroll.y = 0; WebRect targetRect = hitRect; + // Padding only depends on page scale when triggered by manually tapping + int padding = (zoomType == DoubleTap) ? touchPointPadding : nonUserInitiatedPointPadding; if (targetRect.isEmpty()) - targetRect.width = targetRect.height = touchPointPadding; - + targetRect.width = targetRect.height = padding; WebRect rect = computeBlockBounds(targetRect, zoomType); + if (zoomType == FindInPage && rect.isEmpty()) { + // Keep current scale (no need to scroll as x,y will normally already + // be visible). FIXME: Revisit this if it isn't always true. + return; + } - const float overviewScale = m_minimumPageScaleFactor; bool scaleUnchanged = true; if (!rect.isEmpty()) { // Pages should be as legible as on desktop when at dpi scale, so no // need to zoom in further when automatically determining zoom level // (after double tap, find in page, etc), though the user should still // be allowed to manually pinch zoom in further if they desire. - const float maxScale = deviceScaleFactor(); + const float defaultScaleWhenAlreadyLegible = m_minimumPageScaleFactor * doubleTapZoomAlreadyLegibleRatio; + float legibleScale = deviceScaleFactor(); + if (legibleScale < defaultScaleWhenAlreadyLegible) + legibleScale = (scale == m_minimumPageScaleFactor) ? defaultScaleWhenAlreadyLegible : m_minimumPageScaleFactor; const float defaultMargin = doubleTapZoomContentDefaultMargin * deviceScaleFactor(); const float minimumMargin = doubleTapZoomContentMinimumMargin * deviceScaleFactor(); @@ -1105,55 +1118,61 @@ void WebViewImpl::computeScaleAndScrollForHitRect(const WebRect& hitRect, AutoZo rect = widenRectWithinPageBounds(rect, static_cast<int>(defaultMargin * rect.width / m_size.width), static_cast<int>(minimumMargin * rect.width / m_size.width)); - // Fit block to screen, respecting limits. scale *= static_cast<float>(m_size.width) / rect.width; - scale = min(scale, maxScale); + scale = min(scale, legibleScale); scale = clampPageScaleFactorToLimits(scale); scaleUnchanged = fabs(pageScaleFactor() - scale) < minScaleDifference; } - if (zoomType == DoubleTap) { - if (rect.isEmpty() || scaleUnchanged) { - // Zoom out to overview mode. - if (overviewScale) - scale = overviewScale; - return; - } - } else if (rect.isEmpty()) { - // Keep current scale (no need to scroll as x,y will normally already - // be visible). FIXME: Revisit this if it isn't always true. - return; - } - - // FIXME: If this is being called for auto zoom during find in page, - // then if the user manually zooms in it'd be nice to preserve the relative - // increase in zoom they caused (if they zoom out then it's ok to zoom - // them back in again). This isn't compatible with our current double-tap - // zoom strategy (fitting the containing block to the screen) though. - - float screenHeight = m_size.height / scale * pageScaleFactor(); - float screenWidth = m_size.width / scale * pageScaleFactor(); - - // Scroll to vertically align the block. - if (rect.height < screenHeight) { - // Vertically center short blocks. - rect.y -= 0.5 * (screenHeight - rect.height); + if (zoomType == DoubleTap && (rect.isEmpty() || scaleUnchanged || m_doubleTapZoomInEffect)) { + // Zoom out to minimum scale. + scale = m_minimumPageScaleFactor; + scroll = WebPoint(hitRect.x, hitRect.y); + isAnchor = true; + m_doubleTapZoomInEffect = false; } else { - // Ensure position we're zooming to (+ padding) isn't off the bottom of - // the screen. - rect.y = max<float>(rect.y, hitRect.y + touchPointPadding - screenHeight); - } // Otherwise top align the block. - - // Do the same thing for horizontal alignment. - if (rect.width < screenWidth) - rect.x -= 0.5 * (screenWidth - rect.width); - else - rect.x = max<float>(rect.x, hitRect.x + touchPointPadding - screenWidth); + if (zoomType == DoubleTap && scale != m_minimumPageScaleFactor) + m_doubleTapZoomInEffect = true; + else + m_doubleTapZoomInEffect = false; + // FIXME: If this is being called for auto zoom during find in page, + // then if the user manually zooms in it'd be nice to preserve the + // relative increase in zoom they caused (if they zoom out then it's ok + // to zoom them back in again). This isn't compatible with our current + // double-tap zoom strategy (fitting the containing block to the screen) + // though. + + float screenHeight = m_size.height / scale * pageScaleFactor(); + float screenWidth = m_size.width / scale * pageScaleFactor(); + + // Scroll to vertically align the block. + if (rect.height < screenHeight) { + // Vertically center short blocks. + rect.y -= 0.5 * (screenHeight - rect.height); + } else { + // Ensure position we're zooming to (+ padding) isn't off the bottom of + // the screen. + rect.y = max<float>(rect.y, hitRect.y + padding - screenHeight); + } // Otherwise top align the block. + + // Do the same thing for horizontal alignment. + if (rect.width < screenWidth) + rect.x -= 0.5 * (screenWidth - rect.width); + else + rect.x = max<float>(rect.x, hitRect.x + padding - screenWidth); + scroll.x = rect.x; + scroll.y = rect.y; + isAnchor = false; + } - scroll.x = rect.x; - scroll.y = rect.y; + scale = clampPageScaleFactorToLimits(scale); + scroll = mainFrameImpl()->frameView()->windowToContents(scroll); + float scaleDelta = scale / pageScaleFactor(); + scroll = WebPoint(scroll.x * scaleDelta, scroll.y * scaleDelta); + if (!isAnchor) + scroll = clampOffsetAtScale(scroll, scale); } static bool highlightConditions(Node* node) @@ -1179,10 +1198,10 @@ Node* WebViewImpl::bestTouchLinkNode(IntPoint touchEventLocation) while (bestTouchNode && !highlightConditions(bestTouchNode)) bestTouchNode = bestTouchNode->parentNode(); - // If the document has click handlers installed, we don't want to default to applying the highlight to the entire RenderView, or the - // entire body. Also, if the node has non-auto Z-index, we cannot be sure of it's ordering with respect to other possible target nodes. + // If the document/body have click handlers installed, we don't want to default to applying the highlight to the entire RenderView, or the + // entire body. RenderObject* touchNodeRenderer = bestTouchNode ? bestTouchNode->renderer() : 0; - if (bestTouchNode && (!touchNodeRenderer || touchNodeRenderer->isRenderView() || touchNodeRenderer->isBody() || !touchNodeRenderer->style()->hasAutoZIndex())) + if (bestTouchNode && (!touchNodeRenderer || touchNodeRenderer->isRenderView() || touchNodeRenderer->isBody())) return 0; return bestTouchNode; @@ -1206,7 +1225,6 @@ void WebViewImpl::enableTouchHighlight(IntPoint touchEventLocation) return; m_linkHighlight = LinkHighlight::create(touchNode, this); - m_linkHighlight->startHighlightAnimation(); } #endif @@ -1219,11 +1237,13 @@ void WebViewImpl::animateZoomAroundPoint(const IntPoint& point, AutoZoomType zoo float scale; WebPoint scroll; - computeScaleAndScrollForHitRect(WebRect(point.x(), point.y(), 0, 0), zoomType, scale, scroll); + bool isAnchor; + WebPoint webPoint = point; + computeScaleAndScrollForHitRect(WebRect(webPoint.x, webPoint.y, 0, 0), zoomType, scale, scroll, isAnchor); bool isDoubleTap = (zoomType == DoubleTap); - double durationInSeconds = isDoubleTap ? doubleTapZoomAnimationDurationInSeconds : 0; - startPageScaleAnimation(scroll, isDoubleTap, scale, durationInSeconds); + double durationInSeconds = (isDoubleTap && !m_shouldUseDoubleTapTimeZero) ? doubleTapZoomAnimationDurationInSeconds : 0; + startPageScaleAnimation(scroll, isAnchor, scale, durationInSeconds); #endif } @@ -1555,9 +1575,9 @@ void WebViewImpl::resize(const WebSize& newSize) #endif WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate(); - if (agentPrivate && agentPrivate->metricsOverridden()) - agentPrivate->webViewResized(); - else { + if (agentPrivate) + agentPrivate->webViewResized(newSize); + if (!agentPrivate || !agentPrivate->metricsOverridden()) { WebFrameImpl* webFrame = mainFrameImpl(); if (webFrame->frameView()) webFrame->frameView()->resize(newSize.width, newSize.height); @@ -1723,13 +1743,6 @@ void WebViewImpl::updateAnimations(double monotonicFrameBeginTime) #if ENABLE(REQUEST_ANIMATION_FRAME) TRACE_EVENT0("webkit", "WebViewImpl::updateAnimations"); - WebFrameImpl* webframe = mainFrameImpl(); - if (!webframe) - return; - FrameView* view = webframe->frameView(); - if (!view) - return; - // Create synthetic wheel events as necessary for fling. if (m_gestureAnimation) { if (m_gestureAnimation->animate(monotonicFrameBeginTime)) @@ -1738,6 +1751,9 @@ void WebViewImpl::updateAnimations(double monotonicFrameBeginTime) m_gestureAnimation.clear(); } + if (!m_page) + return; + PageWidgetDelegate::animate(m_page.get(), monotonicFrameBeginTime); #endif } @@ -2628,8 +2644,78 @@ void WebViewImpl::scrollFocusedNodeIntoRect(const WebRect& rect) Node* focusedNode = focusedWebCoreNode(); if (!frame || !frame->view() || !focusedNode || !focusedNode->isElementNode()) return; - Element* elementNode = static_cast<Element*>(focusedNode); - frame->view()->scrollElementToRect(elementNode, IntRect(rect.x, rect.y, rect.width, rect.height)); + + if (!m_webSettings->autoZoomFocusedNodeToLegibleScale()) { + Element* elementNode = static_cast<Element*>(focusedNode); + frame->view()->scrollElementToRect(elementNode, IntRect(rect.x, rect.y, rect.width, rect.height)); + return; + } + +#if ENABLE(GESTURE_EVENTS) + focusedNode->document()->updateLayoutIgnorePendingStylesheets(); + + // 'caret' is rect encompassing the blinking cursor. + IntRect textboxRect = focusedNode->document()->view()->contentsToWindow(pixelSnappedIntRect(focusedNode->Node::boundingBox())); + WebRect caret, end; + selectionBounds(caret, end); + + // Pick a scale which is reasonably readable. This is the scale at which + // the caret height will become minReadableCaretHeight (adjusted for dpi + // and font scale factor). + float targetScale = deviceScaleFactor(); +#if ENABLE(TEXT_AUTOSIZING) + if (page() && page()->settings()) + targetScale *= page()->settings()->textAutosizingFontScaleFactor(); +#endif + const float newScale = clampPageScaleFactorToLimits(pageScaleFactor() * minReadableCaretHeight * targetScale / caret.height); + const float deltaScale = newScale / pageScaleFactor(); + + // Convert the rects to absolute space in the new scale. + IntRect textboxRectInDocumentCoordinates = textboxRect; + textboxRectInDocumentCoordinates.move(mainFrame()->scrollOffset()); + textboxRectInDocumentCoordinates.scale(deltaScale); + IntRect caretInDocumentCoordinates = caret; + caretInDocumentCoordinates.move(mainFrame()->scrollOffset()); + caretInDocumentCoordinates.scale(deltaScale); + + IntPoint newOffset; + if (textboxRectInDocumentCoordinates.width() <= m_size.width) { + // Field is narrower than screen. Try to leave padding on left so field's + // label is visible, but it's more important to ensure entire field is + // onscreen. + int idealLeftPadding = m_size.width * leftBoxRatio; + int maxLeftPaddingKeepingBoxOnscreen = m_size.width - textboxRectInDocumentCoordinates.width(); + newOffset.setX(textboxRectInDocumentCoordinates.x() - min<int>(idealLeftPadding, maxLeftPaddingKeepingBoxOnscreen)); + } else { + // Field is wider than screen. Try to left-align field, unless caret would + // be offscreen, in which case right-align the caret. + newOffset.setX(max<int>(textboxRectInDocumentCoordinates.x(), caretInDocumentCoordinates.x() + caretInDocumentCoordinates.width() + caretPadding - m_size.width)); + } + if (textboxRectInDocumentCoordinates.height() <= m_size.height) { + // Field is shorter than screen. Vertically center it. + newOffset.setY(textboxRectInDocumentCoordinates.y() - (m_size.height - textboxRectInDocumentCoordinates.height()) / 2); + } else { + // Field is taller than screen. Try to top align field, unless caret would + // be offscreen, in which case bottom-align the caret. + newOffset.setY(max<int>(textboxRectInDocumentCoordinates.y(), caretInDocumentCoordinates.y() + caretInDocumentCoordinates.height() + caretPadding - m_size.height)); + } + + bool needAnimation = false; + // If we are at less than the target zoom level, zoom in. + if (deltaScale > minScaleChangeToTriggerZoom) + needAnimation = true; + // If the caret is offscreen, then animate. + IntRect sizeRect(0, 0, m_size.width, m_size.height); + if (!sizeRect.contains(caret)) + needAnimation = true; + // If the box is partially offscreen and it's possible to bring it fully + // onscreen, then animate. + if (sizeRect.contains(textboxRectInDocumentCoordinates.width(), textboxRectInDocumentCoordinates.height()) && !sizeRect.contains(textboxRect)) + needAnimation = true; + + if (needAnimation) + startPageScaleAnimation(newOffset, false, newScale, scrollAndScaleAnimationDurationInSeconds); +#endif } void WebViewImpl::advanceFocus(bool reverse) @@ -2756,8 +2842,20 @@ void WebViewImpl::setPageScaleFactor(float scaleFactor, const WebPoint& origin) } scaleFactor = clampPageScaleFactorToLimits(scaleFactor); - WebPoint clampedOrigin = clampOffsetAtScale(origin, scaleFactor); - page()->setPageScaleFactor(scaleFactor, clampedOrigin); + WebPoint scrollOffset; + if (!m_page->settings()->applyPageScaleFactorInCompositor()) { + // If page scale is not applied in the compositor, then the scroll offsets should + // be modified by the scale factor. + scrollOffset = clampOffsetAtScale(origin, scaleFactor); + } else { + IntPoint offset = origin; + WebSize contentSize = mainFrame()->contentsSize(); + offset.shrunkTo(IntPoint(contentSize.width - m_size.width, contentSize.height - m_size.height)); + offset.clampNegativeToZero(); + scrollOffset = offset; + } + + page()->setPageScaleFactor(scaleFactor, scrollOffset); m_pageScaleFactorIsSet = true; } @@ -3195,6 +3293,8 @@ void WebViewImpl::sendResizeEventAndRepaint() m_client->didInvalidateRect(damagedRect); } } + if (m_pageOverlays) + m_pageOverlays->update(); } void WebViewImpl::configureAutoResizeMode() @@ -3412,13 +3512,13 @@ void WebView::addUserScript(const WebString& sourceCode, WebView::UserScriptInjectAt injectAt, WebView::UserContentInjectIn injectIn) { - OwnPtr<Vector<String> > patterns = adoptPtr(new Vector<String>); + Vector<String> patterns; for (size_t i = 0; i < patternsIn.size(); ++i) - patterns->append(patternsIn[i]); + patterns.append(patternsIn[i]); PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::createUninitializedWorld()); - pageGroup->addUserScriptToWorld(world.get(), sourceCode, WebURL(), patterns.release(), nullptr, + pageGroup->addUserScriptToWorld(world.get(), sourceCode, WebURL(), patterns, Vector<String>(), static_cast<UserScriptInjectionTime>(injectAt), static_cast<UserContentInjectedFrames>(injectIn)); } @@ -3428,9 +3528,9 @@ void WebView::addUserStyleSheet(const WebString& sourceCode, WebView::UserContentInjectIn injectIn, WebView::UserStyleInjectionTime injectionTime) { - OwnPtr<Vector<String> > patterns = adoptPtr(new Vector<String>); + Vector<String> patterns; for (size_t i = 0; i < patternsIn.size(); ++i) - patterns->append(patternsIn[i]); + patterns.append(patternsIn[i]); PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::createUninitializedWorld()); @@ -3439,7 +3539,7 @@ void WebView::addUserStyleSheet(const WebString& sourceCode, // callers specify this though, since in other cases the caller will probably want "user" level. // // FIXME: It would be nice to populate the URL correctly, instead of passing an empty URL. - pageGroup->addUserStyleSheetToWorld(world.get(), sourceCode, WebURL(), patterns.release(), nullptr, + pageGroup->addUserStyleSheetToWorld(world.get(), sourceCode, WebURL(), patterns, Vector<String>(), static_cast<UserContentInjectedFrames>(injectIn), UserStyleAuthorLevel, static_cast<WebCore::UserStyleInjectionTime>(injectionTime)); @@ -3462,8 +3562,10 @@ void WebViewImpl::didCommitLoad(bool* isNewNavigation, bool isNavigationWithinPa m_newNavigationLoader = 0; #endif m_observedNewNavigation = false; - if (*isNewNavigation && !isNavigationWithinPage) + if (*isNewNavigation && !isNavigationWithinPage) { m_pageScaleFactorIsSet = false; + m_doubleTapZoomInEffect = false; + } // Make sure link highlight from previous page is cleared. m_linkHighlight.clear(); @@ -3757,6 +3859,8 @@ void WebViewImpl::paintRootLayer(GraphicsContext& context, const IntRect& conten if (!page()) return; FrameView* view = page()->mainFrame()->view(); + if (context.platformContext()) + context.platformContext()->setDeviceScaleFactor(page()->deviceScaleFactor()); view->paintContents(&context, contentRect); double paintEnd = currentTime(); double pixelsPerSec = (contentRect.width() * contentRect.height()) / (paintEnd - paintStart); @@ -3776,8 +3880,9 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active) if (!active) { m_isAcceleratedCompositingActive = false; // We need to finish all GL rendering before sending didDeactivateCompositor() to prevent - // flickering when compositing turns off. - if (m_layerTreeView) + // flickering when compositing turns off. This is only necessary if we're not in + // force-compositing-mode. + if (m_layerTreeView && !page()->settings()->forceCompositingMode()) m_layerTreeView->finishAllRendering(); m_client->didDeactivateCompositor(); } else if (m_layerTreeView) { @@ -3921,15 +4026,22 @@ void WebViewImpl::applyScrollAndScale(const WebSize& scrollDelta, float pageScal mainFrameImpl()->frameView()->scrollBy(scrollDelta); } else { // The page scale changed, so apply a scale and scroll in a single - // operation. The old scroll offset (and passed-in delta) are - // in the old coordinate space, so we first need to multiply them - // by the page scale delta. + // operation. WebSize scrollOffset = mainFrame()->scrollOffset(); scrollOffset.width += scrollDelta.width; scrollOffset.height += scrollDelta.height; - WebPoint scaledScrollOffset(scrollOffset.width * pageScaleDelta, - scrollOffset.height * pageScaleDelta); - setPageScaleFactor(pageScaleFactor() * pageScaleDelta, scaledScrollOffset); + + WebPoint scrollPoint(scrollOffset.width, scrollOffset.height); + if (!m_page->settings()->applyPageScaleFactorInCompositor()) { + // The old scroll offset (and passed-in delta) are in the old + // coordinate space, so we first need to multiply them by the page + // scale delta. + scrollPoint.x = scrollPoint.x * pageScaleDelta; + scrollPoint.y = scrollPoint.y * pageScaleDelta; + } + + setPageScaleFactor(pageScaleFactor() * pageScaleDelta, scrollPoint); + m_doubleTapZoomInEffect = false; } } @@ -4020,12 +4132,8 @@ void WebViewImpl::selectAutofillSuggestionAtIndex(unsigned listIndex) m_autofillPopupClient->valueChanged(listIndex); } -bool WebViewImpl::detectContentOnTouch(const WebPoint& position, WebInputEvent::Type touchType) +bool WebViewImpl::detectContentOnTouch(const WebPoint& position) { - ASSERT(touchType == WebInputEvent::GestureTap - || touchType == WebInputEvent::GestureTwoFingerTap - || touchType == WebInputEvent::GestureLongPress); - HitTestResult touchHit = hitTestResultForWindowPos(position); if (touchHit.isContentEditable()) @@ -4038,22 +4146,14 @@ bool WebViewImpl::detectContentOnTouch(const WebPoint& position, WebInputEvent:: // Ignore when tapping on links or nodes listening to click events, unless the click event is on the // body element, in which case it's unlikely that the original node itself was intended to be clickable. for (; node && !node->hasTagName(HTMLNames::bodyTag); node = node->parentNode()) { - if (node->isLink() || (touchType == WebInputEvent::GestureTap - && (node->willRespondToTouchEvents() || node->willRespondToMouseClickEvents()))) { + if (node->isLink() || node->willRespondToTouchEvents() || node->willRespondToMouseClickEvents()) return false; - } } WebContentDetectionResult content = m_client->detectContentAround(touchHit); if (!content.isValid()) return false; - if (touchType != WebInputEvent::GestureTap) { - // Select the detected content as a block. - focusedFrame()->selectRange(content.range()); - return true; - } - m_client->scheduleContentIntent(content.intent()); return true; } |
