diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-08-24 17:51:47 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2023-10-18 17:42:10 +0200 |
commit | 16023fc77c423a267fcc48894ff942e94cf35b86 (patch) | |
tree | 47422c1fad130ab11a0c59677b9111ad5a5f501c /tests/auto/qml/qqmlcomponent | |
parent | 239359291cd486b5e32ba8068a72e17284af2dac (diff) |
Defer automatic Window transient parent until component completion
A Qt Quick Window without an explicitly set transient parent will
automatically get a transient parent based on its object parent,
for example if it's added as a child another Window or Item in
a QML document, or if a parent is passed to Qt.createComponent
or Qt.createQmlObject.
The logic to handle this was spread out through the various places
that Window objects were added to a QML document or created,
making it hard to maintain or extend this logic. The logic is
now centralized in a single updateTransientParent() function
in QQuickWindowQmlImpl, that's triggered on component completion,
and whenever the conditions for the automatic transient parent
change after that. This allows us to extend the logic to not
apply automatic transient parent when we add support for real
(non transient) child windows later. The machinery relies on
new optional behavior in QObject to send ParentChange events
whenever the parent of an object changes.
Another issue with the previous approach was that it was doing
synchronous QWindow::setTransientParent() calls whenever one
of the conditions were met, which in some cases resulted in
overriding the explicit transientParent set declaratively by
the user. This was an issue because setting the transient
parent to null was the documented way to opt out of one of
the implicit behaviors of a Window with a transient parent,
namely that it defers its visibility until the transient
parent has been made visible. As we now defer the transient
parent magic until the component has been completed, we
know whether the user has set the property explicitly,
and can bail out of the magic if so.
As the deferred visibility of a Window was closely tied to
the transient parent logic, this logic has been refactored
as well, attempting to keep the two machineries as decoupled
as possible. As part of this refactoring the logic to warn
the user if conflicting visibility properties is detected
has been factored into a separate function.
The tst_qquickwindow::attachedProperty() needs a tweak, as
it was was relying on the secondary window not being
transient, which was the case prior to this patch because
we failed to catch the case of Window properties in our
auto-transient-parent machinery:
Rectangle {
property Window someWindow: Window {}
// someWindow is now transient to the
// rectangle's window.
}
Now that we correctly handle this case, the check for
qWaitForWindowActive() was not sufficient to ensure
the Window.active property was true, as transient child
windows are active if their transient parent is active,
and we would not end up spinning the event loop at all,
which is required for the binding to update.
To solve this we now explicitly mark the test window
as not having a transient parent.
[ChangeLog][Qt Quick] Declaring Windows via dedicated
properties of another Window or Item will result in
an automatic transient parent relationship to the
parent Window or Item, just like declaring it as
part of the default data property.
Task-number: QTBUG-116188
Change-Id: Ia1138391d57b64838cebea4bc0a97fbfdf022772
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmlcomponent')
-rw-r--r-- | tests/auto/qml/qqmlcomponent/data/createObject.qml | 3 | ||||
-rw-r--r-- | tests/auto/qml/qqmlcomponent/data/createQmlObject.qml | 21 |
2 files changed, 11 insertions, 13 deletions
diff --git a/tests/auto/qml/qqmlcomponent/data/createObject.qml b/tests/auto/qml/qqmlcomponent/data/createObject.qml index afd9e71229..c9ca605f8f 100644 --- a/tests/auto/qml/qqmlcomponent/data/createObject.qml +++ b/tests/auto/qml/qqmlcomponent/data/createObject.qml @@ -1,5 +1,4 @@ -import QtQuick 2.0 -import QtQuick.Window 2.0 +import QtQuick Item { property QtObject qtobjectParent: QtObject { } diff --git a/tests/auto/qml/qqmlcomponent/data/createQmlObject.qml b/tests/auto/qml/qqmlcomponent/data/createQmlObject.qml index 282ab509f0..480835a5b1 100644 --- a/tests/auto/qml/qqmlcomponent/data/createQmlObject.qml +++ b/tests/auto/qml/qqmlcomponent/data/createQmlObject.qml @@ -1,5 +1,4 @@ -import QtQuick 2.0 -import QtQuick.Window 2.0 +import QtQuick Item { property QtObject qtobjectParent: QtObject { } @@ -19,14 +18,14 @@ Item { property QtObject window_window : null Component.onCompleted: { - qtobject_qtobject = Qt.createQmlObject("import QtQuick 2.0; QtObject{}", qtobjectParent); - qtobject_item = Qt.createQmlObject("import QtQuick 2.0; Item{}", qtobjectParent); - qtobject_window = Qt.createQmlObject("import QtQuick.Window 2.0; Window{}", qtobjectParent); - item_qtobject = Qt.createQmlObject("import QtQuick 2.0; QtObject{}", itemParent); - item_item = Qt.createQmlObject("import QtQuick 2.0; Item{}", itemParent); - item_window = Qt.createQmlObject("import QtQuick.Window 2.0; Window{}", itemParent); - window_qtobject = Qt.createQmlObject("import QtQuick 2.0; QtObject{}", windowParent); - window_item = Qt.createQmlObject("import QtQuick 2.0; Item{}", windowParent); - window_window = Qt.createQmlObject("import QtQuick.Window 2.0; Window{}", windowParent); + qtobject_qtobject = Qt.createQmlObject("import QtQuick; QtObject{}", qtobjectParent); + qtobject_item = Qt.createQmlObject("import QtQuick; Item{}", qtobjectParent); + qtobject_window = Qt.createQmlObject("import QtQuick; Window{}", qtobjectParent); + item_qtobject = Qt.createQmlObject("import QtQuick; QtObject{}", itemParent); + item_item = Qt.createQmlObject("import QtQuick; Item{}", itemParent); + item_window = Qt.createQmlObject("import QtQuick; Window{}", itemParent); + window_qtobject = Qt.createQmlObject("import QtQuick; QtObject{}", windowParent); + window_item = Qt.createQmlObject("import QtQuick; Item{}", windowParent); + window_window = Qt.createQmlObject("import QtQuick; Window{}", windowParent); } } |