aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/doc/src/includes/item.qdocinc3
-rw-r--r--src/quick/items/qquickitem.cpp14
-rw-r--r--tests/auto/quick/qquickitem2/data/mapCoordinatesWithWindows.qml51
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp72
4 files changed, 138 insertions, 2 deletions
diff --git a/src/quick/doc/src/includes/item.qdocinc b/src/quick/doc/src/includes/item.qdocinc
index f70d3b483c..0dd3fc086f 100644
--- a/src/quick/doc/src/includes/item.qdocinc
+++ b/src/quick/doc/src/includes/item.qdocinc
@@ -3,6 +3,9 @@
The following properties of the item are used in the mapping:
\l x, \l y, \l scale, \l rotation, \l transformOrigin, and \l [QML]{Item::}{transform}.
+If the items are part of different scenes, the mapping includes
+the relative position of the two scenes.
+
//! [mapping]
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 7b10b09b50..8a92841176 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -8734,8 +8734,12 @@ void QQuickItem::setContainmentMask(QObject *mask)
QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) const
{
QPointF p = mapToScene(point);
- if (item)
+ if (item) {
+ if (item->window() != window())
+ p = item->window()->mapFromGlobal(window()->mapToGlobal(p));
+
p = item->mapFromScene(p);
+ }
return p;
}
@@ -8827,7 +8831,13 @@ QRectF QQuickItem::mapRectToScene(const QRectF &rect) const
*/
QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) const
{
- QPointF p = item?item->mapToScene(point):point;
+ QPointF p = point;
+ if (item) {
+ p = item->mapToScene(point);
+
+ if (item->window() != window())
+ p = window()->mapFromGlobal(item->window()->mapToGlobal(p));
+ }
return mapFromScene(p);
}
diff --git a/tests/auto/quick/qquickitem2/data/mapCoordinatesWithWindows.qml b/tests/auto/quick/qquickitem2/data/mapCoordinatesWithWindows.qml
new file mode 100644
index 0000000000..8218c5230a
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/mapCoordinatesWithWindows.qml
@@ -0,0 +1,51 @@
+import QtQuick
+
+QtObject {
+ id: root
+
+ property Window windowA: Window {
+ visible: true
+ flags: Qt.FramelessWindowHint
+ color: "green"
+ x: 100; y: 100
+ width: 300; height: 300
+
+ Rectangle {
+ objectName: "childItem"
+ x: 50; y: 50
+ width: 100; height: 100
+ color: "red"
+ }
+
+ Window {
+ objectName: "childWindow"
+ parent: windowA
+ x: 100; y: 100
+ width: 100; height: 100
+ visible: true
+ color: "blue"
+
+ Rectangle {
+ objectName: "childItemInChildWindow"
+ x: 30; y: 30
+ width: 50; height: 50
+ color: "orange"
+ }
+ }
+ }
+
+ property Window windowB: Window {
+ visible: true
+ flags: Qt.FramelessWindowHint
+ color: "magenta"
+ x: 500; y: 200
+ width: 200; height: 200
+
+ Rectangle {
+ objectName: "childItem"
+ x: 50; y: 50
+ width: 100; height: 100
+ color: "cyan"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index dd6ae73b95..2e2abbcd33 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -17,6 +17,7 @@
#include <QtQuick/private/qquickanchors_p.h>
#include <QtGui/qstylehints.h>
#include <private/qquickitem_p.h>
+#include <QtQuickTest/QtQuickTest>
#include <QtQuickTestUtils/private/qmlutils_p.h>
#include <QtQuickTestUtils/private/visualtestutils_p.h>
#include <QtQuickTestUtils/private/viewtestutils_p.h>
@@ -88,6 +89,7 @@ private slots:
void mapCoordinates_data();
void mapCoordinatesRect();
void mapCoordinatesRect_data();
+ void mapCoordinatesWithWindows();
void propertyChanges();
void nonexistentPropertyConnection();
void transforms();
@@ -2800,6 +2802,76 @@ void tst_QQuickItem::mapCoordinatesRect_data()
QTest::newRow(QTest::toString(i)) << i << i << i << i;
}
+void tst_QQuickItem::mapCoordinatesWithWindows()
+{
+ QQmlComponent component(&engine, testFileUrl("mapCoordinatesWithWindows.qml"));
+ std::unique_ptr<QObject> root(component.create());
+ QVERIFY(root);
+
+ auto *windowA = root->property("windowA").value<QQuickWindow*>();
+ QVERIFY(windowA);
+
+ // The window container geometry, parenting, etc, is applied
+ // during polish, so to test these we need to wait for one.
+ QVERIFY(QQuickTest::qWaitForPolish(windowA));
+
+ auto *childItem = windowA->findChild<QQuickItem*>("childItem");
+ QVERIFY(childItem);
+
+ QPoint itemPos = childItem->position().toPoint();
+ QCOMPARE(childItem->mapToScene({0, 0}), itemPos);
+ QCOMPARE(childItem->mapToGlobal({0, 0}), windowA->position() + itemPos);
+
+ auto *childItemInChildWindow = windowA->findChild<QQuickItem*>("childItemInChildWindow");
+ QVERIFY(childItemInChildWindow);
+
+ QPoint windowItemPos = childItemInChildWindow->position().toPoint();
+ QCOMPARE(childItemInChildWindow->mapToScene({0, 0}), windowItemPos);
+ QCOMPARE(childItemInChildWindow->mapToGlobal({0, 0}), windowA->position()
+ + childItemInChildWindow->window()->position() + windowItemPos);
+
+ QCOMPARE(childItemInChildWindow->mapToItem(nullptr, {0, 0}), windowItemPos);
+
+ auto globalItemOffset = [](QQuickItem *a, QQuickItem *b) {
+ return a->mapToGlobal({0, 0}) - b->mapToGlobal({0, 0});
+ };
+
+ QCOMPARE(childItemInChildWindow->mapToItem(childItem, {0, 0}),
+ globalItemOffset(childItemInChildWindow, childItem));
+ QCOMPARE(childItemInChildWindow->mapFromItem(childItem, {0, 0}),
+ globalItemOffset(childItem, childItemInChildWindow));
+
+ QCOMPARE(childItem->mapToItem(childItemInChildWindow, {0, 0}),
+ globalItemOffset(childItem, childItemInChildWindow));
+ QCOMPARE(childItem->mapFromItem(childItemInChildWindow, {0, 0}),
+ globalItemOffset(childItemInChildWindow, childItem));
+
+ auto *windowB = root->property("windowB").value<QQuickWindow*>();
+ QVERIFY(windowA);
+ auto *childItemInOtherWindow = windowB->findChild<QQuickItem*>("childItem");
+ QVERIFY(childItemInOtherWindow);
+
+ QCOMPARE(childItemInOtherWindow->mapToItem(childItem, {0, 0}),
+ globalItemOffset(childItemInOtherWindow, childItem));
+ QCOMPARE(childItemInOtherWindow->mapFromItem(childItem, {0, 0}),
+ globalItemOffset(childItem, childItemInOtherWindow));
+
+ QCOMPARE(childItem->mapToItem(childItemInOtherWindow, {0, 0}),
+ globalItemOffset(childItem, childItemInOtherWindow));
+ QCOMPARE(childItem->mapFromItem(childItemInOtherWindow, {0, 0}),
+ globalItemOffset(childItemInOtherWindow, childItem));
+
+ QCOMPARE(childItemInOtherWindow->mapToItem(childItemInChildWindow, {0, 0}),
+ globalItemOffset(childItemInOtherWindow, childItemInChildWindow));
+ QCOMPARE(childItemInOtherWindow->mapFromItem(childItemInChildWindow, {0, 0}),
+ globalItemOffset(childItemInChildWindow, childItemInOtherWindow));
+
+ QCOMPARE(childItemInChildWindow->mapToItem(childItemInOtherWindow, {0, 0}),
+ globalItemOffset(childItemInChildWindow, childItemInOtherWindow));
+ QCOMPARE(childItemInChildWindow->mapFromItem(childItemInOtherWindow, {0, 0}),
+ globalItemOffset(childItemInOtherWindow, childItemInChildWindow));
+}
+
void tst_QQuickItem::transforms_data()
{
QTest::addColumn<QByteArray>("qml");