QToolButton: always restart the menu popup timer

The logic for activating a delayed popup menu on QToolButton is a bit
cumbersome: when the button is pressed, a timer is started. This timer
however doesn't get reset if the button is released before the timer
expires. Instead, the function triggered by the timer checks if the
button is pressed at that time. If so, the popup menu is shown.

This logic allows the user to press-release a QToolButton many times
and suddenly get a popup menu appear way before the expected timeout
for the popup expired. That's because the first press started the timer,
and then the button happened to be down when the timer expired.

Instead, always *re*start the timer on a button press, and cancel
the timer when the button is released.

Change-Id: I3e0849264fdb6f670d018ebb5012eb15fa699cfb
Task-number: QTBUG-48906
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Giuseppe D'Angelo 2016-04-02 20:45:20 +02:00
parent db22609642
commit 7bd08f4bfd
2 changed files with 9 additions and 1 deletions

View File

@ -62,6 +62,7 @@ public:
void init();
#ifndef QT_NO_MENU
void _q_buttonPressed();
void _q_buttonReleased();
void popupTimerDone();
void _q_updateButtonDown();
void _q_menuTriggered(QAction *);
@ -211,6 +212,7 @@ void QToolButtonPrivate::init()
#ifndef QT_NO_MENU
QObject::connect(q, SIGNAL(pressed()), q, SLOT(_q_buttonPressed()));
QObject::connect(q, SIGNAL(released()), q, SLOT(_q_buttonReleased()));
#endif
setLayoutItemMargins(QStyle::SE_ToolButtonLayoutItem);
@ -698,12 +700,17 @@ void QToolButtonPrivate::_q_buttonPressed()
return; // no menu to show
if (popupMode == QToolButton::MenuButtonPopup)
return;
else if (delay > 0 && !popupTimer.isActive() && popupMode == QToolButton::DelayedPopup)
else if (delay > 0 && popupMode == QToolButton::DelayedPopup)
popupTimer.start(delay, q);
else if (delay == 0 || popupMode == QToolButton::InstantPopup)
q->showMenu();
}
void QToolButtonPrivate::_q_buttonReleased()
{
popupTimer.stop();
}
void QToolButtonPrivate::popupTimerDone()
{
Q_Q(QToolButton);

View File

@ -119,6 +119,7 @@ private:
Q_DECLARE_PRIVATE(QToolButton)
#ifndef QT_NO_MENU
Q_PRIVATE_SLOT(d_func(), void _q_buttonPressed())
Q_PRIVATE_SLOT(d_func(), void _q_buttonReleased())
Q_PRIVATE_SLOT(d_func(), void _q_updateButtonDown())
Q_PRIVATE_SLOT(d_func(), void _q_menuTriggered(QAction*))
#endif