A dynamically-created Window can have a parent Item and vice-versa
authorShawn Rutledge <shawn.rutledge@digia.com>
Tue, 1 Oct 2013 07:01:35 +0000 (09:01 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Thu, 3 Oct 2013 15:48:34 +0000 (17:48 +0200)
There can be a QML-declared Item which uses Component.createObject to
instantiate a Window; in that case the Window will be transient for
the window containing the Item.  There can also be a QML-declared
Window which uses Component.createObject to instantiate an Item;
in that case the Item's parent will be set to the Window's contentItem.

Task-number: QTBUG-33644
Change-Id: I0b1fe2e98c862c100e52bd5952788af3a727d25e
Reviewed-by: Alan Alpert (Personal) <416365416c@gmail.com>
src/quick/items/qquickitemsmodule.cpp

index 0b20c28..daf76c3 100644 (file)
 
 static QQmlPrivate::AutoParentResult qquickitem_autoParent(QObject *obj, QObject *parent)
 {
+    // When setting a parent (especially during dynamic object creation) in QML,
+    // also try to set up the analogous item/window relationship.
     QQuickItem *parentItem = qmlobject_cast<QQuickItem *>(parent);
     if (parentItem) {
         QQuickItem *item = qmlobject_cast<QQuickItem *>(obj);
-        if (!item)
-            return QQmlPrivate::IncompatibleObject;
-        item->setParentItem(parentItem);
-        return QQmlPrivate::Parented;
+        if (item) {
+            // An Item has another Item
+            item->setParentItem(parentItem);
+            return QQmlPrivate::Parented;
+        } else if (parentItem->window()) {
+            QQuickWindow *win = qmlobject_cast<QQuickWindow *>(obj);
+            if (win) {
+                // A Window inside an Item should be transient for that item's window
+                win->setTransientParent(parentItem->window());
+                return QQmlPrivate::Parented;
+            }
+        }
+        return QQmlPrivate::IncompatibleObject;
     } else {
         QQuickWindow *parentWindow = qmlobject_cast<QQuickWindow *>(parent);
         if (parentWindow) {
             QQuickWindow *win = qmlobject_cast<QQuickWindow *>(obj);
-            if (!win)
-                return QQmlPrivate::IncompatibleObject;
-            win->setTransientParent(parentWindow);
-            return QQmlPrivate::Parented;
+            if (win) {
+                // A Window inside a Window should be transient for it
+                win->setTransientParent(parentWindow);
+                return QQmlPrivate::Parented;
+            } else {
+                QQuickItem *item = qmlobject_cast<QQuickItem *>(obj);
+                if (item) {
+                    // The parent of an Item inside a Window is actually the implicit content Item
+                    item->setParentItem(parentWindow->contentItem());
+                    return QQmlPrivate::Parented;
+                }
+            }
+            return QQmlPrivate::IncompatibleObject;
         }
     }
     return QQmlPrivate::IncompatibleParent;