Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: src/quick/items/context2d/qquickcanvasitem.cpp src/quickwidgets/qquickwidget.cpp tests/auto/quickwidgets/qquickwidget/tst_qquickwidget.cpp Change-Id: Idf279cb88e0df2a383489af5b6afdf04d04ae611
This commit is contained in:
commit
42f485231c
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include "mainwindow.h"
|
||||
#include "fbitem.h"
|
||||
#include <QCoreApplication>
|
||||
#include <QVBoxLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
|
|
|
@ -603,7 +603,7 @@ public:
|
|||
RandomNumberGenerator(QObject *parent)
|
||||
: QObject(parent), m_maxValue(100)
|
||||
{
|
||||
qsrand(QDateTime::currentDateTime().toTime_t());
|
||||
qsrand(QDateTime::currentMSecsSinceEpoch() / 1000);
|
||||
QObject::connect(&m_timer, SIGNAL(timeout()), SLOT(updateProperty()));
|
||||
m_timer.start(500);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include <private/qqmldebugserviceinterfaces_p.h>
|
||||
#include "qqmlinfo.h"
|
||||
|
||||
#include <private/qjsvalue_p.h>
|
||||
#include <private/qv4value_p.h>
|
||||
#include <private/qv4qobjectwrapper_p.h>
|
||||
|
||||
|
@ -217,7 +218,9 @@ void QQmlBoundSignalExpression::evaluate(void **a)
|
|||
//### ideally we would use metaTypeToJS, however it currently gives different results
|
||||
// for several cases (such as QVariant type and QObject-derived types)
|
||||
//args[ii] = engine->metaTypeToJS(type, a[ii + 1]);
|
||||
if (type == QMetaType::QVariant) {
|
||||
if (type == qMetaTypeId<QJSValue>()) {
|
||||
callData->args[ii] = *QJSValuePrivate::getValue(reinterpret_cast<QJSValue *>(a[ii + 1]));
|
||||
} else if (type == QMetaType::QVariant) {
|
||||
callData->args[ii] = scope.engine->fromVariant(*((QVariant *)a[ii + 1]));
|
||||
} else if (type == QMetaType::Int) {
|
||||
//### optimization. Can go away if we switch to metaTypeToJS, or be expanded otherwise
|
||||
|
|
|
@ -489,8 +489,8 @@ QQmlType *QQmlType::resolveCompositeBaseType(QQmlEnginePrivate *engine) const
|
|||
Q_ASSERT(isComposite());
|
||||
if (!engine)
|
||||
return 0;
|
||||
QQmlTypeData *td = engine->typeLoader.getType(sourceUrl());
|
||||
if (!td || !td->isComplete())
|
||||
QQmlRefPointer<QQmlTypeData> td(engine->typeLoader.getType(sourceUrl()), QQmlRefPointer<QQmlTypeData>::Adopt);
|
||||
if (td.isNull() || !td->isComplete())
|
||||
return 0;
|
||||
QV4::CompiledData::CompilationUnit *compilationUnit = td->compilationUnit();
|
||||
const QMetaObject *mo = compilationUnit->rootPropertyCache()->firstCppMetaObject();
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
stretches horizontally. The azure rectangle can be resized from 50x150 to 300x150, and the plum
|
||||
rectangle can be resized from 100x100 to ∞x100.
|
||||
|
||||
\snippet windowconstraints.qml rowlayout
|
||||
\snippet qml/windowconstraints.qml rowlayout
|
||||
|
||||
\image rowlayout-minimum.png "RowLayout at its minimum"
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ dedicated thread. Qt attempts to choose a suitable loop based on the
|
|||
platform and possibly the graphics drivers in use. When this is not
|
||||
satisfactory, or for testing purposes, the environment variable
|
||||
\c QSG_RENDER_LOOP can be used to force the usage of a given loop. To
|
||||
verify which render loop is in use, enable the \c qt.scenegraph.info
|
||||
verify which render loop is in use, enable the \c qt.scenegraph.general
|
||||
\l {QLoggingCategory}{logging category}.
|
||||
|
||||
\note The \c threaded and \c windows render loops rely on the OpenGL
|
||||
|
@ -374,7 +374,7 @@ addition to being helpful to Qt contributors.
|
|||
|
||||
\li \c {qt.scenegraph.time.glyph} - logs the time spent preparing distance field glyphs
|
||||
|
||||
\li \c {qt.scenegraph.info} - logs general information about various parts of the scene graph and the graphics stack
|
||||
\li \c {qt.scenegraph.general} - logs general information about various parts of the scene graph and the graphics stack
|
||||
|
||||
\li \c {qt.scenegraph.renderloop} - creates a detailed log of the various stages involved in rendering. This log mode is primarily useful for developers working on Qt.
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ Creator.
|
|||
\div {class="doc-column"}
|
||||
\b{Layouts and Views}
|
||||
\list
|
||||
\li \l{Qt Quick Controls - Basic Layouts Example}{Basic Layouts}
|
||||
\li \l{Qt Quick Layouts - Basic Example}
|
||||
\li \l{Qt Quick Examples - Positioners}{Positioners}
|
||||
\li \l{Qt Quick Examples - Views}{Views}
|
||||
\li \l{Qt Quick Examples - Window and Screen}{Windows and Screen}
|
||||
|
|
|
@ -708,7 +708,7 @@ void QQuickCanvasItem::updatePolish()
|
|||
|
||||
for (auto it = animationCallbacks.cbegin(), end = animationCallbacks.cend(); it != end; ++it) {
|
||||
QV4::ScopedFunctionObject f(scope, it.value().value());
|
||||
callData->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentDateTimeUtc().toTime_t());
|
||||
callData->args[0] = QV4::Primitive::fromUInt32(QDateTime::currentMSecsSinceEpoch() / 1000);
|
||||
f->call(scope, callData);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5772,6 +5772,8 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible)
|
|||
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
|
||||
if (windowPriv->mouseGrabberItem == q)
|
||||
q->ungrabMouse();
|
||||
if (!effectiveVisible)
|
||||
q->ungrabTouchPoints();
|
||||
}
|
||||
|
||||
bool childVisibilityChanged = false;
|
||||
|
@ -5820,6 +5822,8 @@ void QQuickItemPrivate::setEffectiveEnableRecur(QQuickItem *scope, bool newEffec
|
|||
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window);
|
||||
if (windowPriv->mouseGrabberItem == q)
|
||||
q->ungrabMouse();
|
||||
if (!effectiveEnable)
|
||||
q->ungrabTouchPoints();
|
||||
if (scope && !effectiveEnable && activeFocus) {
|
||||
windowPriv->clearFocusInScope(
|
||||
scope, q, Qt::OtherFocusReason, QQuickWindowPrivate::DontChangeFocusProperty | QQuickWindowPrivate::DontChangeSubFocusItem);
|
||||
|
|
|
@ -3147,7 +3147,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
|
|||
}
|
||||
}
|
||||
|
||||
int prevVisibleCount = visibleItems.count();
|
||||
bool visibleAffected = false;
|
||||
if (insertResult->visiblePos.isValid() && pos < insertResult->visiblePos) {
|
||||
// Insert items before the visible item.
|
||||
int insertionIdx = index;
|
||||
|
@ -3170,6 +3170,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
|
|||
if (!item)
|
||||
return false;
|
||||
|
||||
visibleAffected = true;
|
||||
visibleItems.insert(insertionIdx, item);
|
||||
if (insertionIdx == 0)
|
||||
insertResult->changedFirstItem = true;
|
||||
|
@ -3201,6 +3202,9 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
|
|||
|
||||
} else {
|
||||
qreal to = buffer + displayMarginEnd + tempPos + size();
|
||||
|
||||
visibleAffected = count > 0 && pos < to;
|
||||
|
||||
for (int i = 0; i < count && pos <= to; ++i) {
|
||||
FxViewItem *item = 0;
|
||||
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
|
||||
|
@ -3251,7 +3255,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
|
|||
|
||||
updateVisibleIndex();
|
||||
|
||||
return visibleItems.count() > prevVisibleCount;
|
||||
return visibleAffected;
|
||||
}
|
||||
|
||||
void QQuickListViewPrivate::translateAndTransitionItemsAfter(int afterModelIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult)
|
||||
|
|
|
@ -408,6 +408,15 @@ QImage QQuickSpriteEngine::assembledImage()
|
|||
|
||||
QImage img = state->m_pix.image();
|
||||
|
||||
{
|
||||
const QSize frameSize(state->m_frameWidth, state->m_frameHeight);
|
||||
if (!(img.size() - frameSize).isValid()) {
|
||||
qmlInfo(state).nospace() << "SpriteEngine: Invalid frame size " << frameSize << "."
|
||||
" It's bigger than image size " << img.size() << ".";
|
||||
return QImage();
|
||||
}
|
||||
}
|
||||
|
||||
//Check that the frame sizes are the same within one sprite
|
||||
if (!state->m_frameWidth)
|
||||
state->m_frameWidth = img.width() / state->frames();
|
||||
|
|
|
@ -240,8 +240,6 @@ public:
|
|||
|
||||
uint clearBeforeRendering : 1;
|
||||
|
||||
// Currently unused in the default implementation, as we're not stopping
|
||||
// rendering when obscured as we should...
|
||||
uint persistentGLContext : 1;
|
||||
uint persistentSceneGraph : 1;
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
// Used for very high-level info about the renderering and gl context
|
||||
// Includes GL_VERSION, type of render loop, atlas size, etc.
|
||||
Q_LOGGING_CATEGORY(QSG_LOG_INFO, "qt.scenegraph.info")
|
||||
Q_LOGGING_CATEGORY(QSG_LOG_INFO, "qt.scenegraph.general")
|
||||
|
||||
// Used to debug the renderloop logic. Primarily useful for platform integrators
|
||||
// and when investigating the render loop logic.
|
||||
|
|
|
@ -118,10 +118,7 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
|
|||
|
||||
engine = e;
|
||||
|
||||
if (engine.isNull())
|
||||
engine = new QQmlEngine(q);
|
||||
|
||||
if (!engine.data()->incubationController())
|
||||
if (!engine.isNull() && !engine.data()->incubationController())
|
||||
engine.data()->setIncubationController(offscreenWindow->incubationController());
|
||||
|
||||
#ifndef QT_NO_DRAGANDDROP
|
||||
|
@ -134,6 +131,16 @@ void QQuickWidgetPrivate::init(QQmlEngine* e)
|
|||
QObject::connect(renderControl, SIGNAL(sceneChanged()), q, SLOT(triggerUpdate()));
|
||||
}
|
||||
|
||||
void QQuickWidgetPrivate::ensureEngine() const
|
||||
{
|
||||
Q_Q(const QQuickWidget);
|
||||
if (!engine.isNull())
|
||||
return;
|
||||
|
||||
engine = new QQmlEngine(const_cast<QQuickWidget*>(q));
|
||||
engine.data()->setIncubationController(offscreenWindow->incubationController());
|
||||
}
|
||||
|
||||
void QQuickWidgetPrivate::invalidateRenderControl()
|
||||
{
|
||||
#ifndef QT_NO_OPENGL
|
||||
|
@ -215,10 +222,7 @@ QQuickWidgetPrivate::~QQuickWidgetPrivate()
|
|||
void QQuickWidgetPrivate::execute()
|
||||
{
|
||||
Q_Q(QQuickWidget);
|
||||
if (!engine) {
|
||||
qWarning() << "QQuickWidget: invalid qml engine.";
|
||||
return;
|
||||
}
|
||||
ensureEngine();
|
||||
|
||||
if (root) {
|
||||
delete root;
|
||||
|
@ -509,7 +513,6 @@ QQuickWidget::QQuickWidget(QQmlEngine* engine, QWidget *parent)
|
|||
{
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
Q_ASSERT(engine);
|
||||
d_func()->init(engine);
|
||||
}
|
||||
|
||||
|
@ -595,7 +598,8 @@ QUrl QQuickWidget::source() const
|
|||
QQmlEngine* QQuickWidget::engine() const
|
||||
{
|
||||
Q_D(const QQuickWidget);
|
||||
return d->engine ? const_cast<QQmlEngine *>(d->engine.data()) : 0;
|
||||
d->ensureEngine();
|
||||
return const_cast<QQmlEngine *>(d->engine.data());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -608,7 +612,8 @@ QQmlEngine* QQuickWidget::engine() const
|
|||
QQmlContext* QQuickWidget::rootContext() const
|
||||
{
|
||||
Q_D(const QQuickWidget);
|
||||
return d->engine ? d->engine.data()->rootContext() : 0;
|
||||
d->ensureEngine();
|
||||
return d->engine.data()->rootContext();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -653,7 +658,7 @@ QQmlContext* QQuickWidget::rootContext() const
|
|||
QQuickWidget::Status QQuickWidget::status() const
|
||||
{
|
||||
Q_D(const QQuickWidget);
|
||||
if (!d->engine)
|
||||
if (!d->engine && !d->source.isEmpty())
|
||||
return QQuickWidget::Error;
|
||||
|
||||
if (!d->component)
|
||||
|
@ -679,11 +684,12 @@ QList<QQmlError> QQuickWidget::errors() const
|
|||
if (d->component)
|
||||
errs = d->component->errors();
|
||||
|
||||
if (!d->engine) {
|
||||
if (!d->engine && !d->source.isEmpty()) {
|
||||
QQmlError error;
|
||||
error.setDescription(QLatin1String("QQuickWidget: invalid qml engine."));
|
||||
errs << error;
|
||||
} else if (d->component && d->component->status() == QQmlComponent::Ready && !d->root) {
|
||||
}
|
||||
if (d->component && d->component->status() == QQmlComponent::Ready && !d->root) {
|
||||
QQmlError error;
|
||||
error.setDescription(QLatin1String("QQuickWidget: invalid root object."));
|
||||
errs << error;
|
||||
|
@ -897,9 +903,10 @@ void QQuickWidget::createFramebufferObject()
|
|||
return;
|
||||
}
|
||||
|
||||
if (context->shareContext() != QWidgetPrivate::get(window())->shareContext()) {
|
||||
context->setShareContext(QWidgetPrivate::get(window())->shareContext());
|
||||
context->setScreen(context->shareContext()->screen());
|
||||
QOpenGLContext *shareWindowContext = QWidgetPrivate::get(window())->shareContext();
|
||||
if (shareWindowContext && context->shareContext() != shareWindowContext) {
|
||||
context->setShareContext(shareWindowContext);
|
||||
context->setScreen(shareWindowContext->screen());
|
||||
if (!context->create())
|
||||
qWarning("QQuickWidget: Failed to recreate context");
|
||||
// The screen may be different so we must recreate the offscreen surface too.
|
||||
|
@ -1249,15 +1256,20 @@ void QQuickWidget::showEvent(QShowEvent *)
|
|||
d->createContext();
|
||||
if (d->offscreenWindow->openglContext()) {
|
||||
d->render(true);
|
||||
if (d->updatePending) {
|
||||
// render() may have led to a QQuickWindow::update() call (for
|
||||
// example, having a scene with a QQuickFramebufferObject::Renderer
|
||||
// calling update() in its render()) which in turn results in
|
||||
// renderRequested in the rendercontrol, ending up in
|
||||
// triggerUpdate. In this case just calling update() is not
|
||||
// acceptable, we need the full renderSceneGraph issued from
|
||||
// timerEvent().
|
||||
if (!d->eventPending && d->updatePending) {
|
||||
d->updatePending = false;
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
triggerUpdate();
|
||||
}
|
||||
} else {
|
||||
triggerUpdate();
|
||||
}
|
||||
QWindowPrivate *offscreenPrivate = QWindowPrivate::get(d->offscreenWindow);
|
||||
if (!offscreenPrivate->visible) {
|
||||
|
@ -1375,6 +1387,17 @@ bool QQuickWidget::event(QEvent *e)
|
|||
break;
|
||||
|
||||
case QEvent::ScreenChangeInternal:
|
||||
if (QWindow *window = this->window()->windowHandle()) {
|
||||
QScreen *newScreen = window->screen();
|
||||
|
||||
if (d->offscreenWindow)
|
||||
d->offscreenWindow->setScreen(newScreen);
|
||||
if (d->offscreenSurface)
|
||||
d->offscreenSurface->setScreen(newScreen);
|
||||
if (d->context)
|
||||
d->context->setScreen(newScreen);
|
||||
}
|
||||
|
||||
if (d->useSoftwareRenderer
|
||||
#ifndef QT_NO_OPENGL
|
||||
|| d->fbo
|
||||
|
|
|
@ -109,6 +109,7 @@ public:
|
|||
#endif
|
||||
|
||||
void init(QQmlEngine* e = 0);
|
||||
void ensureEngine() const;
|
||||
void handleWindowChange();
|
||||
void invalidateRenderControl();
|
||||
|
||||
|
@ -118,7 +119,7 @@ public:
|
|||
|
||||
QUrl source;
|
||||
|
||||
QPointer<QQmlEngine> engine;
|
||||
mutable QPointer<QQmlEngine> engine;
|
||||
QQmlComponent *component;
|
||||
QBasicTimer resizetimer;
|
||||
QQuickWindow *offscreenWindow;
|
||||
|
|
|
@ -9,8 +9,3 @@ linux
|
|||
linux
|
||||
[ListView::test_listInteractiveCurrentIndexEnforce]
|
||||
linux
|
||||
[Text::test_linecount]
|
||||
osx
|
||||
windows
|
||||
[TextInput::test_doublevalidators]
|
||||
osx
|
||||
|
|
|
@ -102,7 +102,7 @@ Item {
|
|||
property int callCount: 0;
|
||||
property bool ready: false;
|
||||
function handleGrab(result) {
|
||||
if (!result.saveToFile("image.png"))
|
||||
if (!result.saveToFile("itemgrabber/image.png"))
|
||||
print("Error: Failed to save image to disk...");
|
||||
source = "image.png";
|
||||
ready = true;
|
||||
|
@ -116,7 +116,7 @@ Item {
|
|||
y: 0
|
||||
property bool ready: false;
|
||||
function handleGrab(result) {
|
||||
if (!result.saveToFile("image_small.png"))
|
||||
if (!result.saveToFile("itemgrabber/image_small.png"))
|
||||
print("Error: Failed to save image to disk...");
|
||||
source = "image_small.png";
|
||||
ready = true;
|
|
@ -277,6 +277,7 @@ Item {
|
|||
}
|
||||
|
||||
function test_doublevalidators(row) {
|
||||
txtdoublevalidator.validator.locale = "C"
|
||||
compare(txtdoublevalidator.validator.top, 2.0)
|
||||
compare(txtdoublevalidator.validator.bottom, 1.0)
|
||||
txtdoublevalidator.text = row.testnumber;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 238 B |
Binary file not shown.
After Width: | Height: | Size: 135 B |
|
@ -0,0 +1,46 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 2.4
|
||||
|
||||
AnimatedSprite {
|
||||
id: animatedSprite
|
||||
source: big ? "img100x100.png" : "img50x50.png"
|
||||
frameWidth: 100
|
||||
frameHeight: 100
|
||||
property bool big: true
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: animatedSprite.big = !animatedSprite.big
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@
|
|||
#include <QtGui/qopenglcontext.h>
|
||||
#include <QtGui/qopenglfunctions.h>
|
||||
#include <QtGui/qoffscreensurface.h>
|
||||
#include <QtQml/qqmlproperty.h>
|
||||
|
||||
class tst_qquickanimatedsprite : public QQmlDataTest
|
||||
{
|
||||
|
@ -50,6 +51,7 @@ private slots:
|
|||
void test_largeAnimation_data();
|
||||
void test_largeAnimation();
|
||||
void test_reparenting();
|
||||
void test_changeSourceToSmallerImgKeepingBigFrameSize();
|
||||
};
|
||||
|
||||
void tst_qquickanimatedsprite::initTestCase()
|
||||
|
@ -286,6 +288,43 @@ void tst_qquickanimatedsprite::test_reparenting()
|
|||
QTRY_COMPARE(QQuickItemPrivate::get(sprite)->polishScheduled, false);
|
||||
}
|
||||
|
||||
class KillerThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
void run() Q_DECL_OVERRIDE {
|
||||
sleep(3);
|
||||
qFatal("Either the GUI or the render thread is stuck in an infinite loop.");
|
||||
}
|
||||
};
|
||||
|
||||
// Regression test for QTBUG-53937
|
||||
void tst_qquickanimatedsprite::test_changeSourceToSmallerImgKeepingBigFrameSize()
|
||||
{
|
||||
QQuickView window;
|
||||
window.setSource(testFileUrl("sourceSwitch.qml"));
|
||||
window.show();
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&window));
|
||||
|
||||
QVERIFY(window.rootObject());
|
||||
QQuickAnimatedSprite* sprite = qobject_cast<QQuickAnimatedSprite*>(window.rootObject());
|
||||
QVERIFY(sprite);
|
||||
|
||||
QQmlProperty big(sprite, "big");
|
||||
big.write(QVariant::fromValue(false));
|
||||
|
||||
KillerThread *killer = new KillerThread;
|
||||
killer->start(); // will kill us in case the GUI or render thread enters an infinite loop
|
||||
|
||||
QTest::qWait(50); // let it draw with the new source.
|
||||
|
||||
// If we reach this point it's because we didn't hit QTBUG-53937
|
||||
|
||||
killer->terminate();
|
||||
killer->wait();
|
||||
delete killer;
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qquickanimatedsprite)
|
||||
|
||||
#include "tst_qquickanimatedsprite.moc"
|
||||
|
|
|
@ -629,6 +629,8 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
|
|||
}
|
||||
listview->setContentY(contentY);
|
||||
|
||||
QQuickItemViewPrivate::get(listview)->layout();
|
||||
|
||||
QList<QPair<QString, QString> > newData;
|
||||
for (int i=0; i<insertCount; i++)
|
||||
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
|
||||
|
@ -650,6 +652,16 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
|
|||
QCOMPARE(item0->y(), itemsOffsetAfterMove);
|
||||
#endif
|
||||
|
||||
QList<FxViewItem *> visibleItems = QQuickItemViewPrivate::get(listview)->visibleItems;
|
||||
for (QList<FxViewItem *>::const_iterator itemIt = visibleItems.begin(); itemIt != visibleItems.end(); ++itemIt)
|
||||
{
|
||||
FxViewItem *item = *itemIt;
|
||||
if (item->item->position().y() >= 0 && item->item->position().y() < listview->height())
|
||||
{
|
||||
QVERIFY(!QQuickItemPrivate::get(item->item)->culled);
|
||||
}
|
||||
}
|
||||
|
||||
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
|
||||
int firstVisibleIndex = -1;
|
||||
for (int i=0; i<items.count(); i++) {
|
||||
|
@ -770,6 +782,11 @@ void tst_QQuickListView::inserted_more_data()
|
|||
<< 80.0 // show 4-19
|
||||
<< 20 << 3
|
||||
<< 0.0;
|
||||
|
||||
QTest::newRow("add multiple, within visible, content at start")
|
||||
<< 0.0
|
||||
<< 2 << 50
|
||||
<< 0.0;
|
||||
}
|
||||
|
||||
void tst_QQuickListView::insertBeforeVisible()
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
MultiPointTouchArea {
|
||||
width: 240
|
||||
height: 320
|
||||
|
||||
minimumTouchPoints: 1
|
||||
maximumTouchPoints: 5
|
||||
touchPoints: [
|
||||
TouchPoint { objectName: "point1" },
|
||||
TouchPoint { objectName: "point2" },
|
||||
TouchPoint { objectName: "point3" },
|
||||
TouchPoint { objectName: "point4" },
|
||||
TouchPoint { objectName: "point5" }
|
||||
]
|
||||
|
||||
function clearCounts() {
|
||||
touchPointPressCount = 0;
|
||||
touchPointUpdateCount = 0;
|
||||
touchPointReleaseCount = 0;
|
||||
touchPointCancelCount = 0;
|
||||
touchCount = 0;
|
||||
touchUpdatedHandled = false;
|
||||
}
|
||||
|
||||
property int touchPointPressCount: 0
|
||||
property int touchPointUpdateCount: 0
|
||||
property int touchPointReleaseCount: 0
|
||||
property int touchPointCancelCount: 0
|
||||
property int touchCount: 0
|
||||
property bool touchUpdatedHandled: false
|
||||
|
||||
onPressed: { touchPointPressCount = touchPoints.length }
|
||||
onUpdated: { touchPointUpdateCount = touchPoints.length }
|
||||
onReleased: { touchPointReleaseCount = touchPoints.length }
|
||||
onCanceled: { touchPointCancelCount = touchPoints.length }
|
||||
onTouchUpdated: {
|
||||
touchCount = touchPoints.length
|
||||
touchUpdatedHandled = true
|
||||
}
|
||||
}
|
|
@ -69,6 +69,7 @@ private slots:
|
|||
void transformedTouchArea();
|
||||
void mouseInteraction();
|
||||
void mouseInteraction_data();
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
QQuickView *createAndShowView(const QString &file);
|
||||
|
@ -1195,6 +1196,60 @@ void tst_QQuickMultiPointTouchArea::mouseInteraction()
|
|||
QCOMPARE(area->property("touchCount").toInt(), 0);
|
||||
}
|
||||
|
||||
void tst_QQuickMultiPointTouchArea::cancel()
|
||||
{
|
||||
QScopedPointer<QQuickView> window(createAndShowView("cancel.qml"));
|
||||
QVERIFY(window->rootObject() != 0);
|
||||
|
||||
QQuickMultiPointTouchArea *area = qobject_cast<QQuickMultiPointTouchArea *>(window->rootObject());
|
||||
QTest::QTouchEventSequence sequence = QTest::touchEvent(window.data(), device);
|
||||
QQuickTouchPoint *point1 = area->findChild<QQuickTouchPoint*>("point1");
|
||||
|
||||
QPoint p1(20,100);
|
||||
sequence.press(0, p1).commit();
|
||||
QQuickTouchUtils::flush(window.data());
|
||||
QCOMPARE(point1->pressed(), true);
|
||||
QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
|
||||
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointCancelCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchCount").toInt(), 1);
|
||||
QMetaObject::invokeMethod(area, "clearCounts");
|
||||
|
||||
area->setVisible(false);
|
||||
// we should get a onCancel signal
|
||||
QCOMPARE(point1->pressed(), false);
|
||||
QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointCancelCount").toInt(), 1);
|
||||
QCOMPARE(area->property("touchCount").toInt(), 0);
|
||||
QMetaObject::invokeMethod(area, "clearCounts");
|
||||
area->setVisible(true);
|
||||
|
||||
|
||||
sequence.press(0, p1).commit();
|
||||
QQuickTouchUtils::flush(window.data());
|
||||
QCOMPARE(point1->pressed(), true);
|
||||
QCOMPARE(area->property("touchPointPressCount").toInt(), 1);
|
||||
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointCancelCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchCount").toInt(), 1);
|
||||
QMetaObject::invokeMethod(area, "clearCounts");
|
||||
|
||||
area->setEnabled(false);
|
||||
// we should get a onCancel signal
|
||||
QCOMPARE(point1->pressed(), false);
|
||||
QCOMPARE(area->property("touchPointPressCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointUpdateCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointReleaseCount").toInt(), 0);
|
||||
QCOMPARE(area->property("touchPointCancelCount").toInt(), 1);
|
||||
QCOMPARE(area->property("touchCount").toInt(), 0);
|
||||
QMetaObject::invokeMethod(area, "clearCounts");
|
||||
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QQuickMultiPointTouchArea)
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ private slots:
|
|||
void renderingSignals();
|
||||
void grabBeforeShow();
|
||||
void reparentToNewWindow();
|
||||
void nullEngine();
|
||||
};
|
||||
|
||||
|
||||
|
@ -324,6 +325,18 @@ void tst_qquickwidget::reparentToNewWindow()
|
|||
QCOMPARE(img.pixel(5, 5), qRgb(255, 0, 0));
|
||||
}
|
||||
|
||||
void tst_qquickwidget::nullEngine()
|
||||
{
|
||||
QQuickWidget widget;
|
||||
// Default should have no errors, even with a null qml engine
|
||||
QVERIFY(widget.errors().isEmpty());
|
||||
QCOMPARE(widget.status(), QQuickWidget::Null);
|
||||
|
||||
// A QML engine should be created lazily.
|
||||
QVERIFY(widget.rootContext());
|
||||
QVERIFY(widget.engine());
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_qquickwidget)
|
||||
|
||||
#include "tst_qquickwidget.moc"
|
||||
|
|
|
@ -979,8 +979,9 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (!requireWindowManager)
|
||||
qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("minimal"));
|
||||
else
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
|
||||
|
||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true);
|
||||
QGuiApplication app(argc, argv);
|
||||
const QStringList args = app.arguments();
|
||||
const QString appName = QFileInfo(app.applicationFilePath()).baseName();
|
||||
|
|
Loading…
Reference in New Issue