Merge remote-tracking branch 'origin/stable' into dev
authorFrederik Gladhorn <frederik.gladhorn@digia.com>
Fri, 9 May 2014 14:25:58 +0000 (16:25 +0200)
committerGunnar Sletta <gunnar.sletta@jollamobile.com>
Sat, 10 May 2014 09:53:47 +0000 (11:53 +0200)
Conflicts:
.qmake.conf
src/plugins/accessible/quick/quick.pro
src/quick/items/qquickpincharea.cpp
src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
src/quick/scenegraph/qsgthreadedrenderloop.cpp

Manually adjusted for TestHTTPServer constructor change:
    tests/auto/quick/qquickimage/tst_qquickimage.cpp

Change-Id: I5e58a7c08ea92d6fc5e3bce98571c54f7b2ce08f

27 files changed:
1  2 
src/imports/folderlistmodel/qquickfolderlistmodel.cpp
src/qml/compiler/qqmltypecompiler.cpp
src/quick/items/qquickitem.cpp
src/quick/items/qquickitemsmodule.cpp
src/quick/items/qquickmousearea.cpp
src/quick/items/qquickpincharea.cpp
src/quick/items/qquickrendercontrol.cpp
src/quick/items/qquicktextinput.cpp
src/quick/items/qquicktextinput_p.h
src/quick/items/qquickwindow.cpp
src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp
src/quick/scenegraph/coreapi/qsgbatchrenderer_p.h
src/quick/scenegraph/qsgrenderloop.cpp
src/quick/scenegraph/qsgthreadedrenderloop.cpp
src/quick/scenegraph/qsgthreadedrenderloop_p.h
src/quick/scenegraph/qsgwindowsrenderloop.cpp
src/quick/scenegraph/util/qsgatlastexture.cpp
src/quick/scenegraph/util/qsgsimpletexturenode.cpp
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
tests/auto/quick/qquickimage/tst_qquickimage.cpp
tests/auto/quick/qquickitem/tst_qquickitem.cpp
tests/auto/quick/qquickitem2/tst_qquickitem.cpp
tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
tests/auto/quick/qquickwindow/qquickwindow.pro
tests/auto/quick/qquickwindow/tst_qquickwindow.cpp

