Source/WebKit2/ChangeLog

 12012-12-11 Andras Becsi <andras.becsi@digia.com>
 2
 3 [Qt][WK2] Fix painting on Mac with retina display
 4 https://bugs.webkit.org/show_bug.cgi?id=104574
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Since HiDPI support has been added and enabled in Qt we ended up
 9 painting incorrectly scaled content on high-resolution screens.
 10 Because the intrinsic device pixel ratio is always taken into
 11 account by Qt when painting to high-resolution screens we should
 12 automatically obtain the scale ratio from the window in which the
 13 item is rendered instead of setting it in QML.
 14
 15 Since Qt does not make it possible to override the device pixel ratio
 16 of the native window our experimental QML API for setting a custom
 17 value is of no use any more and should be removed.
 18
 19 This patch fixes the scaling issue on Mac retina display by querying
 20 the underlying window for the device scale factor, and removes the
 21 experimental API and related API tests.
 22
 23 * UIProcess/API/qt/qquickwebpage.cpp:
 24 (QQuickWebPage::updatePaintNode):
 25 * UIProcess/API/qt/qquickwebview.cpp:
 26 (QQuickWebViewPrivate::QQuickWebViewPrivate):
 27 (QQuickWebViewLegacyPrivate::updateViewportSize):
 28 (QQuickWebViewFlickablePrivate::onComponentComplete):
 29 * UIProcess/API/qt/qquickwebview_p.h:
 30 * UIProcess/API/qt/tests/qmltests/WebView/tst_devicePixelRatio.qml: Removed.
 31 * UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp:
 32 (tst_QQuickWebView::newWebView):
 33 * UIProcess/PageViewportController.cpp:
 34 (WebKit::PageViewportController::syncVisibleContents):
 35 * UIProcess/qt/QtWebPageSGNode.cpp:
 36 (WebKit::ContentsSGNode::ContentsSGNode):
 37 (WebKit::ContentsSGNode::render):
 38 (WebKit::ContentsSGNode::clipRect):
 39 (ContentsSGNode):
 40 (WebKit::QtWebPageSGNode::QtWebPageSGNode):
 41 (WebKit::QtWebPageSGNode::setRenderer):
 42 * UIProcess/qt/QtWebPageSGNode.h:
 43 (QtWebPageSGNode):
 44
1452012-12-10 Jon Lee <jonlee@apple.com>
246
347 Keep track of plug-in snapshots clicked by user

Source/WebKit2/UIProcess/API/qt/qquickwebpage.cpp

3030#include "qquickwebpage_p_p.h"
3131#include "qquickwebview_p.h"
3232#include "qwebkittest_p.h"
 33#include <QQuickWindow>
3334
3435using namespace WebKit;
3536

@@QSGNode* QQuickWebPage::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData*)
8485 LayerTreeRenderer* renderer = layerTreeCoordinatorProxy->layerTreeRenderer();
8586
8687 QtWebPageSGNode* node = static_cast<QtWebPageSGNode*>(oldNode);
 88 QWindow* const w = window();
 89 ASSERT(w);
 90
 91 if (d->webPageProxy->deviceScaleFactor() != w->devicePixelRatio()) {
 92 d->webPageProxy->setIntrinsicDeviceScaleFactor(w->devicePixelRatio());
 93 d->viewportItem->experimental()->test()->devicePixelRatioChanged();
 94 }
 95
8796 if (!node)
88  node = new QtWebPageSGNode();
 97 node = new QtWebPageSGNode(w);
 98
8999 node->setRenderer(renderer);
90100
91101 node->setScale(d->contentsScale);

Source/WebKit2/UIProcess/API/qt/qquickwebview.cpp

@@QQuickWebViewPrivate::QQuickWebViewPrivate(QQuickWebView* viewport)
280280 viewport->setPixelAligned(true);
281281 QObject::connect(viewport, SIGNAL(visibleChanged()), viewport, SLOT(_q_onVisibleChanged()));
282282 QObject::connect(viewport, SIGNAL(urlChanged()), viewport, SLOT(_q_onUrlChanged()));
283  QObject::connect(experimental, SIGNAL(devicePixelRatioChanged()), experimental->test(), SIGNAL(devicePixelRatioChanged()));
284283 pageView.reset(new QQuickWebPage(viewport));
285284}
286285

