aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-02-15 08:08:32 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-02-15 08:08:32 +0100
commit7a3dd4c1aef155bae57f0b79eacb3d85e1158c1e (patch)
tree5be261a82b44987cc026779ee7315875ee31f21a
parent0fab5761d5428aa708edd66e40fc3c449adc4b11 (diff)
parent19dffeed2e677cf03b6e122c7a15f355ebe413c8 (diff)
Merge remote-tracking branch 'origin/5.6.0' into 5.6
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/quick/items/qquickitem.cpp30
-rw-r--r--src/quick/items/qquickitem.h3
-rw-r--r--src/quick/items/qquicktext.cpp19
-rw-r--r--src/quick/items/qquickwindow.cpp39
-rw-r--r--src/quick/items/qquickwindow.h1
-rw-r--r--src/quick/items/qquickwindow_p.h3
-rw-r--r--src/quick/quick.pro2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp26
-rw-r--r--tests/auto/quick/qquickitem2/data/qtbug_50516_2_1.qml13
-rw-r--r--tests/auto/quick/qquickitem2/data/qtbug_50516_2_2.qml12
-rw-r--r--tests/auto/quick/qquickitem2/data/qtbug_50516_2_3.qml16
-rw-r--r--tests/auto/quick/qquickitem2/data/qtbug_50516_2_4.qml15
-rw-r--r--tests/auto/quick/qquickitem2/data/qtbug_50516_2_5.qml16
-rw-r--r--tests/auto/quick/qquickitem2/data/qtbug_50516_2_6.qml17
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp64
16 files changed, 268 insertions, 10 deletions
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 8f471132b7..bcd97efee8 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -330,6 +330,8 @@ ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *obje
} else if (property->isV4Function()) {
Scope scope(engine);
ScopedContext global(scope, engine->qmlContext());
+ if (!global)
+ global = engine->rootContext();
return QV4::QObjectMethod::create(global, object, property->coreIndex);
} else if (property->isSignalHandler()) {
QmlSignalHandler::initProto(engine);
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index b603e1a58f..24e52ff65e 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2068,6 +2068,10 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus)
\value ItemRotationHasChanged The item's rotation has changed.
ItemChangeData::realValue contains the new rotation.
+
+ \value ItemDevicePixelRatioHasChanged The device pixel ratio of the screen
+ the item is on has changed. ItemChangedData::realValue contains the new
+ device pixel ratio.
*/
/*!
@@ -2471,6 +2475,7 @@ QQuickItem *QQuickItemPrivate::prevTabChildItem(const QQuickItem *item, int star
QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, bool forward)
{
Q_ASSERT(item);
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: item:" << item << ", forward:" << forward;
if (!item->window())
return item;
@@ -2481,19 +2486,25 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
bool all = QGuiApplication::styleHints()->tabFocusBehavior() == Qt::TabFocusAllControls;
QQuickItem *from = 0;
+ bool isTabFence = item->d_func()->isTabFence;
if (forward) {
- from = item->parentItem();
+ if (!isTabFence)
+ from = item->parentItem();
} else {
if (!item->childItems().isEmpty())
from = item->childItems().first();
- else
+ else if (!isTabFence)
from = item->parentItem();
}
bool skip = false;
QQuickItem * startItem = item;
QQuickItem * firstFromItem = from;
QQuickItem *current = item;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: startItem:" << startItem;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: firstFromItem:" << firstFromItem;
do {
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: current:" << current;
+ qCDebug(DBG_FOCUS) << "QQuickItemPrivate::nextPrevItemInTabFocusChain: from:" << from;
skip = false;
QQuickItem *last = current;
@@ -2507,7 +2518,7 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
else
lastChild = prevTabChildItem(current, -1);
}
- bool isTabFence = current->d_func()->isTabFence;
+ isTabFence = current->d_func()->isTabFence;
if (isTabFence && !hasChildren)
return current;
@@ -2562,9 +2573,14 @@ QQuickItem* QQuickItemPrivate::nextPrevItemInTabFocusChain(QQuickItem *item, boo
return startItem;
}
}
- if (!firstFromItem) { //start from root
- startItem = current;
- firstFromItem = from;
+ if (!firstFromItem) {
+ if (startItem->d_func()->isTabFence) {
+ if (current == startItem)
+ firstFromItem = from;
+ } else { //start from root
+ startItem = current;
+ firstFromItem = from;
+ }
}
} while (skip || !current->activeFocusOnTab() || !current->isEnabled() || !current->isVisible()
|| !(all || QQuickItemPrivate::canAcceptTabFocus(current)));
@@ -5940,6 +5956,8 @@ void QQuickItemPrivate::itemChange(QQuickItem::ItemChange change, const QQuickIt
}
break;
case QQuickItem::ItemAntialiasingHasChanged:
+ // fall through
+ case QQuickItem::ItemDevicePixelRatioHasChanged:
q->itemChange(change, data);
break;
}
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index d92910ce9c..bda6dd4da5 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -166,7 +166,8 @@ public:
ItemOpacityHasChanged, // value.realValue
ItemActiveFocusHasChanged, // value.boolValue
ItemRotationHasChanged, // value.realValue
- ItemAntialiasingHasChanged // value.boolValue
+ ItemAntialiasingHasChanged, // value.boolValue
+ ItemDevicePixelRatioHasChanged // value.realValue
};
union ItemChangeData {
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 3aec464958..aa8f04e55d 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -1455,7 +1455,8 @@ void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
{
Q_D(QQuickText);
Q_UNUSED(value);
- if (change == ItemAntialiasingHasChanged) {
+ switch (change) {
+ case ItemAntialiasingHasChanged:
if (!antialiasing())
d->font.setStyleStrategy(QFont::NoAntialias);
else
@@ -1463,6 +1464,22 @@ void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
d->implicitWidthValid = false;
d->implicitHeightValid = false;
d->updateLayout();
+ break;
+
+ case ItemDevicePixelRatioHasChanged:
+ if (d->renderType == NativeRendering) {
+ // Native rendering optimizes for a given pixel grid, so its results must not be scaled.
+ // Text layout code respects the current device pixel ratio automatically, we only need
+ // to rerun layout after the ratio changed.
+ // Changes of implicit size should be minimal; they are hard to avoid.
+ d->implicitWidthValid = false;
+ d->implicitHeightValid = false;
+ d->updateLayout();
+ }
+ break;
+
+ default:
+ break;
}
QQuickItem::itemChange(change, value);
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index b93aa06336..24bac168ea 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -285,10 +285,43 @@ void QQuickWindow::update()
QQuickRenderControlPrivate::get(d->renderControl)->update();
}
+static void updatePixelRatioHelper(QQuickItem *item, float pixelRatio)
+{
+ if (item->flags() & QQuickItem::ItemHasContents) {
+ QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
+ itemPrivate->itemChange(QQuickItem::ItemDevicePixelRatioHasChanged, pixelRatio);
+ }
+
+ QList <QQuickItem *> items = item->childItems();
+ for (int i = 0; i < items.size(); ++i)
+ updatePixelRatioHelper(items.at(i), pixelRatio);
+}
+
+void QQuickWindow::physicalDpiChanged()
+{
+ Q_D(QQuickWindow);
+ const qreal newPixelRatio = screen()->devicePixelRatio();
+ if (qFuzzyCompare(newPixelRatio, d->devicePixelRatio))
+ return;
+ d->devicePixelRatio = newPixelRatio;
+ if (d->contentItem)
+ updatePixelRatioHelper(d->contentItem, newPixelRatio);
+}
+
void QQuickWindow::handleScreenChanged(QScreen *screen)
{
Q_D(QQuickWindow);
- Q_UNUSED(screen)
+ if (screen) {
+ physicalDpiChanged();
+ // When physical DPI changes on the same screen, either the resolution or the device pixel
+ // ratio changed. We must check what it is. Device pixel ratio does not have its own
+ // ...Changed() signal.
+ d->physicalDpiChangedConnection = connect(screen, SIGNAL(physicalDotsPerInchChanged(qreal)),
+ this, SLOT(physicalDpiChanged()));
+ } else {
+ disconnect(d->physicalDpiChangedConnection);
+ }
+
d->forcePolish();
}
@@ -407,6 +440,7 @@ QQuickWindowPrivate::QQuickWindowPrivate()
, touchMouseId(-1)
, touchMousePressTimestamp(0)
, dirtyItemList(0)
+ , devicePixelRatio(0)
, context(0)
, renderer(0)
, windowManager(0)
@@ -459,6 +493,9 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control)
Q_ASSERT(windowManager || renderControl);
+ if (QScreen *screen = q->screen())
+ devicePixelRatio = screen->devicePixelRatio();
+
QSGContext *sg;
if (renderControl) {
QQuickRenderControlPrivate *renderControlPriv = QQuickRenderControlPrivate::get(renderControl);
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index 9f8ad095cd..d4ffb100de 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -196,6 +196,7 @@ protected:
private Q_SLOTS:
void maybeUpdate();
void cleanupSceneGraph();
+ void physicalDpiChanged();
void handleScreenChanged(QScreen *screen);
void setTransientParent_helper(QQuickWindow *window);
void runJobsAfterSwap();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index 623707140e..787958ef86 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -205,6 +205,9 @@ public:
QVector<QQuickItem *> itemsToPolish;
+ qreal devicePixelRatio;
+ QMetaObject::Connection physicalDpiChangedConnection;
+
void updateDirtyNodes();
void cleanupNodes();
void cleanupNodesOnShutdown();
diff --git a/src/quick/quick.pro b/src/quick/quick.pro
index 4ff2d76a09..c8aa47d939 100644
--- a/src/quick/quick.pro
+++ b/src/quick/quick.pro
@@ -29,7 +29,7 @@ load(qt_module)
include(util/util.pri)
include(scenegraph/scenegraph.pri)
include(items/items.pri)
-include(designer/designer.pri)
+!wince:include(designer/designer.pri)
contains(QT_CONFIG, accessibility) {
include(accessible/accessible.pri)
}
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 39bc8b2e5f..35824c6d00 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -190,6 +190,8 @@ private slots:
void argumentEvaluationOrder();
+ void v4FunctionWithoutQML();
+
signals:
void testSignal();
};
@@ -3799,6 +3801,30 @@ void tst_QJSEngine::argumentEvaluationOrder()
}
+class TestObject : public QObject
+{
+ Q_OBJECT
+public:
+ TestObject() : called(false) {}
+
+ bool called;
+
+ Q_INVOKABLE void callMe(QQmlV4Function *) {
+ called = true;
+ }
+};
+
+void tst_QJSEngine::v4FunctionWithoutQML()
+{
+ TestObject obj;
+ QJSEngine engine;
+ QJSValue wrapper = engine.newQObject(&obj);
+ QQmlEngine::setObjectOwnership(&obj, QQmlEngine::CppOwnership);
+ QVERIFY(!obj.called);
+ wrapper.property("callMe").call();
+ QVERIFY(obj.called);
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"
diff --git a/tests/auto/quick/qquickitem2/data/qtbug_50516_2_1.qml b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_1.qml
new file mode 100644
index 0000000000..d8b7833467
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_1.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.1
+import Test 1.0
+
+TabFence2 {
+ objectName: "root"
+ focus: true
+ width: 800
+ height: 600
+ Item {
+ objectName: "item"
+ focus: true
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/qtbug_50516_2_2.qml b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_2.qml
new file mode 100644
index 0000000000..445dc6d2a1
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_2.qml
@@ -0,0 +1,12 @@
+import QtQuick 2.1
+import Test 1.0
+
+TabFence2 {
+ objectName: "root"
+ focus: true
+ width: 800
+ height: 600
+ Item {
+ objectName: "item"
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/qtbug_50516_2_3.qml b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_3.qml
new file mode 100644
index 0000000000..806d48ebeb
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_3.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.1
+import Test 1.0
+
+TabFence2 {
+ objectName: "root"
+ focus: true
+ width: 800
+ height: 600
+ Item {
+ objectName: "item2"
+ focus: true
+ }
+ Item {
+ objectName: "item2"
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/qtbug_50516_2_4.qml b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_4.qml
new file mode 100644
index 0000000000..6fcf513b51
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_4.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.1
+import Test 1.0
+
+TabFence2 {
+ objectName: "root"
+ focus: true
+ width: 800
+ height: 600
+ Item {
+ objectName: "item2"
+ }
+ Item {
+ objectName: "item2"
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/qtbug_50516_2_5.qml b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_5.qml
new file mode 100644
index 0000000000..4f7b68a8de
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_5.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.1
+import Test 1.0
+
+TabFence2 {
+ objectName: "root"
+ focus: true
+ width: 800
+ height: 600
+ TextInput {
+ objectName: "item1"
+ activeFocusOnTab: true
+ }
+ Item {
+ objectName: "item2"
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/qtbug_50516_2_6.qml b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_6.qml
new file mode 100644
index 0000000000..223476327a
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/qtbug_50516_2_6.qml
@@ -0,0 +1,17 @@
+import QtQuick 2.1
+import Test 1.0
+
+TabFence2 {
+ objectName: "root"
+ focus: true
+ width: 800
+ height: 600
+ TextInput {
+ objectName: "item1"
+ activeFocusOnTab: true
+ }
+ TextInput {
+ objectName: "item2"
+ activeFocusOnTab: true
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index 8a75cba84a..58dca5c1a3 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -75,6 +75,8 @@ private slots:
void tabFence();
void qtbug_50516();
+ void qtbug_50516_2_data();
+ void qtbug_50516_2();
void keys();
void standardKeys_data();
@@ -309,6 +311,22 @@ public:
QML_DECLARE_TYPE(TabFenceItem);
+class TabFenceItem2 : public QQuickItem
+{
+ Q_OBJECT
+
+public:
+ TabFenceItem2(QQuickItem *parent = Q_NULLPTR)
+ : QQuickItem(parent)
+ {
+ QQuickItemPrivate *d = QQuickItemPrivate::get(this);
+ d->isTabFence = true;
+ setFlag(ItemIsFocusScope);
+ }
+};
+
+QML_DECLARE_TYPE(TabFenceItem2);
+
tst_QQuickItem::tst_QQuickItem()
{
}
@@ -319,6 +337,7 @@ void tst_QQuickItem::initTestCase()
qmlRegisterType<KeyTestItem>("Test",1,0,"KeyTestItem");
qmlRegisterType<HollowTestItem>("Test", 1, 0, "HollowTestItem");
qmlRegisterType<TabFenceItem>("Test", 1, 0, "TabFence");
+ qmlRegisterType<TabFenceItem2>("Test", 1, 0, "TabFence2");
}
void tst_QQuickItem::cleanup()
@@ -1216,6 +1235,51 @@ void tst_QQuickItem::qtbug_50516()
delete window;
}
+void tst_QQuickItem::qtbug_50516_2_data()
+{
+ QTest::addColumn<QString>("filename");
+ QTest::addColumn<QString>("item1");
+ QTest::addColumn<QString>("item2");
+
+ QTest::newRow("FocusScope TabFence with one Item(focused)")
+ << QStringLiteral("qtbug_50516_2_1.qml") << QStringLiteral("root") << QStringLiteral("root");
+ QTest::newRow("FocusScope TabFence with one Item(unfocused)")
+ << QStringLiteral("qtbug_50516_2_2.qml") << QStringLiteral("root") << QStringLiteral("root");
+ QTest::newRow("FocusScope TabFence with two Items(focused)")
+ << QStringLiteral("qtbug_50516_2_3.qml") << QStringLiteral("root") << QStringLiteral("root");
+ QTest::newRow("FocusScope TabFence with two Items(unfocused)")
+ << QStringLiteral("qtbug_50516_2_4.qml") << QStringLiteral("root") << QStringLiteral("root");
+ QTest::newRow("FocusScope TabFence with one Item and one TextInput(unfocused)")
+ << QStringLiteral("qtbug_50516_2_5.qml") << QStringLiteral("item1") << QStringLiteral("item1");
+ QTest::newRow("FocusScope TabFence with two TextInputs(unfocused)")
+ << QStringLiteral("qtbug_50516_2_6.qml") << QStringLiteral("item1") << QStringLiteral("item2");
+}
+
+void tst_QQuickItem::qtbug_50516_2()
+{
+ QFETCH(QString, filename);
+ QFETCH(QString, item1);
+ QFETCH(QString, item2);
+
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(800,600));
+
+ window->setSource(testFileUrl(filename));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+ QVERIFY(window->rootObject()->hasActiveFocus());
+
+ QQuickItem *contentItem = window->rootObject();
+ QQuickItem *next = contentItem->nextItemInFocusChain(true);
+ QCOMPARE(next->objectName(), item1);
+ next = contentItem->nextItemInFocusChain(false);
+ QCOMPARE(next->objectName(), item2);
+
+ delete window;
+}
+
void tst_QQuickItem::keys()
{
QQuickView *window = new QQuickView(0);