1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQuick module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qquickwindowmodule_p.h"
41#include "qquickwindowattached_p.h"
42#include "qquickrendercontrol.h"
43#include "qquickscreen_p.h"
44#include "qquickview_p.h"
45#include <QtQuick/QQuickWindow>
46#include <QtCore/QCoreApplication>
47#include <QtQml/QQmlEngine>
48
49#include <private/qguiapplication_p.h>
50#include <private/qqmlengine_p.h>
51#include <private/qv4qobjectwrapper_p.h>
52#include <private/qqmlglobal_p.h>
53#include <qpa/qplatformintegration.h>
54
55QT_BEGIN_NAMESPACE
56
57Q_DECLARE_LOGGING_CATEGORY(lcTransient)
58
59class QQuickWindowQmlImplPrivate : public QQuickWindowPrivate
60{
61public:
62 QQuickWindowQmlImplPrivate()
63 : complete(false)
64 , visible(false)
65 , visibility(QQuickWindow::AutomaticVisibility)
66 {
67 }
68
69 bool complete;
70 bool visible;
71 QQuickWindow::Visibility visibility;
72 QV4::PersistentValue rootItemMarker;
73};
74
75QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent)
76 : QQuickWindow(*(new QQuickWindowQmlImplPrivate), parent)
77{
78 connect(sender: this, signal: &QWindow::visibleChanged, receiver: this, slot: &QQuickWindowQmlImpl::visibleChanged);
79 connect(sender: this, signal: &QWindow::visibilityChanged, receiver: this, slot: &QQuickWindowQmlImpl::visibilityChanged);
80 connect(sender: this, signal: &QWindow::screenChanged, receiver: this, slot: &QQuickWindowQmlImpl::screenChanged);
81}
82
83void QQuickWindowQmlImpl::setVisible(bool visible)
84{
85 Q_D(QQuickWindowQmlImpl);
86 d->visible = visible;
87 if (d->complete && (!transientParent() || transientParentVisible()))
88 QQuickWindow::setVisible(visible);
89}
90
91void QQuickWindowQmlImpl::setVisibility(Visibility visibility)
92{
93 Q_D(QQuickWindowQmlImpl);
94 d->visibility = visibility;
95 if (d->complete)
96 QQuickWindow::setVisibility(visibility);
97}
98
99QQuickWindowAttached *QQuickWindowQmlImpl::qmlAttachedProperties(QObject *object)
100{
101 return new QQuickWindowAttached(object);
102}
103
104void QQuickWindowQmlImpl::classBegin()
105{
106 Q_D(QQuickWindowQmlImpl);
107 QQmlEngine* e = qmlEngine(this);
108
109 QQmlEngine::setContextForObject(contentItem(), e->rootContext());
110
111 //Give QQuickView behavior when created from QML with QQmlApplicationEngine
112 if (QCoreApplication::instance()->property(name: "__qml_using_qqmlapplicationengine") == QVariant(true)) {
113 if (e && !e->incubationController())
114 e->setIncubationController(incubationController());
115 }
116 {
117 // The content item has CppOwnership policy (set in QQuickWindow). Ensure the presence of a JS
118 // wrapper so that the garbage collector can see the policy.
119 QV4::ExecutionEngine *v4 = e->handle();
120 QV4::QObjectWrapper::wrap(engine: v4, object: d->contentItem);
121 }
122}
123
124void QQuickWindowQmlImpl::componentComplete()
125{
126 Q_D(QQuickWindowQmlImpl);
127 d->complete = true;
128 QQuickItem *itemParent = qmlobject_cast<QQuickItem *>(object: QObject::parent());
129 const bool transientParentAlreadySet = QQuickWindowPrivate::get(c: this)->transientParentPropertySet;
130 if (!transientParentAlreadySet && itemParent && !itemParent->window()) {
131 qCDebug(lcTransient) << "window" << title() << "has invisible Item parent" << itemParent << "transientParent"
132 << transientParent() << "declared visibility" << d->visibility << "; delaying show";
133 connect(sender: itemParent, signal: &QQuickItem::windowChanged, receiver: this,
134 slot: &QQuickWindowQmlImpl::setWindowVisibility, type: Qt::QueuedConnection);
135 } else if (transientParent() && !transientParent()->isVisible()) {
136 connect(sender: transientParent(), signal: &QQuickWindow::visibleChanged, receiver: this,
137 slot: &QQuickWindowQmlImpl::setWindowVisibility, type: Qt::QueuedConnection);
138 } else {
139 setWindowVisibility();
140 }
141}
142
143void QQuickWindowQmlImpl::setWindowVisibility()
144{
145 Q_D(QQuickWindowQmlImpl);
146 if (transientParent() && !transientParentVisible())
147 return;
148
149 if (QQuickItem *senderItem = qmlobject_cast<QQuickItem *>(object: sender())) {
150 disconnect(sender: senderItem, signal: &QQuickItem::windowChanged, receiver: this, slot: &QQuickWindowQmlImpl::setWindowVisibility);
151 } else if (sender()) {
152 disconnect(sender: transientParent(), signal: &QWindow::visibleChanged, receiver: this, slot: &QQuickWindowQmlImpl::setWindowVisibility);
153 }
154
155 // We have deferred window creation until we have the full picture of what
156 // the user wanted in terms of window state, geometry, visibility, etc.
157
158 if ((d->visibility == Hidden && d->visible) || (d->visibility > AutomaticVisibility && !d->visible)) {
159 QQmlData *data = QQmlData::get(object: this);
160 Q_ASSERT(data && data->context);
161
162 QQmlError error;
163 error.setObject(this);
164
165 const QQmlContextData* urlContext = data->context;
166 while (urlContext && urlContext->url().isEmpty())
167 urlContext = urlContext->parent;
168 error.setUrl(urlContext ? urlContext->url() : QUrl());
169
170 QString objectId = data->context->findObjectId(obj: this);
171 if (!objectId.isEmpty())
172 error.setDescription(QCoreApplication::translate(context: "QQuickWindowQmlImpl",
173 key: "Conflicting properties 'visible' and 'visibility' for Window '%1'").arg(a: objectId));
174 else
175 error.setDescription(QCoreApplication::translate(context: "QQuickWindowQmlImpl",
176 key: "Conflicting properties 'visible' and 'visibility'"));
177
178 QQmlEnginePrivate::get(e: data->context->engine)->warning(error);
179 }
180
181 if (d->visibility == AutomaticVisibility) {
182 setWindowState(QGuiApplicationPrivate::platformIntegration()->defaultWindowState(flags()));
183 setVisible(d->visible);
184 } else {
185 setVisibility(d->visibility);
186 }
187}
188
189QObject *QQuickWindowQmlImpl::screen() const
190{
191 return new QQuickScreenInfo(const_cast<QQuickWindowQmlImpl *>(this), QWindow::screen());
192}
193
194void QQuickWindowQmlImpl::setScreen(QObject *screen)
195{
196 QQuickScreenInfo *screenWrapper = qobject_cast<QQuickScreenInfo *>(object: screen);
197 QWindow::setScreen(screenWrapper ? screenWrapper->wrappedScreen() : nullptr);
198}
199
200bool QQuickWindowQmlImpl::transientParentVisible()
201{
202 Q_ASSERT(transientParent());
203 if (!transientParent()->isVisible()) {
204 // handle case where transient parent is offscreen window
205 QWindow *rw = QQuickRenderControl::renderWindowFor(win: qobject_cast<QQuickWindow*>(object: transientParent()));
206 return rw && rw->isVisible();
207 }
208 return true;
209}
210
211QT_END_NAMESPACE
212
213#include "moc_qquickwindowmodule_p.cpp"
214

source code of qtdeclarative/src/quick/items/qquickwindowmodule.cpp