summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/src/WebViewImpl.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/WebKit/chromium/src/WebViewImpl.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/WebKit/chromium/src/WebViewImpl.cpp')
-rw-r--r--Source/WebKit/chromium/src/WebViewImpl.cpp589
1 files changed, 354 insertions, 235 deletions
diff --git a/Source/WebKit/chromium/src/WebViewImpl.cpp b/Source/WebKit/chromium/src/WebViewImpl.cpp
index 52a022ce9..4318dc79d 100644
--- a/Source/WebKit/chromium/src/WebViewImpl.cpp
+++ b/Source/WebKit/chromium/src/WebViewImpl.cpp
@@ -31,13 +31,14 @@
#include "config.h"
#include "WebViewImpl.h"
-#include "AutofillPopupMenuClient.h"
#include "AXObjectCache.h"
+#include "ActivePlatformGestureAnimation.h"
+#include "AutofillPopupMenuClient.h"
#include "BackForwardListChromium.h"
-#include "cc/CCProxy.h"
-#include "CSSStyleSelector.h"
+#include "BatteryClientImpl.h"
#include "CSSValueKeywords.h"
#include "Chrome.h"
+#include "Color.h"
#include "ColorSpace.h"
#include "CompositionUnderlineVectorBuilder.h"
#include "ContextMenu.h"
@@ -63,6 +64,7 @@
#include "FrameTree.h"
#include "FrameView.h"
#include "GeolocationClientProxy.h"
+#include "GeolocationController.h"
#include "GraphicsContext.h"
#include "GraphicsContext3D.h"
#include "GraphicsContext3DPrivate.h"
@@ -85,6 +87,8 @@
#include "Page.h"
#include "PageGroup.h"
#include "PageGroupLoadDeferrer.h"
+#include "PagePopupClient.h"
+#include "PageWidgetDelegate.h"
#include "Pasteboard.h"
#include "PlatformContextSkia.h"
#include "PlatformKeyboardEvent.h"
@@ -106,46 +110,55 @@
#include "Settings.h"
#include "SharedGraphicsContext3D.h"
#include "SpeechInputClientImpl.h"
+#include "SpeechRecognitionClientProxy.h"
+#include "StyleResolver.h"
+#include "TextFieldDecoratorImpl.h"
#include "TextIterator.h"
#include "Timer.h"
+#include "TouchpadFlingPlatformGestureCurve.h"
#include "TraceEvent.h"
-#include "TypingCommand.h"
#include "UserGestureIndicator.h"
-#include "Vector.h"
#include "WebAccessibilityObject.h"
+#include "WebActiveWheelFlingParameters.h"
#include "WebAutofillClient.h"
#include "WebCompositorImpl.h"
#include "WebDevToolsAgentImpl.h"
#include "WebDevToolsAgentPrivate.h"
-#include "platform/WebDragData.h"
#include "WebFrameImpl.h"
-#include "platform/WebGraphicsContext3D.h"
-#include "platform/WebImage.h"
#include "WebInputElement.h"
#include "WebInputEvent.h"
#include "WebInputEventConversion.h"
#include "WebKit.h"
-#include "platform/WebKitPlatformSupport.h"
-#include "platform/WebLayer.h"
-#include "platform/WebLayerTreeView.h"
#include "WebMediaPlayerAction.h"
#include "WebNode.h"
+#include "WebPagePopupImpl.h"
#include "WebPlugin.h"
#include "WebPluginAction.h"
#include "WebPluginContainerImpl.h"
-#include "platform/WebPoint.h"
#include "WebPopupMenuImpl.h"
#include "WebRange.h"
-#include "platform/WebRect.h"
#include "WebRuntimeFeatures.h"
#include "WebSettingsImpl.h"
+#include "WebViewClient.h"
+#include "WheelEvent.h"
+#include "cc/CCProxy.h"
+#include "painting/GraphicsContextBuilder.h"
+#include "platform/WebDragData.h"
+#include "platform/WebImage.h"
+#include "platform/WebKitPlatformSupport.h"
#include "platform/WebString.h"
#include "platform/WebVector.h"
-#include "WebViewClient.h"
-#include <wtf/ByteArray.h>
+#include <public/Platform.h>
+#include <public/WebFloatPoint.h>
+#include <public/WebGraphicsContext3D.h>
+#include <public/WebLayer.h>
+#include <public/WebLayerTreeView.h>
+#include <public/WebPoint.h>
+#include <public/WebRect.h>
#include <wtf/CurrentTime.h>
#include <wtf/MainThread.h>
#include <wtf/RefPtr.h>
+#include <wtf/Uint8ClampedArray.h>
#if ENABLE(GESTURE_EVENTS)
#include "PlatformGestureEvent.h"
@@ -176,7 +189,7 @@ 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 float minScaleDifference = 0.01;
+static const float minScaleDifference = 0.01f;
static const float doubleTapZoomContentDefaultMargin = 5;
static const float doubleTapZoomContentMinimumMargin = 2;
@@ -313,6 +326,18 @@ void WebViewImpl::setSpellCheckClient(WebSpellCheckClient* spellCheckClient)
m_spellCheckClient = spellCheckClient;
}
+void WebViewImpl::addTextFieldDecoratorClient(WebTextFieldDecoratorClient* client)
+{
+ ASSERT(client);
+ // We limit the number of decorators because it affects performance of text
+ // field creation. If you'd like to add more decorators, consider moving
+ // your decorator or existing decorators to WebCore.
+ const unsigned maximumNumberOfDecorators = 8;
+ if (m_textFieldDecorators.size() >= maximumNumberOfDecorators)
+ CRASH();
+ m_textFieldDecorators.append(TextFieldDecoratorImpl::create(client));
+}
+
WebViewImpl::WebViewImpl(WebViewClient* client)
: m_client(client)
, m_autofillClient(0)
@@ -349,20 +374,30 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
, m_isTransparent(false)
, m_tabsToLinks(false)
, m_dragScrollTimer(adoptPtr(new DragScrollTimer))
+ , m_isCancelingFullScreen(false)
#if USE(ACCELERATED_COMPOSITING)
, m_rootGraphicsLayer(0)
, m_isAcceleratedCompositingActive(false)
, m_compositorCreationFailed(false)
, m_recreatingGraphicsContext(false)
+ , m_compositorSurfaceReady(false)
#endif
#if ENABLE(INPUT_SPEECH)
, m_speechInputClient(SpeechInputClientImpl::create(client))
#endif
+#if ENABLE(SCRIPTED_SPEECH)
+ , m_speechRecognitionClient(SpeechRecognitionClientProxy::create(client ? client->speechRecognizer() : 0))
+#endif
, m_deviceOrientationClientProxy(adoptPtr(new DeviceOrientationClientProxy(client ? client->deviceOrientationClient() : 0)))
, m_geolocationClientProxy(adoptPtr(new GeolocationClientProxy(client ? client->geolocationClient() : 0)))
+#if ENABLE(BATTERY_STATUS)
+ , m_batteryClient(adoptPtr(new BatteryClientImpl(client ? client->batteryStatusClient() : 0)))
+#endif
+ , m_emulatedTextZoomFactor(1)
#if ENABLE(MEDIA_STREAM)
, m_userMediaClientImpl(this)
#endif
+ , m_flingModifier(0)
{
// WebKit/win/WebView.cpp does the same thing, except they call the
// KJS specific wrapper around this method. We need to have threading
@@ -370,16 +405,12 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
WTF::initializeThreading();
WTF::initializeMainThread();
- // set to impossible point so we always get the first mouse pos
- m_lastMousePosition = WebPoint(-1, -1);
-
Page::PageClients pageClients;
pageClients.chromeClient = &m_chromeClientImpl;
pageClients.contextMenuClient = &m_contextMenuClientImpl;
pageClients.editorClient = &m_editorClientImpl;
pageClients.dragClient = &m_dragClientImpl;
pageClients.inspectorClient = &m_inspectorClientImpl;
- pageClients.geolocationClient = m_geolocationClientProxy.get();
pageClients.backForwardClient = BackForwardListChromium::create(this);
m_page = adoptPtr(new Page(pageClients));
@@ -389,13 +420,21 @@ WebViewImpl::WebViewImpl(WebViewClient* client)
#if ENABLE(INPUT_SPEECH)
provideSpeechInputTo(m_page.get(), m_speechInputClient.get());
#endif
-#if ENABLE(NOTIFICATIONS)
+#if ENABLE(SCRIPTED_SPEECH)
+ provideSpeechRecognitionTo(m_page.get(), m_speechRecognitionClient.get());
+#endif
+#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
provideNotification(m_page.get(), notificationPresenterImpl());
#endif
provideDeviceOrientationTo(m_page.get(), m_deviceOrientationClientProxy.get());
- m_geolocationClientProxy->setController(m_page->geolocationController());
+ provideGeolocationTo(m_page.get(), m_geolocationClientProxy.get());
+ m_geolocationClientProxy->setController(GeolocationController::from(m_page.get()));
+#if ENABLE(BATTERY_STATUS)
+ provideBatteryTo(m_page.get(), m_batteryClient.get());
+#endif
+
m_page->setGroupName(pageGroupName);
#if ENABLE(PAGE_VISIBILITY_API)
@@ -433,38 +472,14 @@ void WebViewImpl::setTabKeyCyclesThroughElements(bool value)
m_page->setTabKeyCyclesThroughElements(value);
}
-void WebViewImpl::mouseMove(const WebMouseEvent& event)
+void WebViewImpl::handleMouseLeave(Frame& mainFrame, const WebMouseEvent& event)
{
- if (!mainFrameImpl() || !mainFrameImpl()->frameView())
- return;
-
- m_lastMousePosition = WebPoint(event.x, event.y);
-
- // We call mouseMoved here instead of handleMouseMovedEvent because we need
- // our ChromeClientImpl to receive changes to the mouse position and
- // tooltip text, and mouseMoved handles all of that.
- mainFrameImpl()->frame()->eventHandler()->mouseMoved(
- PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
-}
-
-void WebViewImpl::mouseLeave(const WebMouseEvent& event)
-{
- // This event gets sent as the main frame is closing. In that case, just
- // ignore it.
- if (!mainFrameImpl() || !mainFrameImpl()->frameView())
- return;
-
m_client->setMouseOverURL(WebURL());
-
- mainFrameImpl()->frame()->eventHandler()->handleMouseMoveEvent(
- PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
+ PageWidgetEventHandler::handleMouseLeave(mainFrame, event);
}
-void WebViewImpl::mouseDown(const WebMouseEvent& event)
+void WebViewImpl::handleMouseDown(Frame& mainFrame, const WebMouseEvent& event)
{
- if (!mainFrameImpl() || !mainFrameImpl()->frameView())
- return;
-
// If there is a select popup open, close it as the user is clicking on
// the page (outside of the popup). We also save it so we can prevent a
// click on the select element from immediately reopening the popup.
@@ -488,8 +503,7 @@ void WebViewImpl::mouseDown(const WebMouseEvent& event)
m_mouseCaptureNode = hitNode;
}
- mainFrameImpl()->frame()->eventHandler()->handleMousePressEvent(
- PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
+ PageWidgetEventHandler::handleMouseDown(mainFrame, event);
if (m_selectPopup && m_selectPopup == selectPopup) {
// That click triggered a select popup which is the same as the one that
@@ -540,11 +554,8 @@ void WebViewImpl::mouseContextMenu(const WebMouseEvent& event)
// implementation...
}
-void WebViewImpl::mouseUp(const WebMouseEvent& event)
+void WebViewImpl::handleMouseUp(Frame& mainFrame, const WebMouseEvent& event)
{
- if (!mainFrameImpl() || !mainFrameImpl()->frameView())
- return;
-
#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
@@ -582,8 +593,7 @@ void WebViewImpl::mouseUp(const WebMouseEvent& event)
}
#endif
- mainFrameImpl()->frame()->eventHandler()->handleMouseReleaseEvent(
- PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event));
+ PageWidgetEventHandler::handleMouseUp(mainFrame, event);
#if OS(WINDOWS)
// Dispatch the contextmenu event regardless of if the click was swallowed.
@@ -593,17 +603,89 @@ void WebViewImpl::mouseUp(const WebMouseEvent& event)
#endif
}
-bool WebViewImpl::mouseWheel(const WebMouseWheelEvent& event)
+void WebViewImpl::scrollBy(const WebCore::IntPoint& delta)
{
- PlatformWheelEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
- return mainFrameImpl()->frame()->eventHandler()->handleWheelEvent(platformEvent);
+ WebMouseWheelEvent syntheticWheel;
+ const float tickDivisor = WebCore::WheelEvent::tickMultiplier;
+
+ syntheticWheel.deltaX = delta.x();
+ syntheticWheel.deltaY = delta.y();
+ syntheticWheel.wheelTicksX = delta.x() / tickDivisor;
+ syntheticWheel.wheelTicksY = delta.y() / tickDivisor;
+ syntheticWheel.hasPreciseScrollingDeltas = true;
+ syntheticWheel.x = m_lastWheelPosition.x;
+ syntheticWheel.y = m_lastWheelPosition.y;
+ syntheticWheel.globalX = m_lastWheelGlobalPosition.x;
+ syntheticWheel.globalY = m_lastWheelGlobalPosition.y;
+ syntheticWheel.modifiers = m_flingModifier;
+
+ if (m_page && m_page->mainFrame() && m_page->mainFrame()->view())
+ handleMouseWheel(*m_page->mainFrame(), syntheticWheel);
}
#if ENABLE(GESTURE_EVENTS)
-bool WebViewImpl::gestureEvent(const WebGestureEvent& event)
+bool WebViewImpl::handleGestureEvent(const WebGestureEvent& event)
+{
+ switch (event.type) {
+ case WebInputEvent::GestureFlingStart: {
+ m_lastWheelPosition = WebPoint(event.x, event.y);
+ m_lastWheelGlobalPosition = WebPoint(event.globalX, event.globalY);
+ m_flingModifier = event.modifiers;
+ // FIXME: Make the curve parametrizable from the browser.
+ m_gestureAnimation = ActivePlatformGestureAnimation::create(TouchpadFlingPlatformGestureCurve::create(FloatPoint(event.deltaX, event.deltaY)), this);
+ scheduleAnimation();
+ return true;
+ }
+ case WebInputEvent::GestureFlingCancel:
+ if (m_gestureAnimation) {
+ m_gestureAnimation.clear();
+ return true;
+ }
+ return false;
+ case WebInputEvent::GestureTap: {
+ PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
+ RefPtr<WebCore::PopupContainer> selectPopup;
+ selectPopup = m_selectPopup;
+ hideSelectPopup();
+ ASSERT(!m_selectPopup);
+ bool gestureHandled = mainFrameImpl()->frame()->eventHandler()->handleGestureEvent(platformEvent);
+ if (m_selectPopup && m_selectPopup == selectPopup) {
+ // That tap triggered a select popup which is the same as the one that
+ // was showing before the tap. It means the user tapped the select
+ // while the popup was showing, and as a result we first closed then
+ // immediately reopened the select popup. It needs to be closed.
+ hideSelectPopup();
+ }
+ return gestureHandled;
+ }
+ case WebInputEvent::GestureScrollBegin:
+ case WebInputEvent::GestureScrollEnd:
+ case WebInputEvent::GestureScrollUpdate:
+ case WebInputEvent::GestureTapDown:
+ case WebInputEvent::GestureDoubleTap:
+ case WebInputEvent::GestureLongPress:
+ case WebInputEvent::GesturePinchBegin:
+ case WebInputEvent::GesturePinchEnd:
+ case WebInputEvent::GesturePinchUpdate: {
+ PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
+ return mainFrameImpl()->frame()->eventHandler()->handleGestureEvent(platformEvent);
+ }
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return false;
+}
+
+void WebViewImpl::transferActiveWheelFlingAnimation(const WebActiveWheelFlingParameters& parameters)
{
- PlatformGestureEventBuilder platformEvent(mainFrameImpl()->frameView(), event);
- return mainFrameImpl()->frame()->eventHandler()->handleGestureEvent(platformEvent);
+ TRACE_EVENT0("webkit", "WebViewImpl::transferActiveWheelFlingAnimation");
+ ASSERT(!m_gestureAnimation);
+ m_lastWheelPosition = parameters.point;
+ m_lastWheelGlobalPosition = parameters.globalPoint;
+ m_flingModifier = parameters.modifiers;
+ OwnPtr<PlatformGestureCurve> curve = TouchpadFlingPlatformGestureCurve::create(parameters.delta, IntPoint(parameters.cumulativeScroll));
+ m_gestureAnimation = ActivePlatformGestureAnimation::create(curve.release(), this, parameters.startTime);
+ scheduleAnimation();
}
void WebViewImpl::startPageScaleAnimation(const IntPoint& scroll, bool useAnchor, float newScale, double durationSec)
@@ -613,12 +695,16 @@ void WebViewImpl::startPageScaleAnimation(const IntPoint& scroll, bool useAnchor
}
#endif
-bool WebViewImpl::keyEvent(const WebKeyboardEvent& event)
+bool WebViewImpl::handleKeyEvent(const WebKeyboardEvent& event)
{
ASSERT((event.type == WebInputEvent::RawKeyDown)
|| (event.type == WebInputEvent::KeyDown)
|| (event.type == WebInputEvent::KeyUp));
+ // Halt an in-progress fling on a key event.
+ if (m_gestureAnimation)
+ m_gestureAnimation.clear();
+
// Please refer to the comments explaining the m_suppressNextKeypressEvent
// member.
// The m_suppressNextKeypressEvent is set if the KeyDown is handled by
@@ -631,6 +717,16 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event)
// not the page.
if (m_selectPopup)
return m_selectPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event));
+#if ENABLE(PAGE_POPUP)
+ if (m_pagePopup) {
+ m_pagePopup->handleKeyEvent(PlatformKeyboardEventBuilder(event));
+ // We need to ignore the next Char event after this otherwise pressing
+ // enter when selecting an item in the popup will go to the page.
+ if (WebInputEvent::RawKeyDown == event.type)
+ m_suppressNextKeypressEvent = true;
+ return true;
+ }
+#endif
// Give Autocomplete a chance to consume the key events it is interested in.
if (autocompleteHandleKeyEvent(event))
@@ -727,7 +823,7 @@ bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event)
return false;
}
-bool WebViewImpl::charEvent(const WebKeyboardEvent& event)
+bool WebViewImpl::handleCharEvent(const WebKeyboardEvent& event)
{
ASSERT(event.type == WebInputEvent::Char);
@@ -743,6 +839,10 @@ bool WebViewImpl::charEvent(const WebKeyboardEvent& event)
// not the page.
if (m_selectPopup)
return m_selectPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event));
+#if ENABLE(PAGE_POPUP)
+ if (m_pagePopup)
+ return m_pagePopup->handleKeyEvent(PlatformKeyboardEventBuilder(event));
+#endif
Frame* frame = focusedWebCoreFrame();
if (!frame)
@@ -773,18 +873,6 @@ bool WebViewImpl::charEvent(const WebKeyboardEvent& event)
return true;
}
-#if ENABLE(TOUCH_EVENTS)
-bool WebViewImpl::touchEvent(const WebTouchEvent& event)
-{
- if (!mainFrameImpl() || !mainFrameImpl()->frameView())
- return false;
-
- PlatformTouchEventBuilder touchEventBuilder(mainFrameImpl()->frameView(), event);
- bool defaultPrevented = mainFrameImpl()->frame()->eventHandler()->handleTouchEvent(touchEventBuilder);
- return defaultPrevented;
-}
-#endif
-
#if ENABLE(GESTURE_EVENTS)
WebRect WebViewImpl::computeBlockBounds(const WebRect& rect, AutoZoomType zoomType)
{
@@ -807,7 +895,7 @@ WebRect WebViewImpl::computeBlockBounds(const WebRect& rect, AutoZoomType zoomTy
// Return the bounding box in the window coordinate system.
if (node) {
- IntRect rect = node->Node::getRect();
+ IntRect rect = node->Node::getPixelSnappedRect();
Frame* frame = node->document()->frame();
return frame->view()->contentsToWindow(rect);
}
@@ -1105,6 +1193,42 @@ void WebViewImpl::popupClosed(WebCore::PopupContainer* popupContainer)
}
}
+#if ENABLE(PAGE_POPUP)
+PagePopup* WebViewImpl::openPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView)
+{
+ ASSERT(client);
+ if (hasOpenedPopup())
+ hidePopups();
+ ASSERT(!m_pagePopup);
+
+ WebWidget* popupWidget = m_client->createPopupMenu(WebPopupTypePage);
+ ASSERT(popupWidget);
+ m_pagePopup = static_cast<WebPagePopupImpl*>(popupWidget);
+ if (!m_pagePopup->init(this, client, originBoundsInRootView)) {
+ m_pagePopup->closePopup();
+ m_pagePopup = 0;
+ }
+
+ if (Frame* frame = focusedWebCoreFrame())
+ frame->selection()->setCaretVisible(false);
+ return m_pagePopup.get();
+}
+
+void WebViewImpl::closePagePopup(PagePopup* popup)
+{
+ ASSERT(popup);
+ WebPagePopupImpl* popupImpl = static_cast<WebPagePopupImpl*>(popup);
+ ASSERT(m_pagePopup.get() == popupImpl);
+ if (m_pagePopup.get() != popupImpl)
+ return;
+ m_pagePopup->closePopup();
+ m_pagePopup = 0;
+
+ if (Frame* frame = focusedWebCoreFrame())
+ frame->selection()->pageActivationChanged();
+}
+#endif
+
void WebViewImpl::hideAutofillPopup()
{
if (m_autofillPopupShowing) {
@@ -1171,8 +1295,14 @@ void WebViewImpl::resize(const WebSize& newSize)
return;
m_size = newSize;
- if (mainFrameImpl()->frameView())
- mainFrameImpl()->frameView()->resize(m_size.width, m_size.height);
+ WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate();
+ if (agentPrivate && agentPrivate->metricsOverridden())
+ agentPrivate->webViewResized();
+ else {
+ WebFrameImpl* webFrame = mainFrameImpl();
+ if (webFrame->frameView())
+ webFrame->frameView()->resize(newSize.width, newSize.height);
+ }
sendResizeEventAndRepaint();
}
@@ -1224,8 +1354,14 @@ void WebViewImpl::willExitFullScreen()
return;
if (Document* doc = m_fullScreenFrame->document()) {
- if (doc->webkitIsFullScreen())
+ if (doc->webkitIsFullScreen()) {
+ // When the client exits from full screen we have to call webkitCancelFullScreen to
+ // notify the document. While doing that, suppress notifications back to the client.
+ m_isCancelingFullScreen = true;
+ doc->webkitCancelFullScreen();
+ m_isCancelingFullScreen = false;
doc->webkitWillExitFullScreenForElement(0);
+ }
}
#endif
}
@@ -1250,61 +1386,71 @@ void WebViewImpl::instrumentBeginFrame()
InspectorInstrumentation::didBeginFrame(m_page.get());
}
-void WebViewImpl::animate(double frameBeginTime)
+void WebViewImpl::instrumentCancelFrame()
+{
+ InspectorInstrumentation::didCancelFrame(m_page.get());
+}
+
+#if ENABLE(BATTERY_STATUS)
+void WebViewImpl::updateBatteryStatus(const WebBatteryStatus& status)
+{
+ m_batteryClient->updateBatteryStatus(status);
+}
+#endif
+
+void WebViewImpl::setCompositorSurfaceReady()
+{
+ m_compositorSurfaceReady = true;
+ if (!m_layerTreeView.isNull())
+ m_layerTreeView.setSurfaceReady();
+}
+
+void WebViewImpl::animate(double)
{
#if ENABLE(REQUEST_ANIMATION_FRAME)
- // FIXME: remove this zero-check once render_widget has been modified to
- // pass in a frameBeginTime.
- if (!frameBeginTime)
- frameBeginTime = currentTime();
+ double monotonicFrameBeginTime = monotonicallyIncreasingTime();
#if USE(ACCELERATED_COMPOSITING)
// In composited mode, we always go through the compositor so it can apply
// appropriate flow-control mechanisms.
if (isAcceleratedCompositingActive())
- m_layerTreeView.updateAnimations(frameBeginTime);
+ m_layerTreeView.updateAnimations(monotonicFrameBeginTime);
else
#endif
- updateAnimations(frameBeginTime);
+ updateAnimations(monotonicFrameBeginTime);
#endif
}
-void WebViewImpl::updateAnimations(double frameBeginTime)
+void WebViewImpl::willBeginFrame()
+{
+ instrumentBeginFrame();
+ m_client->willBeginCompositorFrame();
+}
+
+void WebViewImpl::updateAnimations(double monotonicFrameBeginTime)
{
#if ENABLE(REQUEST_ANIMATION_FRAME)
TRACE_EVENT("WebViewImpl::updateAnimations", this, 0);
- WebFrameImpl* webframe = mainFrameImpl();
- if (!webframe)
- return;
- FrameView* view = webframe->frameView();
- if (!view)
+ // Create synthetic wheel events as necessary for fling.
+ if (m_gestureAnimation) {
+ if (m_gestureAnimation->animate(monotonicFrameBeginTime))
+ scheduleAnimation();
+ else
+ m_gestureAnimation.clear();
+ }
+
+ if (!m_page)
return;
- view->serviceScriptedAnimations(convertSecondsToDOMTimeStamp(frameBeginTime));
+
+ PageWidgetDelegate::animate(m_page.get(), monotonicFrameBeginTime);
#endif
}
void WebViewImpl::layout()
{
TRACE_EVENT("WebViewImpl::layout", this, 0);
-
- WebFrameImpl* webframe = mainFrameImpl();
- if (webframe) {
- // In order for our child HWNDs (NativeWindowWidgets) to update properly,
- // they need to be told that we are updating the screen. The problem is
- // that the native widgets need to recalculate their clip region and not
- // overlap any of our non-native widgets. To force the resizing, call
- // setFrameRect(). This will be a quick operation for most frames, but
- // the NativeWindowWidgets will update a proper clipping region.
- FrameView* view = webframe->frameView();
- if (view)
- view->setFrameRect(view->frameRect());
-
- // setFrameRect may have the side-effect of causing existing page
- // layout to be invalidated, so layout needs to be called last.
-
- webframe->layout();
- }
+ PageWidgetDelegate::layout(m_page.get());
}
#if USE(ACCELERATED_COMPOSITING)
@@ -1327,7 +1473,7 @@ void WebViewImpl::doPixelReadbackToCanvas(WebCanvas* canvas, const IntRect& rect
IntRect invertRect(rect.x(), bitmapHeight - rect.maxY(), rect.width(), rect.height());
OwnPtr<ImageBuffer> imageBuffer(ImageBuffer::create(rect.size()));
- RefPtr<ByteArray> pixelArray(ByteArray::create(rect.width() * rect.height() * 4));
+ RefPtr<Uint8ClampedArray> pixelArray(Uint8ClampedArray::createUninitialized(rect.width() * rect.height() * 4));
if (imageBuffer && pixelArray) {
m_layerTreeView.compositeAndReadback(pixelArray->data(), invertRect);
imageBuffer->putByteArray(Premultiplied, pixelArray.get(), rect.size(), IntRect(IntPoint(), rect.size()), IntPoint());
@@ -1357,13 +1503,11 @@ void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect)
#endif
} else {
double paintStart = currentTime();
- WebFrameImpl* webframe = mainFrameImpl();
- if (webframe)
- webframe->paint(canvas, rect);
+ PageWidgetDelegate::paint(m_page.get(), pageOverlays(), canvas, rect);
double paintEnd = currentTime();
double pixelsPerSec = (rect.width * rect.height) / (paintEnd - paintStart);
- PlatformSupport::histogramCustomCounts("Renderer4.SoftwarePaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30);
- PlatformSupport::histogramCustomCounts("Renderer4.SoftwarePaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30);
+ WebKit::Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30);
+ WebKit::Platform::current()->histogramCustomCounts("Renderer4.SoftwarePaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30);
}
}
@@ -1403,6 +1547,15 @@ void WebViewImpl::setNeedsRedraw()
#endif
}
+bool WebViewImpl::isInputThrottled() const
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (!m_layerTreeView.isNull() && isAcceleratedCompositingActive())
+ return m_layerTreeView.commitRequested();
+#endif
+ return false;
+}
+
void WebViewImpl::loseCompositorContext(int numTimes)
{
#if USE(ACCELERATED_COMPOSITING)
@@ -1427,6 +1580,15 @@ void WebViewImpl::enterFullScreenForElement(WebCore::Element* element)
return;
}
+#if USE(NATIVE_FULLSCREEN_VIDEO)
+ if (element && element->isMediaElement()) {
+ HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(element);
+ if (mediaElement->player() && mediaElement->player()->enterFullscreen())
+ m_provisionalFullScreenElement = element;
+ return;
+ }
+#endif
+
// We need to transition to fullscreen mode.
if (m_client && m_client->enterFullScreen())
m_provisionalFullScreenElement = element;
@@ -1434,6 +1596,17 @@ void WebViewImpl::enterFullScreenForElement(WebCore::Element* element)
void WebViewImpl::exitFullScreenForElement(WebCore::Element* element)
{
+ // The client is exiting full screen, so don't send a notification.
+ if (m_isCancelingFullScreen)
+ return;
+#if USE(NATIVE_FULLSCREEN_VIDEO)
+ if (element && element->isMediaElement()) {
+ HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(element);
+ if (mediaElement->player())
+ mediaElement->player()->exitFullscreen();
+ return;
+ }
+#endif
if (m_client)
m_client->exitFullScreen();
}
@@ -1504,79 +1677,8 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent)
return true;
}
- bool handled = true;
-
- // FIXME: WebKit seems to always return false on mouse events processing
- // methods. For now we'll assume it has processed them (as we are only
- // interested in whether keyboard events are processed).
- switch (inputEvent.type) {
- case WebInputEvent::MouseMove:
- mouseMove(*static_cast<const WebMouseEvent*>(&inputEvent));
- break;
-
- case WebInputEvent::MouseLeave:
- mouseLeave(*static_cast<const WebMouseEvent*>(&inputEvent));
- break;
-
- case WebInputEvent::MouseWheel:
- handled = mouseWheel(*static_cast<const WebMouseWheelEvent*>(&inputEvent));
- break;
-
- case WebInputEvent::MouseDown:
- mouseDown(*static_cast<const WebMouseEvent*>(&inputEvent));
- break;
-
- case WebInputEvent::MouseUp:
- mouseUp(*static_cast<const WebMouseEvent*>(&inputEvent));
- break;
-
- case WebInputEvent::RawKeyDown:
- case WebInputEvent::KeyDown:
- case WebInputEvent::KeyUp:
- handled = keyEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));
- break;
-
- case WebInputEvent::Char:
- handled = charEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent));
- break;
-
-#if ENABLE(GESTURE_EVENTS)
- case WebInputEvent::GestureScrollBegin:
- case WebInputEvent::GestureScrollEnd:
- case WebInputEvent::GestureScrollUpdate:
- case WebInputEvent::GestureFlingStart:
- case WebInputEvent::GestureFlingCancel:
- case WebInputEvent::GestureTap:
- case WebInputEvent::GestureTapDown:
- case WebInputEvent::GestureDoubleTap:
- handled = gestureEvent(*static_cast<const WebGestureEvent*>(&inputEvent));
- break;
-#endif
-
-#if ENABLE(TOUCH_EVENTS)
- case WebInputEvent::TouchStart:
- case WebInputEvent::TouchMove:
- case WebInputEvent::TouchEnd:
- case WebInputEvent::TouchCancel:
- handled = touchEvent(*static_cast<const WebTouchEvent*>(&inputEvent));
- break;
-#endif
-
-#if ENABLE(GESTURE_EVENTS)
- case WebInputEvent::GesturePinchBegin:
- case WebInputEvent::GesturePinchEnd:
- case WebInputEvent::GesturePinchUpdate:
- // FIXME: Once PlatformGestureEvent is updated to support pinch, this should call handleGestureEvent, just like it currently does for gesture scroll.
- handled = false;
- break;
-#endif
-
- default:
- handled = false;
- }
-
+ bool handled = PageWidgetDelegate::handleInputEvent(m_page.get(), *this, inputEvent);
m_currentInputEvent = 0;
-
return handled;
}
@@ -1615,8 +1717,7 @@ void WebViewImpl::setFocus(bool enable)
}
m_imeAcceptEvents = true;
} else {
- hideAutofillPopup();
- hideSelectPopup();
+ hidePopups();
// Clear focus on the currently focused frame if any.
if (!m_page)
@@ -2103,9 +2204,9 @@ double WebViewImpl::setZoomLevel(bool textOnly, double zoomLevel)
else {
float zoomFactor = static_cast<float>(zoomLevelToZoomFactor(m_zoomLevel));
if (textOnly)
- frame->setPageAndTextZoomFactors(1, zoomFactor);
+ frame->setPageAndTextZoomFactors(1, zoomFactor * m_emulatedTextZoomFactor);
else
- frame->setPageAndTextZoomFactors(zoomFactor, 1);
+ frame->setPageAndTextZoomFactors(zoomFactor, m_emulatedTextZoomFactor);
}
return m_zoomLevel;
}
@@ -2263,14 +2364,6 @@ void WebViewImpl::disableAutoResizeMode()
configureAutoResizeMode();
}
-void WebViewImpl::enableAutoResizeMode(bool enable, const WebSize& minSize, const WebSize& maxSize)
-{
- if (enable)
- enableAutoResizeMode(minSize, maxSize);
- else
- disableAutoResizeMode();
-}
-
void WebViewImpl::setPageScaleFactorLimits(float minPageScale, float maxPageScale)
{
m_pageDefinedMinimumPageScaleFactor = minPageScale;
@@ -2658,12 +2751,11 @@ void WebViewImpl::applyAutofillSuggestions(
const WebVector<WebString>& names,
const WebVector<WebString>& labels,
const WebVector<WebString>& icons,
- const WebVector<int>& uniqueIDs,
+ const WebVector<int>& itemIDs,
int separatorIndex)
{
ASSERT(names.size() == labels.size());
- ASSERT(names.size() == uniqueIDs.size());
- ASSERT(separatorIndex < static_cast<int>(names.size()));
+ ASSERT(names.size() == itemIDs.size());
if (names.isEmpty()) {
hideAutofillPopup();
@@ -2688,19 +2780,24 @@ void WebViewImpl::applyAutofillSuggestions(
m_autofillPopupClient = adoptPtr(new AutofillPopupMenuClient);
m_autofillPopupClient->initialize(
- inputElem, names, labels, icons, uniqueIDs, separatorIndex);
+ inputElem, names, labels, icons, itemIDs, separatorIndex);
if (!m_autofillPopup) {
+ PopupContainerSettings popupSettings = autofillPopupSettings;
+ popupSettings.defaultDeviceScaleFactor =
+ m_page->settings()->defaultDeviceScaleFactor();
+ if (!popupSettings.defaultDeviceScaleFactor)
+ popupSettings.defaultDeviceScaleFactor = 1;
m_autofillPopup = PopupContainer::create(m_autofillPopupClient.get(),
PopupContainer::Suggestion,
- autofillPopupSettings);
+ popupSettings);
}
if (m_autofillPopupShowing) {
refreshAutofillPopup();
} else {
- m_autofillPopup->showInRect(focusedNode->getRect(), focusedNode->ownerDocument()->view(), 0);
m_autofillPopupShowing = true;
+ m_autofillPopup->showInRect(focusedNode->getPixelSnappedRect(), focusedNode->ownerDocument()->view(), 0);
}
}
@@ -2708,6 +2805,10 @@ void WebViewImpl::hidePopups()
{
hideSelectPopup();
hideAutofillPopup();
+#if ENABLE(PAGE_POPUP)
+ if (m_pagePopup)
+ closePagePopup(m_pagePopup.get());
+#endif
}
void WebViewImpl::performCustomContextMenuAction(unsigned action)
@@ -2837,6 +2938,8 @@ void WebViewImpl::didCommitLoad(bool* isNewNavigation, bool isNavigationWithinPa
m_observedNewNavigation = false;
if (!isNavigationWithinPage)
m_pageScaleFactorIsSet = false;
+
+ m_gestureAnimation.clear();
}
void WebViewImpl::layoutUpdated(WebFrameImpl* webframe)
@@ -2876,6 +2979,14 @@ bool WebViewImpl::useExternalPopupMenus()
return shouldUseExternalPopupMenus;
}
+void WebViewImpl::setEmulatedTextZoomFactor(float textZoomFactor)
+{
+ m_emulatedTextZoomFactor = textZoomFactor;
+ Frame* frame = mainFrameImpl()->frame();
+ if (frame)
+ frame->setPageAndTextZoomFactors(frame->pageZoomFactor(), m_emulatedTextZoomFactor);
+}
+
bool WebViewImpl::navigationPolicyFromMouseEvent(unsigned short button,
bool ctrl, bool shift,
bool alt, bool meta,
@@ -2952,7 +3063,7 @@ void WebViewImpl::setOverlayLayer(WebCore::GraphicsLayer* layer)
}
}
-#if ENABLE(NOTIFICATIONS)
+#if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
NotificationPresenterImpl* WebViewImpl::notificationPresenterImpl()
{
if (!m_notificationPresenter.isInitialized() && m_client)
@@ -2971,16 +3082,11 @@ void WebViewImpl::refreshAutofillPopup()
return;
}
- IntRect oldBounds = m_autofillPopup->frameRect();
- m_autofillPopup->refresh(focusedWebCoreNode()->getRect());
- IntRect newBounds = m_autofillPopup->frameRect();
+ WebRect newWidgetRect = m_autofillPopup->refresh(focusedWebCoreNode()->getPixelSnappedRect());
// Let's resize the backing window if necessary.
- if (oldBounds != newBounds) {
- WebPopupMenuImpl* popupMenu =
- static_cast<WebPopupMenuImpl*>(m_autofillPopup->client());
- if (popupMenu)
- popupMenu->client()->setWindowRect(m_chromeClientImpl.rootViewToScreen(newBounds));
- }
+ WebPopupMenuImpl* popupMenu = static_cast<WebPopupMenuImpl*>(m_autofillPopup->client());
+ if (popupMenu && popupMenu->client()->windowRect() != newWidgetRect)
+ popupMenu->client()->setWindowRect(newWidgetRect);
}
Node* WebViewImpl::focusedWebCoreNode()
@@ -3089,6 +3195,14 @@ NonCompositedContentHost* WebViewImpl::nonCompositedContentHost()
return m_nonCompositedContentHost.get();
}
+void WebViewImpl::setBackgroundColor(const WebCore::Color& color)
+{
+ WebCore::Color documentBackgroundColor = color.isValid() ? color : WebCore::Color::white;
+ WebColor webDocumentBackgroundColor = documentBackgroundColor.rgb();
+ m_nonCompositedContentHost->setBackgroundColor(documentBackgroundColor);
+ m_layerTreeView.setBackgroundColor(webDocumentBackgroundColor);
+}
+
#if ENABLE(REQUEST_ANIMATION_FRAME)
void WebViewImpl::scheduleAnimation()
{
@@ -3121,11 +3235,10 @@ public:
view->paintContents(&context, contentRect);
double paintEnd = currentTime();
double pixelsPerSec = (contentRect.width() * contentRect.height()) / (paintEnd - paintStart);
- PlatformSupport::histogramCustomCounts("Renderer4.AccelRootPaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30);
- PlatformSupport::histogramCustomCounts("Renderer4.AccelRootPaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30);
-
- m_webViewImpl->nonCompositedContentHost()->setBackgroundColor(view->documentBackgroundColor());
+ WebKit::Platform::current()->histogramCustomCounts("Renderer4.AccelRootPaintDurationMS", (paintEnd - paintStart) * 1000, 0, 120, 30);
+ WebKit::Platform::current()->histogramCustomCounts("Renderer4.AccelRootPaintMegapixPerSecond", pixelsPerSec / 1000000, 10, 210, 30);
+ m_webViewImpl->setBackgroundColor(view->documentBackgroundColor());
}
private:
@@ -3139,7 +3252,7 @@ private:
void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
{
- PlatformSupport::histogramEnumeration("GPU.setIsAcceleratedCompositingActive", active * 2 + m_isAcceleratedCompositingActive, 4);
+ WebKit::Platform::current()->histogramEnumeration("GPU.setIsAcceleratedCompositingActive", active * 2 + m_isAcceleratedCompositingActive, 4);
if (m_isAcceleratedCompositingActive == active)
return;
@@ -3161,7 +3274,6 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
WebLayerTreeView::Settings layerTreeViewSettings;
layerTreeViewSettings.acceleratePainting = page()->settings()->acceleratedDrawingEnabled();
- layerTreeViewSettings.compositeOffscreen = settings()->compositeToTextureEnabled();
layerTreeViewSettings.showFPSCounter = settings()->showFPSCounter();
layerTreeViewSettings.showPlatformLayerTree = settings()->showPlatformLayerTree();
@@ -3172,12 +3284,11 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
m_nonCompositedContentHost = NonCompositedContentHost::create(WebViewImplContentPainter::create(this));
m_nonCompositedContentHost->setShowDebugBorders(page()->settings()->showDebugBorders());
- if (page() && page()->mainFrame()->view())
- m_nonCompositedContentHost->setBackgroundColor(page()->mainFrame()->view()->documentBackgroundColor());
-
m_layerTreeView.initialize(this, m_rootLayer, layerTreeViewSettings);
if (!m_layerTreeView.isNull()) {
m_layerTreeView.setPageScaleFactorAndLimits(pageScaleFactor(), m_minimumPageScaleFactor, m_maximumPageScaleFactor);
+ if (m_compositorSurfaceReady)
+ m_layerTreeView.setSurfaceReady();
updateLayerTreeViewport();
m_client->didActivateCompositor(m_layerTreeView.compositorIdentifier());
m_isAcceleratedCompositingActive = true;
@@ -3239,9 +3350,10 @@ void WebViewImpl::applyScrollAndScale(const WebSize& scrollDelta, float pageScal
if (!mainFrameImpl() || !mainFrameImpl()->frameView())
return;
- if (pageScaleDelta == 1)
+ if (pageScaleDelta == 1) {
+ TRACE_EVENT_INSTANT2("webkit", "WebViewImpl::applyScrollAndScale::scrollBy", "x", scrollDelta.width, "y", scrollDelta.height);
mainFrameImpl()->frameView()->scrollBy(scrollDelta);
- else {
+ } 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
@@ -3255,6 +3367,12 @@ void WebViewImpl::applyScrollAndScale(const WebSize& scrollDelta, float pageScal
}
}
+void WebViewImpl::didCommit()
+{
+ if (m_client)
+ m_client->didBecomeReadyForAdditionalInput();
+}
+
void WebViewImpl::didCommitAndDrawFrame()
{
if (m_client)
@@ -3310,7 +3428,7 @@ void WebViewImpl::updateLayerTreeViewport()
layerAdjustX = -view->contentsSize().width() + view->visibleContentRect(false).width();
}
m_nonCompositedContentHost->setViewport(visibleRect.size(), view->contentsSize(), scroll, pageScaleFactor(), layerAdjustX);
- m_layerTreeView.setViewportSize(visibleRect.size());
+ m_layerTreeView.setViewportSize(size());
m_layerTreeView.setPageScaleFactorAndLimits(pageScaleFactor(), m_minimumPageScaleFactor, m_maximumPageScaleFactor);
}
@@ -3343,7 +3461,7 @@ WebGraphicsContext3D* WebViewImpl::sharedGraphicsContext3D()
if (!m_page->settings()->acceleratedCompositingEnabled() || !allowsAcceleratedCompositing())
return 0;
- return GraphicsContext3DPrivate::extractWebGraphicsContext3D(SharedGraphicsContext3D::get());
+ return GraphicsContext3DPrivate::extractWebGraphicsContext3D(SharedGraphicsContext3D::get().get());
}
void WebViewImpl::setVisibilityState(WebPageVisibilityState visibilityState,
@@ -3354,14 +3472,15 @@ void WebViewImpl::setVisibilityState(WebPageVisibilityState visibilityState,
#if ENABLE(PAGE_VISIBILITY_API)
ASSERT(visibilityState == WebPageVisibilityStateVisible
|| visibilityState == WebPageVisibilityStateHidden
- || visibilityState == WebPageVisibilityStatePrerender);
+ || visibilityState == WebPageVisibilityStatePrerender
+ || visibilityState == WebPageVisibilityStatePreview);
m_page->setVisibilityState(static_cast<PageVisibilityState>(static_cast<int>(visibilityState)), isInitialState);
#endif
#if USE(ACCELERATED_COMPOSITING)
- if (isAcceleratedCompositingActive()) {
+ if (!m_layerTreeView.isNull()) {
bool visible = visibilityState == WebPageVisibilityStateVisible;
- if (!visible)
+ if (!visible && isAcceleratedCompositingActive())
m_nonCompositedContentHost->protectVisibleTileTextures();
m_layerTreeView.setVisible(visible);
}