Branch data Line data Source code
1 : : // Copyright (C) 2021 The Qt Company Ltd.
2 : : // Copyright (C) 2019 Luxoft Sweden AB
3 : : // Copyright (C) 2018 Pelagicore AG
4 : : // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
5 : :
6 : : #include <QGuiApplication>
7 : : #include <QDebug>
8 : : #include <QtQml/QQmlEngine>
9 : : #include <QtQml/private/qqmlmetatype_p.h>
10 : : #include <QtQuick/QQuickItem>
11 : : #include <QtQuick/private/qquickwindowmodule_p.h>
12 : : #include <qpa/qplatformnativeinterface.h>
13 : : #include <qpa/qplatformwindow.h>
14 : :
15 : : #include "logging.h"
16 : : #include "applicationmain.h"
17 : : #include "applicationmanagerwindow.h"
18 : : #include "waylandapplicationmanagerwindowimpl.h"
19 : :
20 : : QT_BEGIN_NAMESPACE_AM
21 : :
22 : :
23 : : class AMQuickWindowQmlImpl : public QQuickWindowQmlImpl
24 : : {
25 : : Q_OBJECT
26 : : public:
27 : 70 : AMQuickWindowQmlImpl(ApplicationManagerWindow *amwindow)
28 : 70 : : QQuickWindowQmlImpl(nullptr)
29 : 140 : , m_amwindow(amwindow)
30 : : { }
31 : : using QQuickWindowQmlImpl::classBegin;
32 : : using QQuickWindowQmlImpl::componentComplete;
33 : :
34 : : ApplicationManagerWindow *m_amwindow;
35 : : };
36 : :
37 : 70 : WaylandApplicationManagerWindowImpl::WaylandApplicationManagerWindowImpl(ApplicationManagerWindow *window,
38 : 70 : ApplicationMain *applicationMain)
39 : : : ApplicationManagerWindowImpl(window)
40 : 140 : , m_applicationMain(applicationMain)
41 [ + - + - : 140 : , m_qwindow(new AMQuickWindowQmlImpl(window))
+ - + - ]
42 : : {
43 [ + - ]: 70 : m_color = qUnpremultiply(m_qwindow->color().rgba64());
44 : :
45 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::windowTitleChanged,
46 : 70 : window, &ApplicationManagerWindow::titleChanged);
47 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::xChanged,
48 : 70 : window, &ApplicationManagerWindow::xChanged);
49 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::yChanged,
50 : 70 : window, &ApplicationManagerWindow::yChanged);
51 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::widthChanged,
52 : 70 : window, &ApplicationManagerWindow::widthChanged);
53 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::heightChanged,
54 : 70 : window, &ApplicationManagerWindow::heightChanged);
55 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::minimumWidthChanged,
56 : 70 : window, &ApplicationManagerWindow::minimumWidthChanged);
57 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::maximumWidthChanged,
58 : 70 : window, &ApplicationManagerWindow::maximumWidthChanged);
59 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::minimumHeightChanged,
60 : 70 : window, &ApplicationManagerWindow::minimumHeightChanged);
61 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::maximumHeightChanged,
62 : 70 : window, &ApplicationManagerWindow::maximumHeightChanged);
63 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::opacityChanged,
64 : 70 : window, &ApplicationManagerWindow::opacityChanged);
65 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::visibleChanged,
66 : 70 : window, &ApplicationManagerWindow::visibleChanged);
67 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::colorChanged,
68 : 70 : window, &ApplicationManagerWindow::colorChanged);
69 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::activeChanged,
70 : 70 : window, &ApplicationManagerWindow::activeChanged);
71 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::activeFocusItemChanged,
72 : 70 : window, &ApplicationManagerWindow::activeFocusItemChanged);
73 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::visibilityChanged,
74 : 70 : window, &ApplicationManagerWindow::visibilityChanged);
75 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::closing,
76 : 70 : window, &ApplicationManagerWindow::closing);
77 : :
78 : : // pass-through signals from the actual QQuickWindow
79 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::frameSwapped,
80 : 70 : window, &ApplicationManagerWindow::frameSwapped);
81 [ + - ]: 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::afterAnimating,
82 : 70 : window, &ApplicationManagerWindow::afterAnimating);
83 : 70 : QObject::connect(m_qwindow, &AMQuickWindowQmlImpl::sceneGraphError,
84 : 70 : window, &ApplicationManagerWindow::sceneGraphError);
85 : :
86 [ + - ]: 70 : QObject::connect(m_qwindow, &QObject::destroyed,
87 : 70 : window, [this, deadWindow = m_qwindow.get()](QObject *) {
88 [ + - ]: 65 : if (m_applicationMain)
89 : 65 : m_applicationMain->clearWindowPropertyCache(deadWindow);
90 : 65 : });
91 : 70 : }
92 : :
93 : 130 : WaylandApplicationManagerWindowImpl::~WaylandApplicationManagerWindowImpl()
94 : : {
95 [ + - + - ]: 65 : if (m_applicationMain && m_qwindow)
96 : 65 : m_applicationMain->clearWindowPropertyCache(m_qwindow.get());
97 [ + - ]: 65 : delete m_qwindow.get();
98 : 130 : }
99 : :
100 : 2 : bool WaylandApplicationManagerWindowImpl::isSingleProcess() const
101 : : {
102 : 2 : return false;
103 : : }
104 : :
105 : 55 : QObject *WaylandApplicationManagerWindowImpl::backingObject() const
106 : : {
107 : 55 : return m_qwindow.get();
108 : : }
109 : :
110 : 70 : void WaylandApplicationManagerWindowImpl::classBegin()
111 : : {
112 : 70 : QQmlEngine::setContextForObject(m_qwindow, QQmlEngine::contextForObject(amWindow()));
113 : :
114 : : // find parent QWindow or parent ApplicationManagerWindow
115 : 70 : QQuickWindow *parentWindow = nullptr;
116 : 70 : QObject *p = amWindow()->parent();
117 [ + + ]: 77 : while (p) {
118 [ + + ]: 19 : if (auto *directWindow = qobject_cast<QQuickWindow *>(p)) {
119 : : parentWindow = directWindow;
120 : : break;
121 [ + + ]: 18 : } else if (auto *indirectWindow = qobject_cast<ApplicationManagerWindow *>(p)) {
122 : 11 : parentWindow = static_cast<WaylandApplicationManagerWindowImpl *>(indirectWindow->implementation())->m_qwindow;
123 : 11 : break;
124 : : } else {
125 : 7 : p = p->parent();
126 : : }
127 : : }
128 : :
129 [ + + ]: 70 : if (parentWindow)
130 : 12 : m_qwindow->setTransientParent(parentWindow);
131 : :
132 : 70 : m_qwindow->classBegin();
133 : :
134 : 70 : QObject::connect(m_applicationMain, &ApplicationMain::windowPropertyChanged,
135 : 70 : amWindow(), [this](QWindow *window, const QString &name, const QVariant &value) {
136 [ + + ]: 123 : if (window == m_qwindow)
137 : 97 : emit amWindow()->windowPropertyChanged(name, value);
138 : 123 : });
139 : :
140 : : // For historical reasons, we deviate from the standard Window behavior.
141 : : // We cannot set this is in the constructor, because the base class thinks it's
142 : : // componentComplete between the constructor and classBegin.
143 : 70 : m_qwindow->setFlags(m_qwindow->flags() | Qt::FramelessWindowHint);
144 : 70 : m_qwindow->setWidth(1024);
145 : 70 : m_qwindow->setHeight(768);
146 : 70 : m_qwindow->setVisible(true);
147 : :
148 : 70 : m_qwindow->create(); // force allocation of platform resources
149 : 70 : }
150 : :
151 : 70 : void WaylandApplicationManagerWindowImpl::componentComplete()
152 : : {
153 : 70 : m_qwindow->componentComplete();
154 : 70 : }
155 : :
156 : 148 : QQuickItem *WaylandApplicationManagerWindowImpl::contentItem()
157 : : {
158 [ + - ]: 148 : return m_qwindow ? m_qwindow->contentItem() : nullptr;
159 : : }
160 : :
161 : 46 : bool WaylandApplicationManagerWindowImpl::setWindowProperty(const QString &name, const QVariant &value)
162 : : {
163 : 46 : return m_applicationMain->setWindowProperty(m_qwindow, name, value);
164 : : }
165 : :
166 : 0 : QVariant WaylandApplicationManagerWindowImpl::windowProperty(const QString &name) const
167 : : {
168 [ # # ]: 0 : return windowProperties().value(name);
169 : : }
170 : :
171 : 7 : QVariantMap WaylandApplicationManagerWindowImpl::windowProperties() const
172 : : {
173 : 7 : return m_applicationMain->windowProperties(m_qwindow);
174 : : }
175 : :
176 : 0 : void WaylandApplicationManagerWindowImpl::close()
177 : : {
178 [ # # ]: 0 : if (m_qwindow)
179 : 0 : m_qwindow->close();
180 : 0 : }
181 : :
182 : 3 : QWindow::Visibility WaylandApplicationManagerWindowImpl::visibility() const
183 : : {
184 [ + - ]: 3 : return m_qwindow ? m_qwindow->visibility() : QWindow::Hidden;
185 : : }
186 : :
187 : 0 : void WaylandApplicationManagerWindowImpl::setVisibility(QWindow::Visibility newVisibility)
188 : : {
189 [ # # ]: 0 : if (m_qwindow)
190 : 0 : m_qwindow->setVisibility(newVisibility);
191 : 0 : }
192 : :
193 : 0 : void WaylandApplicationManagerWindowImpl::hide()
194 : : {
195 [ # # ]: 0 : if (m_qwindow)
196 : 0 : m_qwindow->hide();
197 : 0 : }
198 : :
199 : 0 : void WaylandApplicationManagerWindowImpl::show()
200 : : {
201 [ # # ]: 0 : if (m_qwindow)
202 : 0 : m_qwindow->show();
203 : 0 : }
204 : :
205 : 0 : void WaylandApplicationManagerWindowImpl::showFullScreen()
206 : : {
207 [ # # ]: 0 : if (m_qwindow)
208 : 0 : m_qwindow->showFullScreen();
209 : 0 : }
210 : :
211 : 0 : void WaylandApplicationManagerWindowImpl::showMinimized()
212 : : {
213 [ # # ]: 0 : if (m_qwindow)
214 : 0 : m_qwindow->showMinimized();
215 : 0 : }
216 : :
217 : 0 : void WaylandApplicationManagerWindowImpl::showMaximized()
218 : : {
219 [ # # ]: 0 : if (m_qwindow)
220 : 0 : m_qwindow->showMaximized();
221 : 0 : }
222 : :
223 : 0 : void WaylandApplicationManagerWindowImpl::showNormal()
224 : : {
225 [ # # ]: 0 : if (m_qwindow)
226 : 0 : m_qwindow->showNormal();
227 : 0 : }
228 : :
229 : 1 : QString WaylandApplicationManagerWindowImpl::title() const
230 : : {
231 [ + - ]: 1 : return m_qwindow ? m_qwindow->title() : QString { };
232 : : }
233 : :
234 : 14 : void WaylandApplicationManagerWindowImpl::setTitle(const QString &title)
235 : : {
236 [ + - ]: 14 : if (m_qwindow)
237 : 14 : m_qwindow->setTitle(title);
238 : 14 : }
239 : :
240 : 1 : int WaylandApplicationManagerWindowImpl::x() const
241 : : {
242 [ + - ]: 1 : return m_qwindow ? m_qwindow->x() : 0;
243 : : }
244 : :
245 : 0 : void WaylandApplicationManagerWindowImpl::setX(int x)
246 : : {
247 [ # # ]: 0 : if (m_qwindow)
248 : 0 : m_qwindow->setX(x);
249 : 0 : }
250 : :
251 : 1 : int WaylandApplicationManagerWindowImpl::y() const
252 : : {
253 [ + - ]: 1 : return m_qwindow ? m_qwindow->y() : 0;
254 : : }
255 : :
256 : 0 : void WaylandApplicationManagerWindowImpl::setY(int y)
257 : : {
258 [ # # ]: 0 : if (m_qwindow)
259 : 0 : m_qwindow->setY(y);
260 : 0 : }
261 : :
262 : 2 : int WaylandApplicationManagerWindowImpl::width() const
263 : : {
264 [ + - ]: 2 : return m_qwindow ? m_qwindow->width() : 0;
265 : : }
266 : :
267 : 50 : void WaylandApplicationManagerWindowImpl::setWidth(int w)
268 : : {
269 [ + - ]: 50 : if (m_qwindow)
270 : 50 : m_qwindow->setWidth(w);
271 : 50 : }
272 : :
273 : 4 : int WaylandApplicationManagerWindowImpl::height() const
274 : : {
275 [ + - ]: 4 : return m_qwindow ? m_qwindow->height() : 0;
276 : : }
277 : :
278 : 50 : void WaylandApplicationManagerWindowImpl::setHeight(int h)
279 : : {
280 [ + - ]: 50 : if (m_qwindow)
281 : 50 : m_qwindow->setHeight(h);
282 : 50 : }
283 : :
284 : 1 : int WaylandApplicationManagerWindowImpl::minimumWidth() const
285 : : {
286 [ + - ]: 1 : return m_qwindow ? m_qwindow->minimumWidth() : 0;
287 : : }
288 : :
289 : 0 : void WaylandApplicationManagerWindowImpl::setMinimumWidth(int minw)
290 : : {
291 [ # # ]: 0 : if (m_qwindow)
292 : 0 : m_qwindow->setMinimumWidth(minw);
293 : 0 : }
294 : :
295 : 1 : int WaylandApplicationManagerWindowImpl::minimumHeight() const
296 : : {
297 [ + - ]: 1 : return m_qwindow ? m_qwindow->minimumHeight() : 0;
298 : : }
299 : :
300 : 0 : void WaylandApplicationManagerWindowImpl::setMinimumHeight(int minh)
301 : : {
302 [ # # ]: 0 : if (m_qwindow)
303 : 0 : m_qwindow->setMinimumHeight(minh);
304 : 0 : }
305 : :
306 : 1 : int WaylandApplicationManagerWindowImpl::maximumWidth() const
307 : : {
308 [ + - ]: 1 : return m_qwindow ? m_qwindow->maximumWidth() : 0;
309 : : }
310 : :
311 : 0 : void WaylandApplicationManagerWindowImpl::setMaximumWidth(int maxw)
312 : : {
313 [ # # ]: 0 : if (m_qwindow)
314 : 0 : m_qwindow->setMaximumWidth(maxw);
315 : 0 : }
316 : :
317 : 1 : int WaylandApplicationManagerWindowImpl::maximumHeight() const
318 : : {
319 [ + - ]: 1 : return m_qwindow ? m_qwindow->maximumHeight() : 0;
320 : : }
321 : :
322 : 0 : void WaylandApplicationManagerWindowImpl::setMaximumHeight(int maxh)
323 : : {
324 [ # # ]: 0 : if (m_qwindow)
325 : 0 : m_qwindow->setMaximumHeight(maxh);
326 : 0 : }
327 : :
328 : 1 : bool WaylandApplicationManagerWindowImpl::isVisible() const
329 : : {
330 [ + - - + ]: 1 : return m_qwindow ? m_qwindow->isVisible() : false;
331 : : }
332 : :
333 : 44 : void WaylandApplicationManagerWindowImpl::setVisible(bool visible)
334 : : {
335 [ + - ]: 44 : if (m_qwindow)
336 : 44 : m_qwindow->setVisible(visible);
337 : 44 : }
338 : :
339 : 1 : qreal WaylandApplicationManagerWindowImpl::opacity() const
340 : : {
341 [ + - ]: 1 : return m_qwindow ? m_qwindow->opacity() : qreal(1);
342 : : }
343 : :
344 : 0 : void WaylandApplicationManagerWindowImpl::setOpacity(qreal opactity)
345 : : {
346 [ # # ]: 0 : if (m_qwindow)
347 : 0 : m_qwindow->setOpacity(opactity);
348 : 0 : }
349 : :
350 : 1 : QColor WaylandApplicationManagerWindowImpl::color() const
351 : : {
352 [ + - ]: 1 : return m_qwindow ? m_color : QColor { };
353 : : }
354 : :
355 : 38 : void WaylandApplicationManagerWindowImpl::setColor(const QColor &c)
356 : : {
357 [ + - ]: 38 : if (m_qwindow) {
358 : 38 : m_color = c; // qUnpremultiply(qPremultiply(...)) introduces rounding errors
359 : 38 : m_qwindow->setColor(qPremultiply(c.rgba64()));
360 : : }
361 : 38 : }
362 : :
363 : 51 : bool WaylandApplicationManagerWindowImpl::isActive() const
364 : : {
365 [ + - + + ]: 51 : return m_qwindow ? m_qwindow->isActive(): false;
366 : : }
367 : :
368 : 10 : QQuickItem *WaylandApplicationManagerWindowImpl::activeFocusItem() const
369 : : {
370 [ + - ]: 10 : return m_qwindow ? m_qwindow->activeFocusItem() : nullptr;
371 : : }
372 : :
373 : :
374 : : ///////////////////////////////////////////////////////////////////////////////////////////////////
375 : : // WaylandApplicationManagerWindowAttachedImpl
376 : : ///////////////////////////////////////////////////////////////////////////////////////////////////
377 : :
378 : :
379 : 1 : WaylandApplicationManagerWindowAttachedImpl::WaylandApplicationManagerWindowAttachedImpl(ApplicationManagerWindowAttached *windowAttached, QQuickItem *attacheeItem)
380 : 1 : : ApplicationManagerWindowAttachedImpl(windowAttached, attacheeItem)
381 : 1 : { }
382 : :
383 : 1 : ApplicationManagerWindow *WaylandApplicationManagerWindowAttachedImpl::findApplicationManagerWindow()
384 : : {
385 [ + - ]: 1 : if (!attacheeItem())
386 : : return nullptr;
387 : :
388 : 1 : QObject::connect(attacheeItem(), &QQuickItem::windowChanged,
389 : 1 : amWindowAttached(), [this](QQuickWindow *newWin) {
390 : 1 : auto *quickWindow = qobject_cast<AMQuickWindowQmlImpl *>(newWin);
391 [ - + ]: 1 : onWindowChanged(quickWindow ? quickWindow->m_amwindow : nullptr);
392 : 1 : });
393 : 1 : auto *quickWindow = qobject_cast<AMQuickWindowQmlImpl *>(attacheeItem()->window());
394 [ + - ]: 1 : return quickWindow ? quickWindow->m_amwindow : nullptr;
395 : : }
396 : :
397 : : QT_END_NAMESPACE_AM
398 : :
399 : : #include "waylandapplicationmanagerwindowimpl.moc"
|