From bf9970d40bf0c99a75b59674fa55bc859291d9ba Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@digia.com>
Date: Mon, 5 May 2014 12:22:22 +0200
Subject: [PATCH] Use QCoreApplication::postEvent() for replaying popup mouse
 events.

When replaying the mouse events synchronously, nested calls
of QEventLoop::exec() may happen in conjunction with menus.

Task-number: QTBUG-38550
Change-Id: I2b1dafdac59d1a080775af5f165d1e594ea58804
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@digia.com>
---
 src/corelib/kernel/qcoreevent.h      |  1 +
 src/widgets/kernel/qwidgetwindow.cpp | 10 ++++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index 3ee0eaaa61b..8b58fdf55f2 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -323,6 +323,7 @@ private:
     friend class QGraphicsViewPrivate;
     friend class QGraphicsScene;
     friend class QGraphicsScenePrivate;
+    friend class QWidgetWindow;
 #ifndef QT_NO_GESTURES
     friend class QGestureManager;
 #endif
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 0031d8e965e..fc328e7af0f 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -440,11 +440,13 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
                     if (!win)
                         win = w->nativeParentWidget()->windowHandle();
                     if (win && win->geometry().contains(event->globalPos())) {
+                        // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec()
                         const QPoint localPos = win->mapFromGlobal(event->globalPos());
-                        QMouseEvent e(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
-                        QGuiApplicationPrivate::setMouseEventSource(&e, QGuiApplicationPrivate::mouseEventSource(event));
-                        e.setTimestamp(event->timestamp());
-                        QApplication::sendSpontaneousEvent(win, &e);
+                        QMouseEvent *e = new QMouseEvent(QEvent::MouseButtonPress, localPos, localPos, event->globalPos(), event->button(), event->buttons(), event->modifiers());
+                        e->spont = 1;
+                        QGuiApplicationPrivate::setMouseEventSource(e, QGuiApplicationPrivate::mouseEventSource(event));
+                        e->setTimestamp(event->timestamp());
+                        QCoreApplication::postEvent(win, e);
                     }
                 }
             }
-- 
GitLab