aboutsummaryrefslogtreecommitdiffstats
path: root/src/quicktemplates/qquickoverlay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quicktemplates/qquickoverlay.cpp')
-rw-r--r--src/quicktemplates/qquickoverlay.cpp70
1 files changed, 38 insertions, 32 deletions
diff --git a/src/quicktemplates/qquickoverlay.cpp b/src/quicktemplates/qquickoverlay.cpp
index bbbde24602..36fa669d22 100644
--- a/src/quicktemplates/qquickoverlay.cpp
+++ b/src/quicktemplates/qquickoverlay.cpp
@@ -9,6 +9,7 @@
#include "qquickdrawer_p.h"
#include "qquickdrawer_p_p.h"
#include "qquickapplicationwindow_p.h"
+#include <QtGui/qpainterpath.h>
#include <QtQml/qqmlinfo.h>
#include <QtQml/qqmlproperty.h>
#include <QtQml/qqmlcomponent.h>
@@ -66,6 +67,11 @@ void QQuickOverlayPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChang
updateGeometry();
}
+void QQuickOverlayPrivate::itemRotationChanged(QQuickItem *)
+{
+ updateGeometry();
+}
+
bool QQuickOverlayPrivate::startDrag(QEvent *event, const QPointF &pos)
{
Q_Q(QQuickOverlay);
@@ -256,38 +262,15 @@ void QQuickOverlayPrivate::setMouseGrabberPopup(QQuickPopup *popup)
void QQuickOverlayPrivate::updateGeometry()
{
Q_Q(QQuickOverlay);
- if (!window)
+ if (!window || !window->contentItem())
return;
- QPointF pos;
- QSizeF size = window->size();
- qreal rotation = 0;
-
- switch (window->contentOrientation()) {
- case Qt::PrimaryOrientation:
- case Qt::PortraitOrientation:
- size = window->size();
- break;
- case Qt::LandscapeOrientation:
- rotation = 90;
- pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2);
- size.transpose();
- break;
- case Qt::InvertedPortraitOrientation:
- rotation = 180;
- break;
- case Qt::InvertedLandscapeOrientation:
- rotation = 270;
- pos = QPointF((size.width() - size.height()) / 2, -(size.width() - size.height()) / 2);
- size.transpose();
- break;
- default:
- break;
- }
+ const QSizeF size = window->contentItem()->size();
+ const QPointF pos(-(size.width() - window->size().width()) / 2,
+ -(size.height() - window->size().height()) / 2);
q->setSize(size);
q->setPosition(pos);
- q->setRotation(rotation);
}
QQuickOverlay::QQuickOverlay(QQuickItem *parent)
@@ -307,7 +290,8 @@ QQuickOverlay::QQuickOverlay(QQuickItem *parent)
QQuickItemPrivate::get(parent)->addItemChangeListener(d, QQuickItemPrivate::Geometry);
if (QQuickWindow *window = parent->window()) {
window->installEventFilter(this);
- QObjectPrivate::connect(window, &QWindow::contentOrientationChanged, d, &QQuickOverlayPrivate::updateGeometry);
+ if (QQuickItem *contentItem = window->contentItem())
+ QQuickItemPrivate::get(contentItem)->addItemChangeListener(d, QQuickItemPrivate::Rotation);
}
}
}
@@ -315,8 +299,13 @@ QQuickOverlay::QQuickOverlay(QQuickItem *parent)
QQuickOverlay::~QQuickOverlay()
{
Q_D(QQuickOverlay);
- if (QQuickItem *parent = parentItem())
+ if (QQuickItem *parent = parentItem()) {
QQuickItemPrivate::get(parent)->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
+ if (QQuickWindow *window = parent->window()) {
+ if (QQuickItem *contentItem = window->contentItem())
+ QQuickItemPrivate::get(contentItem)->removeItemChangeListener(d, QQuickItemPrivate::Rotation);
+ }
+ }
}
QQmlComponent *QQuickOverlay::modal() const
@@ -392,7 +381,7 @@ void QQuickOverlay::geometryChange(const QRectF &newGeometry, const QRectF &oldG
Q_D(QQuickOverlay);
QQuickItem::geometryChange(newGeometry, oldGeometry);
for (QQuickPopup *popup : std::as_const(d->allPopups))
- QQuickPopupPrivate::get(popup)->resizeOverlay();
+ QQuickPopupPrivate::get(popup)->resizeDimmer();
}
void QQuickOverlay::mousePressEvent(QMouseEvent *event)
@@ -522,6 +511,12 @@ bool QQuickOverlay::eventFilter(QObject *object, QEvent *event)
// Make sure to accept the touch event in order to receive the consequent
// touch events, to be able to close non-modal popups on release outside.
event->accept();
+ // Since we eat the event, QQuickWindow::event never sees it to clean up the
+ // grabber states. So we have to do so explicitly.
+ if (QQuickWindow *window = parentItem() ? parentItem()->window() : nullptr) {
+ QQuickWindowPrivate *d = QQuickWindowPrivate::get(window);
+ d->clearGrabbers(static_cast<QPointerEvent *>(event));
+ }
return true;
#endif
@@ -567,7 +562,18 @@ bool QQuickOverlay::eventFilter(QObject *object, QEvent *event)
if (targetItems.isEmpty())
break;
+ QQuickItem * const dimmerItem = property("_q_dimmerItem").value<QQuickItem *>();
QQuickItem * const topItem = targetItems.first();
+
+ QQuickItem *item = topItem;
+ while ((item = item->parentItem())) {
+ if (qobject_cast<QQuickPopupItem *>(item))
+ break;
+ }
+
+ if (!item && dimmerItem != topItem && isAncestorOf(topItem))
+ break;
+
const auto popups = d->stackingOrderPopups();
// Eat the event if receiver topItem is not a child of a popup before
// the first modal popup.
@@ -575,8 +581,8 @@ bool QQuickOverlay::eventFilter(QObject *object, QEvent *event)
const QQuickItem *popupItem = popup->popupItem();
if (!popupItem)
continue;
- // if we reach a popup that contains the item, deliver the event
- if (popupItem->isAncestorOf(topItem))
+ // if current popup item matches with any popup in stack, deliver the event
+ if (popupItem == item)
break;
// if the popup doesn't contain the item but is modal, eat the event
if (popup->overlayEvent(topItem, we))