diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-17 16:21:14 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-10-17 16:21:14 +0200 |
commit | 8995b83bcbfbb68245f779b64e5517627c6cc6ea (patch) | |
tree | 17985605dab9263cc2444bd4d45f189e142cca7c /Source/WebKit/chromium/src/WebViewImpl.cpp | |
parent | b9c9652036d5e9f1e29c574f40bc73a35c81ace6 (diff) | |
download | qtwebkit-8995b83bcbfbb68245f779b64e5517627c6cc6ea.tar.gz |
Imported WebKit commit cf4f8fc6f19b0629f51860cb2d4b25e139d07e00 (http://svn.webkit.org/repository/webkit/trunk@131592)
New snapshot that includes the build fixes for Mac OS X 10.6 and earlier as well
as the previously cherry-picked changes
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; } |