1/****************************************************************************
2**
3** Copyright (C) 2017 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
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 http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qquickcontrol_p_p.h"
38#include "qquickoverlay_p.h"
39#include "qquickoverlay_p_p.h"
40#include "qquickpopupitem_p_p.h"
41#include "qquickpopup_p_p.h"
42#include "qquickdrawer_p.h"
43#include "qquickdrawer_p_p.h"
44#include "qquickapplicationwindow_p.h"
45#include <QtQml/qqmlinfo.h>
46#include <QtQml/qqmlproperty.h>
47#include <QtQml/qqmlcomponent.h>
48#include <algorithm>
49
50QT_BEGIN_NAMESPACE
51
52/*!
53 \qmltype Overlay
54 \inherits Item
55//! \instantiates QQuickOverlay
56 \inqmlmodule QtQuick.Controls
57 \since 5.10
58 \brief A window overlay for popups.
59
60 Overlay provides a layer for popups, ensuring that popups are displayed above
61 other content and that the background is dimmed when a \l {Popup::}{modal} or
62 \l {Popup::dim}{dimmed} popup is visible.
63
64 The overlay is an ordinary Item that covers the entire window. It can be used
65 as a visual parent to position a popup in scene coordinates.
66
67 \include qquickoverlay-popup-parent.qdocinc
68
69 \sa ApplicationWindow
70*/
71
72QVector<QQuickPopup *> QQuickOverlayPrivate::stackingOrderPopups() const
73{
74 const QList<QQuickItem *> children = paintOrderChildItems();
75
76 QVector<QQuickPopup *> popups;
77 popups.reserve(asize: children.count());
78
79 for (auto it = children.crbegin(), end = children.crend(); it != end; ++it) {
80 QQuickPopup *popup = qobject_cast<QQuickPopup *>(object: (*it)->parent());
81 if (popup)
82 popups += popup;
83 }
84
85 return popups;
86}
87
88QVector<QQuickDrawer *> QQuickOverlayPrivate::stackingOrderDrawers() const
89{
90 QVector<QQuickDrawer *> sorted(allDrawers);
91 std::sort(first: sorted.begin(), last: sorted.end(), comp: [](const QQuickDrawer *one, const QQuickDrawer *another) {
92 return one->z() > another->z();
93 });
94 return sorted;
95}
96
97void QQuickOverlayPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
98{
99 updateGeometry();
100}
101
102bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos)
103{
104 Q_Q(QQuickOverlay);
105 if (allDrawers.isEmpty())
106 return false;
107
108 // don't start dragging a drawer if a modal popup overlay is blocking (QTBUG-60602)
109 QQuickItem *item = q->childAt(x: pos.x(), y: pos.y());
110 if (item) {
111 const auto popups = stackingOrderPopups();
112 for (QQuickPopup *popup : popups) {
113 QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
114 if (p->dimmer == item && popup->isVisible() && popup->isModal())
115 return false;
116 }
117 }
118
119 const QVector<QQuickDrawer *> drawers = stackingOrderDrawers();
120 for (QQuickDrawer *drawer : drawers) {
121 QQuickDrawerPrivate *p = QQuickDrawerPrivate::get(drawer);
122 if (p->startDrag(event)) {
123 setMouseGrabberPopup(drawer);
124 return true;
125 }
126 }
127
128 return false;
129}
130
131bool QQuickOverlayPrivate::handlePress(QQuickItem *source, QEvent *event, QQuickPopup *target)
132{
133 if (target) {
134 if (target->overlayEvent(item: source, event)) {
135 setMouseGrabberPopup(target);
136 return true;
137 }
138 return false;
139 }
140
141 switch (event->type()) {
142 default: {
143 if (mouseGrabberPopup)
144 break;
145#if QT_CONFIG(quicktemplates2_multitouch)
146 Q_FALLTHROUGH();
147 case QEvent::TouchBegin:
148 case QEvent::TouchUpdate:
149 case QEvent::TouchEnd:
150#endif
151 // allow non-modal popups to close themselves,
152 // and non-dimming modal popups to block the event
153 const auto popups = stackingOrderPopups();
154 for (QQuickPopup *popup : popups) {
155 if (popup->overlayEvent(item: source, event)) {
156 setMouseGrabberPopup(popup);
157 return true;
158 }
159 }
160 break;
161 }
162 }
163
164 event->ignore();
165 return false;
166}
167
168bool QQuickOverlayPrivate::handleMove(QQuickItem *source, QEvent *event, QQuickPopup *target)
169{
170 if (target)
171 return target->overlayEvent(item: source, event);
172 return false;
173}
174
175bool QQuickOverlayPrivate::handleRelease(QQuickItem *source, QEvent *event, QQuickPopup *target)
176{
177 if (target) {
178 setMouseGrabberPopup(nullptr);
179 if (target->overlayEvent(item: source, event)) {
180 setMouseGrabberPopup(nullptr);
181 return true;
182 }
183 } else {
184 const auto popups = stackingOrderPopups();
185 for (QQuickPopup *popup : popups) {
186 if (popup->overlayEvent(item: source, event))
187 return true;
188 }
189 }
190 return false;
191}
192
193bool QQuickOverlayPrivate::handleMouseEvent(QQuickItem *source, QMouseEvent *event, QQuickPopup *target)
194{
195 switch (event->type()) {
196 case QEvent::MouseButtonPress:
197 if (!target && startDrag(event, pos: event->windowPos()))
198 return true;
199 return handlePress(source, event, target);
200 case QEvent::MouseMove:
201 return handleMove(source, event, target: target ? target : mouseGrabberPopup.data());
202 case QEvent::MouseButtonRelease:
203 return handleRelease(source, event, target: target ? target : mouseGrabberPopup.data());
204 default:
205 break;
206 }
207 return false;
208}
209
210#if QT_CONFIG(quicktemplates2_multitouch)
211bool QQuickOverlayPrivate::handleTouchEvent(QQuickItem *source, QTouchEvent *event, QQuickPopup *target)
212{
213 bool handled = false;
214 switch (event->type()) {
215 case QEvent::TouchBegin:
216 case QEvent::TouchUpdate:
217 case QEvent::TouchEnd:
218 for (const QTouchEvent::TouchPoint &point : event->touchPoints()) {
219 switch (point.state()) {
220 case Qt::TouchPointPressed:
221 if (!target && startDrag(event, pos: point.scenePos()))
222 handled = true;
223 else
224 handled |= handlePress(source, event, target);
225 break;
226 case Qt::TouchPointMoved:
227 handled |= handleMove(source, event, target: target ? target : mouseGrabberPopup.data());
228 break;
229 case Qt::TouchPointReleased:
230 handled |= handleRelease(source, event, target: target ? target : mouseGrabberPopup.data());
231 break;
232 default:
233 break;
234 }
235 }
236 break;
237
238 default:
239 break;
240 }
241
242 return handled;
243}
244#endif
245
246void QQuickOverlayPrivate::addPopup(QQuickPopup *popup)
247{
248 Q_Q(QQuickOverlay);
249 allPopups += popup;
250 if (QQuickDrawer *drawer = qobject_cast<QQuickDrawer *>(object: popup)) {
251 allDrawers += drawer;
252 q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
253 }
254}
255
256void QQuickOverlayPrivate::removePopup(QQuickPopup *popup)
257{
258 Q_Q(QQuickOverlay);
259 allPopups.removeOne(t: popup);
260 if (allDrawers.removeOne(t: qobject_cast<QQuickDrawer *>(object: popup)))
261 q->setVisible(!allDrawers.isEmpty() || !q->childItems().isEmpty());
262}
263
264void QQuickOverlayPrivate::setMouseGrabberPopup(QQuickPopup *popup)
265{
266 if (popup && !popup->isVisible())
267 popup = nullptr;
268 mouseGrabberPopup = popup;
269}
270
271void QQuickOverlayPrivate::updateGeometry()
272{
273 Q_Q(QQuickOverlay);
274 if (!window)
275 return;
276
277 QPointF pos;
278 QSizeF size = window->size();
279 qreal rotation = 0;
280
281 switch (window->contentOrientation()) {
282 case Qt::PrimaryOrientation:
283 case Qt::PortraitOrientation:
284 size = window->size();
285 break;
286 case Qt::LandscapeOrientation:
287 rotation = 90;
288 pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2);
289 size.transpose();
290 break;
291 case Qt::InvertedPortraitOrientation:
292 rotation = 180;
293 break;
294 case Qt::InvertedLandscapeOrientation:
295 rotation = 270;
296 pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2);
297 size.transpose();
298 break;
299 default:
300 break;
301 }
302
303 q->setSize(size);
304 q->setPosition(pos);
305 q->setRotation(rotation);
306}
307
308QQuickOverlay::QQuickOverlay(QQuickItem *parent)
309 : QQuickItem(*(new QQuickOverlayPrivate), parent)
310{
311 Q_D(QQuickOverlay);
312 setZ(1000001); // DefaultWindowDecoration+1
313 setAcceptedMouseButtons(Qt::AllButtons);
314#if QT_CONFIG(quicktemplates2_multitouch)
315 setAcceptTouchEvents(true);
316#endif
317 setFiltersChildMouseEvents(true);
318 setVisible(false);
319
320 if (parent) {
321 d->updateGeometry();
322 QQuickItemPrivate::get(item: parent)->addItemChangeListener(listener: d, types: QQuickItemPrivate::Geometry);
323 if (QQuickWindow *window = parent->window()) {
324 window->installEventFilter(filterObj: this);
325 QObjectPrivate::connect(sender: window, signal: &QWindow::contentOrientationChanged, receiverPrivate: d, slot: &QQuickOverlayPrivate::updateGeometry);
326 }
327 }
328}
329
330QQuickOverlay::~QQuickOverlay()
331{
332 Q_D(QQuickOverlay);
333 if (QQuickItem *parent = parentItem())
334 QQuickItemPrivate::get(item: parent)->removeItemChangeListener(d, types: QQuickItemPrivate::Geometry);
335}
336
337QQmlComponent *QQuickOverlay::modal() const
338{
339 Q_D(const QQuickOverlay);
340 return d->modal;
341}
342
343void QQuickOverlay::setModal(QQmlComponent *modal)
344{
345 Q_D(QQuickOverlay);
346 if (d->modal == modal)
347 return;
348
349 d->modal = modal;
350 emit modalChanged();
351}
352
353QQmlComponent *QQuickOverlay::modeless() const
354{
355 Q_D(const QQuickOverlay);
356 return d->modeless;
357}
358
359void QQuickOverlay::setModeless(QQmlComponent *modeless)
360{
361 Q_D(QQuickOverlay);
362 if (d->modeless == modeless)
363 return;
364
365 d->modeless = modeless;
366 emit modelessChanged();
367}
368
369QQuickOverlay *QQuickOverlay::overlay(QQuickWindow *window)
370{
371 if (!window)
372 return nullptr;
373
374 QQuickApplicationWindow *applicationWindow = qobject_cast<QQuickApplicationWindow *>(object: window);
375 if (applicationWindow)
376 return applicationWindow->overlay();
377
378 const char *name = "_q_QQuickOverlay";
379 QQuickOverlay *overlay = window->property(name).value<QQuickOverlay *>();
380 if (!overlay) {
381 QQuickItem *content = window->contentItem();
382 // Do not re-create the overlay if the window is being destroyed
383 // and thus, its content item no longer has a window associated.
384 if (content && content->window()) {
385 overlay = new QQuickOverlay(window->contentItem());
386 window->setProperty(name, value: QVariant::fromValue(value: overlay));
387 }
388 }
389 return overlay;
390}
391
392QQuickOverlayAttached *QQuickOverlay::qmlAttachedProperties(QObject *object)
393{
394 return new QQuickOverlayAttached(object);
395}
396
397void QQuickOverlay::itemChange(ItemChange change, const ItemChangeData &data)
398{
399 Q_D(QQuickOverlay);
400 QQuickItem::itemChange(change, data);
401
402 if (change == ItemChildAddedChange || change == ItemChildRemovedChange)
403 setVisible(!d->allDrawers.isEmpty() || !childItems().isEmpty());
404}
405
406void QQuickOverlay::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
407{
408 Q_D(QQuickOverlay);
409 QQuickItem::geometryChanged(newGeometry, oldGeometry);
410 for (QQuickPopup *popup : qAsConst(t&: d->allPopups))
411 QQuickPopupPrivate::get(popup)->resizeOverlay();
412}
413
414void QQuickOverlay::mousePressEvent(QMouseEvent *event)
415{
416 Q_D(QQuickOverlay);
417 d->handleMouseEvent(source: this, event);
418}
419
420void QQuickOverlay::mouseMoveEvent(QMouseEvent *event)
421{
422 Q_D(QQuickOverlay);
423 d->handleMouseEvent(source: this, event);
424}
425
426void QQuickOverlay::mouseReleaseEvent(QMouseEvent *event)
427{
428 Q_D(QQuickOverlay);
429 d->handleMouseEvent(source: this, event);
430}
431
432#if QT_CONFIG(quicktemplates2_multitouch)
433void QQuickOverlay::touchEvent(QTouchEvent *event)
434{
435 Q_D(QQuickOverlay);
436 d->handleTouchEvent(source: this, event);
437}
438#endif
439
440#if QT_CONFIG(wheelevent)
441void QQuickOverlay::wheelEvent(QWheelEvent *event)
442{
443 Q_D(QQuickOverlay);
444 if (d->mouseGrabberPopup) {
445 d->mouseGrabberPopup->overlayEvent(item: this, event);
446 return;
447 } else {
448 const auto popups = d->stackingOrderPopups();
449 for (QQuickPopup *popup : popups) {
450 if (popup->overlayEvent(item: this, event))
451 return;
452 }
453 }
454 event->ignore();
455}
456#endif
457
458bool QQuickOverlay::childMouseEventFilter(QQuickItem *item, QEvent *event)
459{
460 Q_D(QQuickOverlay);
461 const auto popups = d->stackingOrderPopups();
462 for (QQuickPopup *popup : popups) {
463 QQuickPopupPrivate *p = QQuickPopupPrivate::get(popup);
464
465 // Stop filtering overlay events when reaching a popup item or an item
466 // that is inside the popup. Let the popup content handle its events.
467 if (item == p->popupItem || p->popupItem->isAncestorOf(child: item))
468 break;
469
470 // Let the popup try closing itself when pressing or releasing over its
471 // background dimming OR over another popup underneath, in case the popup
472 // does not have background dimming.
473 if (item == p->dimmer || !p->popupItem->isAncestorOf(child: item)) {
474 bool handled = false;
475 switch (event->type()) {
476#if QT_CONFIG(quicktemplates2_multitouch)
477 case QEvent::TouchBegin:
478 case QEvent::TouchUpdate:
479 case QEvent::TouchEnd:
480 handled = d->handleTouchEvent(source: item, event: static_cast<QTouchEvent *>(event), target: popup);
481 break;
482#endif
483
484 case QEvent::MouseButtonPress:
485 case QEvent::MouseMove:
486 case QEvent::MouseButtonRelease:
487 handled = d->handleMouseEvent(source: item, event: static_cast<QMouseEvent *>(event), target: popup);
488 break;
489
490 default:
491 break;
492 }
493 if (handled)
494 return true;
495 }
496 }
497 return false;
498}
499
500bool QQuickOverlay::eventFilter(QObject *object, QEvent *event)
501{
502 Q_D(QQuickOverlay);
503 if (!isVisible() || object != d->window)
504 return false;
505
506 switch (event->type()) {
507#if QT_CONFIG(quicktemplates2_multitouch)
508 case QEvent::TouchBegin:
509 case QEvent::TouchUpdate:
510 case QEvent::TouchEnd:
511 if (static_cast<QTouchEvent *>(event)->touchPointStates() & Qt::TouchPointPressed)
512 emit pressed();
513 if (static_cast<QTouchEvent *>(event)->touchPointStates() & Qt::TouchPointReleased)
514 emit released();
515
516 // allow non-modal popups to close on touch release outside
517 if (!d->mouseGrabberPopup) {
518 for (const QTouchEvent::TouchPoint &point : static_cast<QTouchEvent *>(event)->touchPoints()) {
519 if (point.state() == Qt::TouchPointReleased) {
520 if (d->handleRelease(source: d->window->contentItem(), event, target: nullptr))
521 break;
522 }
523 }
524 }
525
526 QQuickWindowPrivate::get(c: d->window)->handleTouchEvent(static_cast<QTouchEvent *>(event));
527
528 // If a touch event hasn't been accepted after being delivered, there
529 // were no items interested in touch events at any of the touch points.
530 // Make sure to accept the touch event in order to receive the consequent
531 // touch events, to be able to close non-modal popups on release outside.
532 event->accept();
533 return true;
534#endif
535
536 case QEvent::MouseButtonPress:
537#if QT_CONFIG(quicktemplates2_multitouch)
538 // do not emit pressed() twice when mouse events have been synthesized from touch events
539 if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized)
540#endif
541 emit pressed();
542
543 QQuickWindowPrivate::get(c: d->window)->handleMouseEvent(static_cast<QMouseEvent *>(event));
544
545 // If a mouse event hasn't been accepted after being delivered, there
546 // was no item interested in mouse events at the mouse point. Make sure
547 // to accept the mouse event in order to receive the consequent mouse
548 // events, to be able to close non-modal popups on release outside.
549 event->accept();
550 return true;
551
552 case QEvent::MouseButtonRelease:
553#if QT_CONFIG(quicktemplates2_multitouch)
554 // do not emit released() twice when mouse events have been synthesized from touch events
555 if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventNotSynthesized)
556#endif
557 emit released();
558
559 // allow non-modal popups to close on mouse release outside
560 if (!d->mouseGrabberPopup)
561 d->handleRelease(source: d->window->contentItem(), event, target: nullptr);
562 break;
563
564 default:
565 break;
566 }
567
568 return false;
569}
570
571class QQuickOverlayAttachedPrivate : public QObjectPrivate
572{
573 Q_DECLARE_PUBLIC(QQuickOverlayAttached)
574
575public:
576 void setWindow(QQuickWindow *newWindow);
577
578 QQuickWindow *window = nullptr;
579 QQmlComponent *modal = nullptr;
580 QQmlComponent *modeless = nullptr;
581};
582
583void QQuickOverlayAttachedPrivate::setWindow(QQuickWindow *newWindow)
584{
585 Q_Q(QQuickOverlayAttached);
586 if (window == newWindow)
587 return;
588
589 if (QQuickOverlay *oldOverlay = QQuickOverlay::overlay(window)) {
590 QObject::disconnect(sender: oldOverlay, signal: &QQuickOverlay::pressed, receiver: q, slot: &QQuickOverlayAttached::pressed);
591 QObject::disconnect(sender: oldOverlay, signal: &QQuickOverlay::released, receiver: q, slot: &QQuickOverlayAttached::released);
592 }
593
594 if (QQuickOverlay *newOverlay = QQuickOverlay::overlay(window: newWindow)) {
595 QObject::connect(sender: newOverlay, signal: &QQuickOverlay::pressed, receiver: q, slot: &QQuickOverlayAttached::pressed);
596 QObject::connect(sender: newOverlay, signal: &QQuickOverlay::released, receiver: q, slot: &QQuickOverlayAttached::released);
597 }
598
599 window = newWindow;
600 emit q->overlayChanged();
601}
602
603/*!
604 \qmlattachedsignal QtQuick.Controls::Overlay::pressed()
605
606 This attached signal is emitted when the overlay is pressed by the user while
607 a popup is visible.
608
609 The signal can be attached to any item, popup, or window. When attached to an
610 item or a popup, the signal is only emitted if the item or popup is in a window.
611*/
612
613/*!
614 \qmlattachedsignal QtQuick.Controls::Overlay::released()
615
616 This attached signal is emitted when the overlay is released by the user while
617 a popup is visible.
618
619 The signal can be attached to any item, popup, or window. When attached to an
620 item or a popup, the signal is only emitted if the item or popup is in a window.
621*/
622
623QQuickOverlayAttached::QQuickOverlayAttached(QObject *parent)
624 : QObject(*(new QQuickOverlayAttachedPrivate), parent)
625{
626 Q_D(QQuickOverlayAttached);
627 if (QQuickItem *item = qobject_cast<QQuickItem *>(object: parent)) {
628 d->setWindow(item->window());
629 QObjectPrivate::connect(sender: item, signal: &QQuickItem::windowChanged, receiverPrivate: d, slot: &QQuickOverlayAttachedPrivate::setWindow);
630 } else if (QQuickPopup *popup = qobject_cast<QQuickPopup *>(object: parent)) {
631 d->setWindow(popup->window());
632 QObjectPrivate::connect(sender: popup, signal: &QQuickPopup::windowChanged, receiverPrivate: d, slot: &QQuickOverlayAttachedPrivate::setWindow);
633 } else {
634 d->setWindow(qobject_cast<QQuickWindow *>(object: parent));
635 }
636}
637
638/*!
639 \qmlattachedproperty Overlay QtQuick.Controls::Overlay::overlay
640 \readonly
641
642 This attached property holds the window overlay item.
643
644 The property can be attached to any item, popup, or window. When attached to an
645 item or a popup, the value is \c null if the item or popup is not in a window.
646*/
647QQuickOverlay *QQuickOverlayAttached::overlay() const
648{
649 Q_D(const QQuickOverlayAttached);
650 return QQuickOverlay::overlay(window: d->window);
651}
652
653/*!
654 \qmlattachedproperty Component QtQuick.Controls::Overlay::modal
655
656 This attached property holds a component to use as a visual item that implements
657 background dimming for modal popups. It is created for and stacked below visible
658 modal popups.
659
660 The property can be attached to any popup.
661
662 For example, to change the color of the background dimming for a modal
663 popup, the following code can be used:
664
665 \snippet qtquickcontrols2-overlay-modal.qml 1
666
667 \sa Popup::modal
668*/
669QQmlComponent *QQuickOverlayAttached::modal() const
670{
671 Q_D(const QQuickOverlayAttached);
672 return d->modal;
673}
674
675void QQuickOverlayAttached::setModal(QQmlComponent *modal)
676{
677 Q_D(QQuickOverlayAttached);
678 if (d->modal == modal)
679 return;
680
681 d->modal = modal;
682 emit modalChanged();
683}
684
685/*!
686 \qmlattachedproperty Component QtQuick.Controls::Overlay::modeless
687
688 This attached property holds a component to use as a visual item that implements
689 background dimming for modeless popups. It is created for and stacked below visible
690 dimming popups.
691
692 The property can be attached to any popup.
693
694 For example, to change the color of the background dimming for a modeless
695 popup, the following code can be used:
696
697 \snippet qtquickcontrols2-overlay-modeless.qml 1
698
699 \sa Popup::dim
700*/
701QQmlComponent *QQuickOverlayAttached::modeless() const
702{
703 Q_D(const QQuickOverlayAttached);
704 return d->modeless;
705}
706
707void QQuickOverlayAttached::setModeless(QQmlComponent *modeless)
708{
709 Q_D(QQuickOverlayAttached);
710 if (d->modeless == modeless)
711 return;
712
713 d->modeless = modeless;
714 emit modelessChanged();
715}
716
717QT_END_NAMESPACE
718

source code of qtquickcontrols2/src/quicktemplates2/qquickoverlay.cpp