Skip to content

Commit

Permalink
QPushButton: use QMenu::popup instead of exec to show menu
Browse files Browse the repository at this point in the history
QMenu::exec opens a blocking loop, which is problematic for webassembly.
Replace with QMenu::popup, and reset the down-state of the button when
the menu is about to hide. QMenu emits aboutToHide immediately before
existing the event loop in the hideEvent override, so the timing is the
same.

Change-Id: Iccb418d10fcb25f6ad1f73f9cdce6ea6581bd73b
Reviewed-by: Qt CI Bot <[email protected]>
Reviewed-by: Richard Moe Gustavsen <[email protected]>
  • Loading branch information
vohi committed Apr 11, 2023
1 parent cf5d9e9 commit 7199498
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 9 deletions.
11 changes: 4 additions & 7 deletions src/widgets/widgets/qpushbutton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,17 +575,14 @@ void QPushButtonPrivate::_q_popupPressed()

QPoint menuPos = adjustedMenuPosition();

QPointer<QPushButton> guard(q);
QMenuPrivate::get(menu)->causedPopup.widget = guard;
QMenuPrivate::get(menu)->causedPopup.widget = q;

//Because of a delay in menu effects, we must keep track of the
//menu visibility to avoid flicker on button release
menuOpen = true;
menu->exec(menuPos);
if (guard) {
menuOpen = false;
q->setDown(false);
}
QObject::connect(menu, &QMenu::aboutToHide,
q, [q]{ q->setDown(false); }, Qt::SingleShotConnection);
menu->popup(menuPos);
}

QPoint QPushButtonPrivate::adjustedMenuPosition()
Expand Down
8 changes: 6 additions & 2 deletions tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1143,14 +1143,18 @@ void tst_QMenu::pushButtonPopulateOnAboutToShow()
QSKIP("Your window manager won't allow a window against the bottom of the screen");
}

QTimer::singleShot(300, buttonMenu, SLOT(hide()));
QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center());
QVERIFY(QTest::qWaitForWindowExposed(buttonMenu));
QTest::qWait(300);
buttonMenu->hide();
QVERIFY2(!buttonMenu->geometry().intersects(b.geometry()), msgGeometryIntersects(buttonMenu->geometry(), b.geometry()));

// note: we're assuming that, if we previously got the desired geometry, we'll get it here too
b.move(10, screen.bottom()-buttonMenu->height()-5);
QTimer::singleShot(300, buttonMenu, SLOT(hide()));
QTest::mouseClick(&b, Qt::LeftButton, Qt::NoModifier, b.rect().center());
QVERIFY(QTest::qWaitForWindowExposed(buttonMenu));
QTest::qWait(300);
buttonMenu->hide();
QVERIFY2(!buttonMenu->geometry().intersects(b.geometry()), msgGeometryIntersects(buttonMenu->geometry(), b.geometry()));
}

Expand Down

0 comments on commit 7199498

Please sign in to comment.