path: root/src
diff options
authorVolker Hilsheimer <>2020-03-06 17:17:40 +0100
committerVolker Hilsheimer <>2020-03-30 20:06:20 +0100
commitd934fd7f54eae24ea3f719890e2c4dbbc445049d (patch)
treec8c42ae64ac150bba11c90cfd48df47806723385 /src
parent22fe29303869ccf31af25cd4eeeaad768c3f647b (diff)
Send MouseMove events without buttons if the press closed the popup
With nested popup widgets, pressing a mouse button on the lower popup will close the active popup. MouseMove events that are generated before the button is released again should not have that button included, as it is likely to result in incorrect state handling in the widget. This change removes all buttons from the MouseMove event, which is the second best option. This is mostly consistent with the behavior when closing a popup and no other popup remains. The widget underneath will get MouseMove events without the respective button included. This change doesn't include a fix for the final release event, which should ideally also not be delivered to the remaining popup, as it never got a corresponding press event. Qt has already reset the states in which it stores which widget received the press event at the time the release is generated, such as qt_button_down and qt_popup_down. So we can't separate a release grabbed by a newly opened popup (which we want) from a release to the popup that became active after closing (which we don't want). However, widgets can more easily work around this issue, and the risk of breaking things by changing the code further becomes too high. Change-Id: I603bbdbc7e7355952d96ab77c5e2d2f1e6f94987 Fixes: QTBUG-82538 Reviewed-by: Tor Arne Vestbø <> Reviewed-by: Gatis Paeglis <>
Diffstat (limited to 'src')
1 files changed, 5 insertions, 3 deletions
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index 596343c52f..7b36699d5c 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -505,7 +505,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
QGuiApplicationPrivate::platformTheme()->themeHint(QPlatformTheme::ContextMenuOnMouseRelease).toBool() ?
QEvent::MouseButtonRelease : QEvent::MouseButtonPress;
if (QApplicationPrivate::inPopupMode()) {
- QWidget *activePopupWidget = QApplication::activePopupWidget();
+ QPointer<QWidget> activePopupWidget = QApplication::activePopupWidget();
QPoint mapped = event->pos();
if (activePopupWidget != m_widget)
mapped = activePopupWidget->mapFromGlobal(event->globalPos());
@@ -565,9 +565,11 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if ((event->type() != QEvent::MouseButtonPress)
|| !(event->flags().testFlag(Qt::MouseEventCreatedDoubleClick))) {
+ // if the widget that was pressed is gone, then deliver move events without buttons
+ const auto buttons = event->type() == QEvent::MouseMove && qt_button_down == nullptr
+ ? Qt::NoButton : event->buttons();
QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(),
- event->button(), event->buttons(), event->modifiers(), event->source());
+ event->button(), buttons, event->modifiers(), event->source());
QApplicationPrivate::sendMouseEvent(receiver, &e, receiver, receiver->window(), &qt_button_down, qt_last_mouse_receiver);
qt_last_mouse_receiver = receiver;