Close popups in the correct order

According to the protocol, child popups have to be closed before
parents, but QMenuBar/QMenu will sometimes close the parent first.

Change-Id: Id027ac483b727a19388df619fe1503d794e12c12
Task-number: QTBUG-62048
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
This commit is contained in:
Paul Olav Tvete 2017-07-21 10:21:22 +02:00
parent 027a713154
commit 844002cb81
2 changed files with 20 additions and 0 deletions

View File

@ -341,9 +341,26 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect)
QWindowSystemInterface::handleExposeEvent(window(), rect); QWindowSystemInterface::handleExposeEvent(window(), rect);
} }
static QVector<QPointer<QWaylandWindow>> activePopups;
void QWaylandWindow::closePopups(QWaylandWindow *parent)
{
while (!activePopups.isEmpty()) {
auto popup = activePopups.takeLast();
if (popup.isNull())
continue;
if (popup.data() == parent)
return;
popup->reset();
}
}
void QWaylandWindow::setVisible(bool visible) void QWaylandWindow::setVisible(bool visible)
{ {
if (visible) { if (visible) {
if (window()->type() == Qt::Popup)
activePopups << this;
initWindow(); initWindow();
mDisplay->flushRequests(); mDisplay->flushRequests();
@ -357,6 +374,8 @@ void QWaylandWindow::setVisible(bool visible)
// case 'this' will be deleted. When that happens, we must abort right away. // case 'this' will be deleted. When that happens, we must abort right away.
QPointer<QWaylandWindow> deleteGuard(this); QPointer<QWaylandWindow> deleteGuard(this);
QWindowSystemInterface::flushWindowSystemEvents(); QWindowSystemInterface::flushWindowSystemEvents();
if (!deleteGuard.isNull() && window()->type() == Qt::Popup)
closePopups(this);
if (!deleteGuard.isNull()) if (!deleteGuard.isNull())
reset(); reset();
} }

View File

@ -253,6 +253,7 @@ private:
bool shouldCreateSubSurface() const; bool shouldCreateSubSurface() const;
void reset(); void reset();
void sendExposeEvent(const QRect &rect); void sendExposeEvent(const QRect &rect);
static void closePopups(QWaylandWindow *parent);
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e); void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);