Reset d->mouseDown only if it's the menu being hidden

If the mouse cursor is over a menu entry with a submenu, and the
submenu is open, quickly moving the mouse to a near menu entry and
clicking it sometimes results in the click being eaten: this happens
when the mouse is pressed before the submenu disappears and released
after it disappeared: the submenu resets d->mouseDown that is a static,
causing the mouse release event on the action we want to have no effect.
Set d->mouseDown to 0 only when the window is hiding is the actual
window that contains the mouseDown, otherwise is still valid.

Change-Id: I2c981b9432728e9e7518c30a146c9595199f8afe
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
bb10
Marco Martin 2017-02-17 11:34:40 +01:00 committed by Marco Martin
parent 3064067154
commit 7fffc04335
2 changed files with 37 additions and 1 deletions

View File

@ -2584,7 +2584,8 @@ void QMenu::hideEvent(QHideEvent *)
if (QMenuBar *mb = qobject_cast<QMenuBar*>(d->causedPopup.widget))
mb->d_func()->setCurrentAction(0);
#endif
d->mouseDown = 0;
if (d->mouseDown == this)
d->mouseDown = 0;
d->hasHadMouse = false;
if (d->activeMenu)
d->hideMenu(d->activeMenu);

View File

@ -110,6 +110,8 @@ private slots:
#ifdef Q_OS_MAC
void QTBUG_37933_ampersands_data();
void QTBUG_37933_ampersands();
#else
void click_while_dismissing_submenu();
#endif
void QTBUG_56917_wideMenuSize();
void QTBUG_56917_wideMenuScreenNumber();
@ -1134,6 +1136,39 @@ void tst_QMenu::QTBUG20403_nested_popup_on_shortcut_trigger()
QVERIFY(!subsub1.isVisible());
}
#ifndef Q_OS_MACOS
void tst_QMenu::click_while_dismissing_submenu()
{
QMenu menu("Test Menu");
QAction *action = menu.addAction("action");
QMenu sub("&sub");
sub.addAction("subaction");
menu.addMenu(&sub);
centerOnScreen(&menu, QSize(120, 100));
menu.show();
QSignalSpy spy(action, SIGNAL(triggered()));
QSignalSpy menuShownSpy(&sub, SIGNAL(aboutToShow()));
QSignalSpy menuHiddenSpy(&sub, SIGNAL(aboutToHide()));
QVERIFY(QTest::qWaitForWindowExposed(&menu));
//go over the submenu, press, move and release over the top level action
//this opens the submenu, move two times to emulate user interaction (d->motions > 0 in QMenu)
QTest::mouseMove(&menu, menu.rect().center() + QPoint(0,2));
QTest::mouseMove(&menu, menu.rect().center() + QPoint(1,3), 60);
QVERIFY(menuShownSpy.wait());
QVERIFY(sub.isVisible());
QVERIFY(QTest::qWaitForWindowExposed(&sub));
//press over the submenu entry
QTest::mousePress(&menu, Qt::LeftButton, 0, menu.rect().center() + QPoint(0,2), 300);
//move over the main action
QTest::mouseMove(&menu, menu.rect().center() - QPoint(0,2));
QVERIFY(menuHiddenSpy.wait());
//the submenu must have been hidden for the bug to be triggered
QVERIFY(!sub.isVisible());
QTest::mouseRelease(&menu, Qt::LeftButton, 0, menu.rect().center() - QPoint(0,2), 300);
QCOMPARE(spy.count(), 1);
}
#endif
class MyWidget : public QWidget
{
public: