aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.1.03
-rw-r--r--src/quick/items/qquickitem.cpp21
-rw-r--r--src/quick/items/qquickitem.h1
-rw-r--r--src/quick/items/qquickwindow.cpp91
-rw-r--r--src/quick/items/qquickwindow.h1
-rw-r--r--src/quick/items/qquickwindow_p.h6
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp2
7 files changed, 119 insertions, 6 deletions
diff --git a/dist/changes-5.1.0 b/dist/changes-5.1.0
index cee8d4b382..4333c4a8dd 100644
--- a/dist/changes-5.1.0
+++ b/dist/changes-5.1.0
@@ -32,6 +32,9 @@ Third party components
* Important Behavior Changes *
****************************************************************************
+ - A Window declared nested inside another Item or Window automatically
+ becomes transient for (centered upon) its parent's window, if x and y
+ were not explicitly specified
****************************************************************************
* Library *
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index d110a01290..d31e142035 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -2685,6 +2685,23 @@ void QQuickItemPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
} else {
if (o->inherits("QGraphicsItem"))
qWarning("Cannot add a QtQuick 1.0 item (%s) into a QtQuick 2.0 scene!", o->metaObject()->className());
+ else {
+ QQuickWindow *thisWindow = qmlobject_cast<QQuickWindow *>(o);
+ QQuickItem *item = that;
+ QQuickWindow *itemWindow = that->window();
+ while (!itemWindow && item && item->parentItem()) {
+ item = item->parentItem();
+ itemWindow = item->window();
+ }
+
+ if (thisWindow) {
+ if (itemWindow)
+ thisWindow->setTransientParent(itemWindow);
+ else
+ QObject::connect(item, SIGNAL(windowChanged(QQuickWindow*)),
+ thisWindow, SLOT(setTransientParent_helper(QQuickWindow*)));
+ }
+ }
// XXX todo - do we really want this behavior?
o->setParent(that);
@@ -4413,8 +4430,8 @@ void QQuickItemPrivate::deliverDragEvent(QEvent *e)
*/
void QQuickItem::itemChange(ItemChange change, const ItemChangeData &value)
{
- Q_UNUSED(change);
- Q_UNUSED(value);
+ if (change == ItemSceneChange)
+ emit windowChanged(value.window);
}
#ifndef QT_NO_IM
diff --git a/src/quick/items/qquickitem.h b/src/quick/items/qquickitem.h
index 040f9d6888..5dea86296f 100644
--- a/src/quick/items/qquickitem.h
+++ b/src/quick/items/qquickitem.h
@@ -355,6 +355,7 @@ Q_SIGNALS:
void smoothChanged(bool);
void antialiasingChanged(bool);
void clipChanged(bool);
+ Q_REVISION(1) void windowChanged(QQuickWindow* window);
// XXX todo
void childrenChanged();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 4789314e01..97a257614f 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -414,7 +414,10 @@ void QQuickWindowPrivate::init(QQuickWindow *c)
QQmlListProperty<QObject> QQuickWindowPrivate::data()
{
initContentItem();
- return QQuickItemPrivate::get(contentItem)->data();
+ return QQmlListProperty<QObject>(q_func(), 0, QQuickWindowPrivate::data_append,
+ QQuickWindowPrivate::data_count,
+ QQuickWindowPrivate::data_at,
+ QQuickWindowPrivate::data_clear);
}
void QQuickWindowPrivate::initContentItem()
@@ -846,7 +849,21 @@ void QQuickWindowPrivate::cleanup(QSGNode *n)
import QtQuick.Window 2.1
\endcode
- Restricting this import will allow you to have a QML environment without access to window system features.
+ Omitting this import will allow you to have a QML environment without
+ access to window system features.
+
+ A Window can be declared inside an Item or inside another Window; in that
+ case the inner Window will automatically become "transient for" the outer
+ Window: that is, most platforms will show it centered upon the outer window
+ by default, and there may be other platform-dependent behaviors, depending
+ also on the \l flags. If the nested window is intended to be a dialog in
+ your application, you should also set \l flags to Qt.Dialog, because some
+ window managers will not provide the centering behavior without that flag.
+ You can also declare multiple windows inside a top-level \l QtObject, in which
+ case the windows will have no transient relationship.
+
+ Alternatively you can set or bind \l x and \l y to position the Window
+ explicitly on the screen.
*/
/*!
\class QQuickWindow
@@ -1094,7 +1111,10 @@ QQuickItem *QQuickWindow::contentItem() const
}
/*!
- Returns the item which currently has active focus.
+ \property QQuickWindow::activeFocusItem
+
+ \brief The item which currently has active focus or \c null if there is
+ no item with active focus.
*/
QQuickItem *QQuickWindow::activeFocusItem() const
{
@@ -2037,6 +2057,64 @@ bool QQuickWindowPrivate::dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent
return overThreshold;
}
+/*!
+ \qmlproperty list<Object> QtQuick.Window2::Window::data
+ \default
+
+ The data property allows you to freely mix visual children, resources
+ and other Windows in a Window.
+
+ If you assign another Window to the data list, the nested window will
+ become "transient for" the outer Window.
+
+ If you assign an \l Item to the data list, it becomes a child of the
+ Window's \l contentItem, so that it appears inside the window. The item's
+ parent will be the window's contentItem, which is the root of the Item
+ ownership tree within that Window.
+
+ If you assign any other object type, it is added as a resource.
+
+ It should not generally be necessary to refer to the \c data property,
+ as it is the default property for Window and thus all child items are
+ automatically assigned to this property.
+
+ \sa QWindow::transientParent()
+ */
+
+void QQuickWindowPrivate::data_append(QQmlListProperty<QObject> *property, QObject *o)
+{
+ if (!o)
+ return;
+ QQuickWindow *that = static_cast<QQuickWindow *>(property->object);
+ if (QQuickWindow *window = qmlobject_cast<QQuickWindow *>(o))
+ window->setTransientParent(that);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(that->contentItem())->data();
+ itemProperty.append(&itemProperty, o);
+}
+
+int QQuickWindowPrivate::data_count(QQmlListProperty<QObject> *property)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ if (!win || !win->contentItem() || !QQuickItemPrivate::get(win->contentItem())->data().count)
+ return 0;
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ return itemProperty.count(&itemProperty);
+}
+
+QObject *QQuickWindowPrivate::data_at(QQmlListProperty<QObject> *property, int i)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ return itemProperty.at(&itemProperty, i);
+}
+
+void QQuickWindowPrivate::data_clear(QQmlListProperty<QObject> *property)
+{
+ QQuickWindow *win = static_cast<QQuickWindow*>(property->object);
+ QQmlListProperty<QObject> itemProperty = QQuickItemPrivate::get(win->contentItem())->data();
+ itemProperty.clear(&itemProperty);
+}
+
bool QQuickWindowPrivate::isRenderable() const
{
const QQuickWindow *q = q_func();
@@ -2456,6 +2534,13 @@ void QQuickWindow::cleanupSceneGraph()
d->renderer = 0;
}
+void QQuickWindow::setTransientParent_helper(QQuickWindow *window)
+{
+ setTransientParent(window);
+ disconnect(sender(), SIGNAL(windowChanged(QQuickWindow*)),
+ this, SLOT(setTransientParent_helper(QQuickWindow*)));
+}
+
/*!
Returns the opengl context used for rendering.
diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h
index a2ba9e9fe0..3adc0be83b 100644
--- a/src/quick/items/qquickwindow.h
+++ b/src/quick/items/qquickwindow.h
@@ -162,6 +162,7 @@ protected:
private Q_SLOTS:
void maybeUpdate();
void cleanupSceneGraph();
+ void setTransientParent_helper(QQuickWindow *window);
private:
friend class QQuickItem;
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index ab772ca2bc..ed2ff3b902 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -224,6 +224,12 @@ public:
static bool dragOverThreshold(qreal d, Qt::Axis axis, QMouseEvent *event);
+ // data property
+ static void data_append(QQmlListProperty<QObject> *, QObject *);
+ static int data_count(QQmlListProperty<QObject> *);
+ static QObject *data_at(QQmlListProperty<QObject> *, int);
+ static void data_clear(QQmlListProperty<QObject> *);
+
private:
static void cleanupNodesOnShutdown(QQuickItem *);
};
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index fa33f3f626..a959a60acf 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -585,7 +585,7 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
QWindow *secondWindow = qvariant_cast<QWindow*>(window->rootObject()->property("secondWindow"));
secondWindow->setProperty("visible", true);
- QTest::qWaitForWindowActive(secondWindow);
+ QTest::qWaitForWindowExposed(secondWindow);
QVERIFY(!window->rootObject()->property("pressed").toBool());
QVERIFY(window->rootObject()->property("canceled").toBool());