@@void QQuickWebViewLegacyPrivate::updateViewportSize()
829828
830829 float devicePixelRatio = webPageProxy->deviceScaleFactor();
831830 pageView->setContentsSize(viewportSize);
832  // Make sure that our scale matches the one passed to setVisibleContentsRect.
833  pageView->setContentsScale(devicePixelRatio);
834831
835832 // The fixed layout is handled by the FrameView and the drawing area doesn't behave differently
836833 // whether its fixed or not. We still need to tell the drawing area which part of it
837834 // has to be rendered on tiles, and in desktop mode it's all of it.
838  webPageProxy->drawingArea()->setSize((viewportSize / devicePixelRatio).toSize(), IntSize());
839  webPageProxy->drawingArea()->setVisibleContentsRect(FloatRect(FloatPoint(), FloatSize(viewportSize / devicePixelRatio)), devicePixelRatio, FloatPoint());
 835 webPageProxy->drawingArea()->setSize(viewportSize.toSize(), IntSize());
 836 webPageProxy->drawingArea()->setVisibleContentsRect(FloatRect(FloatPoint(), FloatSize(viewportSize)), devicePixelRatio, FloatPoint());
840837}
841838
842839qreal QQuickWebViewLegacyPrivate::zoomFactor() const

@@void QQuickWebViewFlickablePrivate::onComponentComplete()
868865 m_pageViewportController.reset(new PageViewportController(webPageProxy.get(), m_pageViewportControllerClient.data()));
869866 pageView->eventHandler()->setViewportController(m_pageViewportControllerClient.data());
870867
871  // Notify about device pixel ratio here because due to the delayed instantiation
872  // of the viewport controller the correct value might not have reached QWebKitTest
873  // in time it was used from QML.
874  emit experimental->test()->devicePixelRatioChanged();
875 
876868 // Trigger setting of correct visibility flags after everything was allocated and initialized.
877869 _q_onVisibleChanged();
878870}

