diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2020-06-15 00:23:41 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2020-07-01 14:52:49 +0200 |
commit | ab6861b01ff9c14fd1648cb725da17d1ebf3faea (patch) | |
tree | 422f4ff7626e16fcfcd0a4aef35e9d6f27436e5f /src/widgets/kernel/qwidgetwindow.cpp | |
parent | 37d9e44cd010c9844b0dbe2b25f307eab15b3ea8 (diff) |
Fix delivery of MouseMove events to newly opened popup windows
Amend d934fd7f54eae24ea3f719890e2c4dbbc445049d, which was too naive in
assuming that any change to the popup stack while a popup had been
pressed into should result in mouse move events to be delivered without
buttons.
Instead, add a new flag that is set explicitly when the qt_popup_down
widget is closed, and remove buttons from the move move events only when
that flag is set.
Add the sorely missing test case as well, even if we have to accept that
not all behavior can be tested reliably. Ie. on macOS, the simulated
mouse event differs from the event we do get from the QPA plugin or the
system; on Xcb, some of the behavior depends on the window manager.
This is something we could try to clean up for Qt 6.
Change-Id: Ibf0a0a6fb7d401915057365788947e5a35aa20c3
Fixes: QTBUG-84926
Task-number: QTBUG-82538
Pick-to: 5.15
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Liang Qi <liang.qi@qt.io>
Diffstat (limited to 'src/widgets/kernel/qwidgetwindow.cpp')
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 2faedccc20..51e785d0aa 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -62,6 +62,7 @@ Q_WIDGETS_EXPORT QWidget *qt_button_down = nullptr; // widget got last button-do // popup control QWidget *qt_popup_down = nullptr; // popup that contains the pressed widget extern int openPopupCount; +bool qt_popup_down_closed = false; // qt_popup_down has been closed bool qt_replay_popup_mouse_event = false; extern bool qt_try_modal(QWidget *widget, QEvent::Type type); @@ -526,6 +527,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) case QEvent::MouseButtonDblClick: qt_button_down = popupChild; qt_popup_down = activePopupWidget; + qt_popup_down_closed = false; break; case QEvent::MouseButtonRelease: releaseAfter = true; @@ -570,7 +572,7 @@ 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 + const auto buttons = event->type() == QEvent::MouseMove && qt_popup_down_closed ? Qt::NoButton : event->buttons(); QMouseEvent e(event->type(), widgetPos, event->scenePosition(), event->globalPosition(), event->button(), buttons, event->modifiers(), event->source()); @@ -643,11 +645,13 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) if (releaseAfter) { qt_button_down = nullptr; + qt_popup_down_closed = false; qt_popup_down = nullptr; } return; } + qt_popup_down_closed = false; // modal event handling if (QApplicationPrivate::instance()->modalState() && !qt_try_modal(m_widget, event->type())) return; |