From 0bee7cae9a9bddb21122e011cd20c1cc79729179 Mon Sep 17 00:00:00 2001 From: Peter van der Tak Date: Fri, 8 Jan 2016 17:10:12 +0100 Subject: [PATCH 1/2] Fix mouse release event not always being fired when closing a popup window. The mouse release event would not be fired if both the press and release events were processed in the same iteration of QWindowSystemInterface::sendWindowSystemEvents and the press event closed a popup window. In this case, it would: - Process the press event by closing the popup and posting a replayed press event on the event queue for the clicked widget. - Process the leave event, which would not be delivered to the clicked widget because the corresponding (replayed) press event was not yet processed. - Process the replayed press event, which is propageted to the clicked widget. - No leave event occurs any more, leaving the application to think the mouse is in the "pressed" state. This change makes the replay event be delivered immediately/synchonously, rather than being pushed on the event queue. This fixes QTBUG-50051 but breaks QTBUG-38550 again. Change-Id: I62b6d933a9486eb197d60fcd94ef228f195d9f62 --- src/widgets/kernel/qwidgetwindow.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index fc328e7..959edb1 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -443,10 +443,9 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) // Use postEvent() to ensure the local QEventLoop terminates when called from QMenu::exec() const QPoint localPos = win->mapFromGlobal(event->globalPos()); 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); + QApplication::sendSpontaneousEvent(win, e); } } } -- 2.6.2.windows.1 From 898eae9ab078b9e8d318691abf4ebacc35cd5f39 Mon Sep 17 00:00:00 2001 From: Peter van der Tak Date: Fri, 8 Jan 2016 17:22:32 +0100 Subject: [PATCH 2/2] Fix push buttons not being released when another push button is pressed. Ensure that QPushButtonPrivate::_q_popupPressed does not rely on QMenu::exec to return immediately after the menu closes. Alternative fix to QTBUG-38550 (bf9970d40bf0c99a75b59674fa55bc859291d9ba), which does not break QTBUG-50051. Change-Id: Ieb09c69f42f2f1c0cefad6c9fdedbe67e5072ce1 --- src/widgets/widgets/qpushbutton.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/widgets/widgets/qpushbutton.cpp b/src/widgets/widgets/qpushbutton.cpp index 264123a..1298ef9 100644 --- a/src/widgets/widgets/qpushbutton.cpp +++ b/src/widgets/widgets/qpushbutton.cpp @@ -587,11 +587,17 @@ void QPushButtonPrivate::_q_popupPressed() //Because of a delay in menu effects, we must keep track of the //menu visibility to avoid flicker on button release menuOpen = true; + + // Ensure the menu closure is detected immediately when the menu closes, + // even if QEventLoop::exec processed more events. QTBUG-38550 + QMetaObject::Connection connection = QObject::connect(menu, &QMenu::aboutToHide, [&]() { + if (guard) { + menuOpen = false; + q->setDown(false); + } + }); menu->exec(menuPos); - if (guard) { - menuOpen = false; - q->setDown(false); - } + menu->disconnect(connection); } QPoint QPushButtonPrivate::adjustedMenuPosition() -- 2.6.2.windows.1