@@void QQuickWebViewExperimental::setUserAgent(const QString& userAgent)
11911183/*!
11921184 \internal
11931185
1194  \qmlproperty real WebViewExperimental::devicePixelRatio
1195  \brief The ratio between the CSS units and device pixels when the content is unscaled.
1196 
1197  When designing touch-friendly contents, knowing the approximated target size on a device
1198  is important for contents providers in order to get the intented layout and element
1199  sizes.
1200 
1201  As most first generation touch devices had a PPI of approximately 160, this became a
1202  de-facto value, when used in conjunction with the viewport meta tag.
1203 
1204  Devices with a higher PPI learning towards 240 or 320, applies a pre-scaling on all
1205  content, of either 1.5 or 2.0, not affecting the CSS scale or pinch zooming.
1206 
1207  This value can be set using this property and it is exposed to CSS media queries using
1208  the -webkit-device-pixel-ratio query.
1209 
1210  For instance, if you want to load an image without having it upscaled on a web view
1211  using a device pixel ratio of 2.0 it can be done by loading an image of say 100x100
1212  pixels but showing it at half the size.
1213 
1214  FIXME: Move documentation example out in separate files
1215 
1216  @media (-webkit-min-device-pixel-ratio: 1.5) {
1217  .icon {
1218  width: 50px;
1219  height: 50px;
1220  url: "/images/icon@2x.png"; // This is actually a 100x100 image
1221  }
1222  }
1223 
1224  If the above is used on a device with device pixel ratio of 1.5, it will be scaled
1225  down but still provide a better looking image.
1226 */
1227 
1228 qreal QQuickWebViewExperimental::devicePixelRatio() const
1229 {
1230  Q_D(const QQuickWebView);
1231  return d->webPageProxy->deviceScaleFactor();
1232 }
1233 
1234 void QQuickWebViewExperimental::setDevicePixelRatio(qreal devicePixelRatio)
1235 {
1236  Q_D(QQuickWebView);
1237  if (0 >= devicePixelRatio || devicePixelRatio == this->devicePixelRatio())
1238  return;
1239 
1240  d->webPageProxy->setIntrinsicDeviceScaleFactor(devicePixelRatio);
1241  emit devicePixelRatioChanged();
1242 }
1243 
1244 /*!
1245  \internal
1246 
12471186 \qmlproperty int WebViewExperimental::deviceWidth
12481187 \brief The device width used by the viewport calculations.
12491188

Source/WebKit2/UIProcess/API/qt/qquickwebview_p.h

@@class QWEBKIT_EXPORT QQuickWebViewExperimental : public QObject {
256256 Q_PROPERTY(int preferredMinimumContentsWidth WRITE setPreferredMinimumContentsWidth READ preferredMinimumContentsWidth NOTIFY preferredMinimumContentsWidthChanged)
257257 Q_PROPERTY(int deviceWidth WRITE setDeviceWidth READ deviceWidth NOTIFY deviceWidthChanged)
258258 Q_PROPERTY(int deviceHeight WRITE setDeviceHeight READ deviceHeight NOTIFY deviceHeightChanged)
259  Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged)
260259
261260 Q_PROPERTY(QWebNavigationHistory* navigationHistory READ navigationHistory CONSTANT FINAL)
262261

@@public:
312311 void setDeviceWidth(int);
313312 int deviceHeight() const;
314313 void setDeviceHeight(int);
315  qreal devicePixelRatio() const;
316  void setDevicePixelRatio(qreal);
317314 QList<QUrl> userScripts() const;
318315 void setUserScripts(const QList<QUrl>& userScripts);
319316 QUrl remoteInspectorUrl() const;

@@Q_SIGNALS:
371368 void userAgentChanged();
372369 void deviceWidthChanged();
373370 void deviceHeightChanged();
374  void devicePixelRatioChanged();
375371 void enterFullScreenRequested();
376372 void exitFullScreenRequested();
377373 void userScriptsChanged();

Source/WebKit2/UIProcess/API/qt/tests/qmltests/WebView/tst_devicePixelRatio.qml

1 import QtQuick 2.0
2 import QtTest 1.0
3 import QtWebKit 3.0
4 import QtWebKit.experimental 1.0
5 import "../common"
6 
7 
8 TestWebView {
9  id: webView
10  property variant lastResult
11  width: 400
12  height: 300
13  focus: true
14 
15  SignalSpy {
16  id: resultSpy
17  target: webView
18  signalName: "lastResultChanged"
19  }
20 
21  TestCase {
22  name: "DevicePixelRatio"
23 
24  function init() {
25  resultSpy.clear()
26  webView.lastResult = null
27  }
28 
29  function test_devicePixelRatio() {
30  resultSpy.clear()
31  webView.url = Qt.resolvedUrl("../common/test1.html");
32  webView.experimental.devicePixelRatio = 2.0
33  verify(webView.waitForLoadSucceeded())
34 
35  webView.experimental.evaluateJavaScript(
36  "(function() { return window.devicePixelRatio })()",
37  function(result) {
38  webView.lastResult = result
39  })
40 
41  resultSpy.wait()
42  compare(webView.lastResult, 2.0)
43  compare(webView.lastResult, webView.experimental.devicePixelRatio)
44  }
45 
46  function test_devicePixelRatioMediaQuery() {
47  resultSpy.clear()
48  webView.url = Qt.resolvedUrl("../common/test2.html");
49  webView.experimental.devicePixelRatio = 2.0
50  verify(webView.waitForLoadSucceeded())
51 
52  webView.experimental.evaluateJavaScript(
53  "(function() { return window.matchMedia(\"(-webkit-device-pixel-ratio: 2)\").matches })()",
54  function(result) {
55  webView.lastResult = result
56  })
57 
58  resultSpy.wait()
59  verify(webView.lastResult)
60  }
61  }
62 }

Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp

@@QQuickWebView* tst_QQuickWebView::newWebView()
9393{
9494 QObject* viewInstance = m_component->create();
9595 QQuickWebView* webView = qobject_cast<QQuickWebView*>(viewInstance);
96  webView->experimental()->setDevicePixelRatio(1.5);
9796 return webView;
9897}
9998

Source/WebKit2/UIProcess/PageViewportController.cpp

@@void PageViewportController::syncVisibleContents(const FloatPoint& trajectoryVec
261261
262262 FloatRect visibleContentsRect(boundContentsPosition(m_contentsPosition), visibleContentsSize());
263263 visibleContentsRect.intersect(FloatRect(FloatPoint::zero(), m_contentsSize));
264  drawingArea->setVisibleContentsRect(visibleContentsRect, m_effectiveScale, trajectoryVector);
 264 drawingArea->setVisibleContentsRect(visibleContentsRect, devicePixelRatio() * m_effectiveScale, trajectoryVector);
265265
266266 m_client->didChangeVisibleContents();
267267}

Source/WebKit2/UIProcess/qt/QtWebPageSGNode.cpp

2424#include "LayerTreeRenderer.h"
2525#include <QtGui/QPolygonF>
2626#include <QtQuick/QSGSimpleRectNode>
 27#include <WebCore/TransformationMatrix.h>
2728#include <private/qsgrendernode_p.h>
2829
2930using namespace WebCore;

@@namespace WebKit {
3233
3334class ContentsSGNode : public QSGRenderNode {
3435public:
35  ContentsSGNode(PassRefPtr<LayerTreeRenderer> renderer)
 36 ContentsSGNode(PassRefPtr<LayerTreeRenderer> renderer, const QWindow* const parentWindow)
3637 : m_renderer(renderer)
 38 , m_window(parentWindow)
3739 {
3840 layerTreeRenderer()->setActive(true);
3941 }

@@public:
4547
4648 virtual void render(const RenderState& state)
4749 {
48  QMatrix4x4 renderMatrix = matrix() ? *matrix() : QMatrix4x4();
 50 ASSERT(m_window);
 51 TransformationMatrix renderMatrix;
 52 if (m_window->devicePixelRatio() != 1.0) {
 53 renderMatrix.scale(m_window->devicePixelRatio());
 54 if (matrix())
 55 renderMatrix.multiply(*matrix());
 56 } else if (matrix())
 57 renderMatrix = *matrix();
4958
5059 // When rendering to an intermediate surface, Qt will
5160 // mirror the projection matrix to fit on the destination coordinate system.

@@public:
6675private:
6776 QRectF clipRect() const
6877 {
 78 ASSERT(m_window);
 79
6980 // Start with an invalid rect.
7081 QRectF resultRect(0, 0, -1, -1);
7182

@@private:
7384 QMatrix4x4 clipMatrix;
7485 if (clip->matrix())
7586 clipMatrix = *clip->matrix();
 87 clipMatrix.scale(m_window->devicePixelRatio());
 88
7689 QRectF currentClip;
7790
7891 if (clip->isRectangular())

@@private:
106119 }
107120
108121 RefPtr<LayerTreeRenderer> m_renderer;
 122 const QWindow* const m_window;
109123};
110124
111 QtWebPageSGNode::QtWebPageSGNode()
 125QtWebPageSGNode::QtWebPageSGNode(const QWindow* const window)
112126 : m_contentsNode(0)
113127 , m_backgroundNode(new QSGSimpleRectNode)
 128 , m_window(window)
114129{
115130 appendChildNode(m_backgroundNode);
116131}

@@void QtWebPageSGNode::setRenderer(PassRefPtr<LayerTreeRenderer> renderer)
134149 return;
135150
136151 delete m_contentsNode;
137  m_contentsNode = new ContentsSGNode(renderer);
 152 m_contentsNode = new ContentsSGNode(renderer, m_window);
138153 appendChildNode(m_contentsNode);
139154}
140155

Source/WebKit2/UIProcess/qt/QtWebPageSGNode.h

2121#ifndef QtWebPageSGNode_h
2222#define QtWebPageSGNode_h
2323
 24#include <QtGui/QWindow>
2425#include <QtQuick/QSGTransformNode>
2526#include <wtf/PassRefPtr.h>
2627

@@class LayerTreeRenderer;
3536
3637class QtWebPageSGNode : public QSGTransformNode {
3738 public:
38  QtWebPageSGNode();
 39 QtWebPageSGNode(const QWindow* const parentWindow);
3940 void setBackground(const QRectF&, const QColor&);
4041 void setScale(float);
4142 void setRenderer(PassRefPtr<LayerTreeRenderer>);

@@class QtWebPageSGNode : public QSGTransformNode {
4344 private:
4445 ContentsSGNode* m_contentsNode;
4546 QSGSimpleRectNode* m_backgroundNode;
 47 const QWindow* const m_window;
4648};
4749
4850} // namespace WebKit

Tools/ChangeLog

 12012-12-11 Andras Becsi <andras.becsi@digia.com>
 2
 3 [Qt][WK2] Fix painting on Mac with retina display
 4 https://bugs.webkit.org/show_bug.cgi?id=104574
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Remove setting the devicePixelRatio experimental property
 9 since the value is now automatically picked up from Qt.
 10
 11 * MiniBrowser/qt/qml/BrowserWindow.qml:
 12
1132012-12-10 Dirk Pranke <dpranke@chromium.org>
214
315 old-run-webkit-tests: add --show-results properly

Tools/MiniBrowser/qt/qml/BrowserWindow.qml

@@Rectangle {
354354 webView.loadHtml("Failed to load " + loadRequest.url, "", loadRequest.url)
355355 }
356356
357  experimental.devicePixelRatio: 1.5
358357 experimental.preferences.fullScreenEnabled: true
359358 experimental.preferences.webGLEnabled: true
360359 experimental.preferences.webAudioEnabled: true