Simple merge
Simple merge
Simple merge
Simple merge
@@@ -359,10 -345,40 +376,43 @@@ void QQuickPinchArea::updatePinch(
  {
      Q_D(QQuickPinchArea);
  
 +    QQuickWindow *win = window();
++
+     if (d->touchPoints.count() < 2) {
+         setKeepMouseGrab(false);
+         QQuickWindow *c = window();
+         if (c && c->mouseGrabberItem() == this)
+             ungrabMouse();
+     }
+     if (d->touchPoints.count() == 0) {
+         if (d->inPinch) {
+             d->inPinch = false;
+             QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
+             QQuickPinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, d->pinchRotation);
+             pe.setStartCenter(d->pinchStartCenter);
+             pe.setPreviousCenter(pinchCenter);
+             pe.setPreviousAngle(d->pinchLastAngle);
+             pe.setPreviousScale(d->pinchLastScale);
+             pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+             pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+             pe.setPoint1(mapFromScene(d->lastPoint1));
+             pe.setPoint2(mapFromScene(d->lastPoint2));
+             emit pinchFinished(&pe);
+             d->pinchStartDist = 0;
+             d->pinchActivated = false;
+             if (d->pinch && d->pinch->target())
+                 d->pinch->setActive(false);
+         }
+         d->initPinch = false;
+         d->pinchRejected = false;
+         d->stealMouse = false;
+         return;
+     }
      QTouchEvent::TouchPoint touchPoint1 = d->touchPoints.at(0);
      QTouchEvent::TouchPoint touchPoint2 = d->touchPoints.at(d->touchPoints. count() >= 2 ? 1 : 0);
 +
      QRectF bounds = clipRect();
      // Pinch is not started unless there are exactly two touch points
      // AND one or more of the points has just now been pressed (wasn't pressed already)
                  d->pinchRotation = 0.0;
                  d->lastPoint1 = p1;
                  d->lastPoint2 = p2;
-                 QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
-                 pe.setStartCenter(d->pinchStartCenter);
-                 pe.setPreviousCenter(d->pinchStartCenter);
-                 pe.setPreviousAngle(d->pinchLastAngle);
-                 pe.setPreviousScale(d->pinchLastScale);
-                 pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
-                 pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
-                 pe.setPoint1(mapFromScene(d->lastPoint1));
-                 pe.setPoint2(mapFromScene(d->lastPoint2));
-                 pe.setPointCount(d->touchPoints.count());
-                 emit pinchStarted(&pe);
-                 if (pe.accepted()) {
-                     if (win && win->mouseGrabberItem() != this)
-                         grabMouse();
-                     setKeepMouseGrab(true);
-                     grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id());
-                     d->inPinch = true;
-                     d->stealMouse = true;
-                     if (d->pinch && d->pinch->target()) {
-                         d->pinchStartPos = pinch()->target()->position();
-                         d->pinchStartScale = d->pinch->target()->scale();
-                         d->pinchStartRotation = d->pinch->target()->rotation();
-                         d->pinch->setActive(true);
+                 if (qAbs(dist - d->pinchStartDist) >= dragThreshold ||
+                         (pinch()->axis() != QQuickPinch::NoDrag &&
+                          (qAbs(p1.x()-d->sceneStartPoint1.x()) >= dragThreshold
+                           || qAbs(p1.y()-d->sceneStartPoint1.y()) >= dragThreshold
+                           || qAbs(p2.x()-d->sceneStartPoint2.x()) >= dragThreshold
+                           || qAbs(p2.y()-d->sceneStartPoint2.y()) >= dragThreshold))) {
+                     QQuickPinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
+                     d->pinchStartDist = dist;
+                     pe.setStartCenter(d->pinchStartCenter);
+                     pe.setPreviousCenter(d->pinchStartCenter);
+                     pe.setPreviousAngle(d->pinchLastAngle);
+                     pe.setPreviousScale(d->pinchLastScale);
+                     pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+                     pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+                     pe.setPoint1(mapFromScene(d->lastPoint1));
+                     pe.setPoint2(mapFromScene(d->lastPoint2));
+                     pe.setPointCount(d->touchPoints.count());
+                     emit pinchStarted(&pe);
+                     if (pe.accepted()) {
+                         d->inPinch = true;
+                         d->stealMouse = true;
 -                        QQuickWindow *c = window();
 -                        if (c && c->mouseGrabberItem() != this)
++                        if (win && win->mouseGrabberItem() != this)
+                             grabMouse();
+                         setKeepMouseGrab(true);
++                        grabTouchPoints(QVector<int>() << touchPoint1.id() << touchPoint2.id());
++                        d->inPinch = true;
++                        d->stealMouse = true;
+                         if (d->pinch && d->pinch->target()) {
+                             d->pinchStartPos = pinch()->target()->position();
+                             d->pinchStartScale = d->pinch->target()->scale();
+                             d->pinchStartRotation = d->pinch->target()->rotation();
+                             d->pinch->setActive(true);
+                         }
+                     } else {
+                         d->pinchRejected = true;
                      }
-                 } else {
-                     d->pinchRejected = true;
                  }
              }
          } else if (d->pinchStartDist > 0) {
Simple merge
Simple merge
Simple merge
@@@ -791,9 -823,47 +798,7 @@@ void QSGThreadedRenderLoop::startOrStop
      }
  }
  
  /*
 -    Adds this window to the list of tracked windows in this window
 -    manager. show() does not trigger rendering to start, that happens
 -    in expose.
 - */
 -
 -void QSGThreadedRenderLoop::show(QQuickWindow *window)
 -{
 -    QSG_GUI_DEBUG(window, "show()");
 -
 -    if (Window *w = windowFor(m_windows, window)) {
 -        /* Safeguard ourselves against misbehaving platform plugins.
 -         *
 -         * When being shown, the window should not be exposed as the
 -         * platform plugin is only told to show after we send the show
 -         * event. If we are already shown at this time and we don't have
 -         * an active rendering thread we don't trust the plugin to send
 -         * us another expose event, so make this explicit call to
 -         * handleExposure.
 -         *
 -         * REF: QTCREATORBUG-10699
 -         */
 -        if (window->isExposed() && (!w->thread || !w->thread->window))
 -            handleExposure(w);
 -        return;
 -    }
 -
 -    QSG_GUI_DEBUG(window, " - now tracking new window");
 -
 -    Window win;
 -    win.window = window;
 -    win.actualWindowFormat = window->format();
 -    win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context);
 -    win.timerId = 0;
 -    win.updateDuringSync = false;
 -    m_windows << win;
 -}
 -
 -
 -
 -/*
      Removes this window from the list of tracked windowes in this
      window manager. hide() will trigger obscure, which in turn will
      stop rendering.
@@@ -864,21 -927,9 +869,22 @@@ void QSGThreadedRenderLoop::exposureCha
      Will post an event to the render thread that this window should
      start to render.
   */
 -void QSGThreadedRenderLoop::handleExposure(Window *w)
 +void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window)
  {
 -    QSG_GUI_DEBUG(w->window, "handleExposure");
 +    QSG_GUI_DEBUG(window, "handleExposure");
 +
 +    Window *w = windowFor(m_windows, window);
 +    if (!w) {
 +        QSG_GUI_DEBUG(window, " - adding window to list");
 +        Window win;
 +        win.window = window;
++        win.actualWindowFormat = window->format();
 +        win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context);
 +        win.timerId = 0;
 +        win.updateDuringSync = false;
 +        m_windows << win;
 +        w = &m_windows.last();
 +    }
  
      if (w->window->width() <= 0 || w->window->height() <= 0
              || !w->window->geometry().intersects(w->window->screen()->availableGeometry())) {
@@@ -1043,9 -1105,9 +1049,9 @@@ void QSGThreadedRenderLoop::releaseReso
          // create it here and pass it on to QSGRenderThread::invalidateGL()
          QOffscreenSurface *fallback = 0;
          if (!window->handle()) {
 -            QSG_GUI_DEBUG(w->window, " - using fallback surface");
 +            QSG_GUI_DEBUG(window, " - using fallback surface");
              fallback = new QOffscreenSurface();
-             fallback->setFormat(window->requestedFormat());
+             fallback->setFormat(w->actualWindowFormat);
              fallback->create();
          }
  
@@@ -928,6 -933,49 +933,49 @@@ void tst_qquickimage::correctStatus(
      delete obj;
  }
  
 -    TestHTTPServer server(14449);
 -    QVERIFY(server.isValid());
+ void tst_qquickimage::highdpi()
+ {
++    TestHTTPServer server;
++    QVERIFY2(server.listen(SERVER_PORT), qPrintable(server.errorString()));
+     server.serveDirectory(dataDirectory());
+     QString componentStr = "import QtQuick 2.0\nImage { source: srcImage ;  }";
+     QQmlComponent component(&engine);
+     component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+     QQmlContext *ctxt = engine.rootContext();
+     // Testing "@2x" high-dpi image loading:
+     // The basic case is as follows. Suppose you have foo.png,
+     // which is a 64x64 png that fits in a QML layout. Now,
+     // on a high-dpi system that pixmap would not provide
+     // enough pixels. To fix this the app developer provides
+     // a 128x128 foo@2x.png, which Qt automatically loads.
+     // The image continues to be referred to as "foo.png" in
+     // the QML sources, and reports a size of 64x64.
+     //
+     // Load "heart-highdpi@2x.png", which is a 300x300 png. As a 2x scale image it
+     // should render and report a geometry of 150x150.
+     ctxt->setContextProperty("srcImage", testFileUrl("heart-highdpi@2x.png"));
+     QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
+     QVERIFY(obj != 0);
+     QCOMPARE(obj->width(), 150.0);
+     QCOMPARE(obj->height(), 150.0);
+     QCOMPARE(obj->paintedWidth(), 150.0);
+     QCOMPARE(obj->paintedHeight(), 150.0);
+     // Load a normal 1x image.
+     ctxt->setContextProperty("srcImage", testFileUrl("heart.png"));
+     QCOMPARE(obj->width(), 300.0);
+     QCOMPARE(obj->height(), 300.0);
+     QCOMPARE(obj->paintedWidth(), 300.0);
+     QCOMPARE(obj->paintedHeight(), 300.0);
+     delete obj;
+ }
  QTEST_MAIN(tst_qquickimage)
  
  #include "tst_qquickimage.moc"