QComboBox: refactor item flashing code in hidePopup
Instead of using a local event loop, control the flashing through timers
and lambdas. Move the actual hiding of the popup then into a helper that
gets called when the flashing is done.
Note: this changes behavior -the popup will not be hidden when
hidePopup returns. And since events continue get processed during the
flashing effect, we might still get reentrancy (so the code added in
accc833e55
has to stay anyway).
Change-Id: I2ce20520dea16bd3be78544e9fdd059a2969a795
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
parent
a9fa999f79
commit
f4b028114a
@ -2813,41 +2813,54 @@ void QComboBox::hidePopup()
|
||||
auto resetHidingPopup = qScopeGuard([d]{
|
||||
d->hidingPopup = false;
|
||||
});
|
||||
if (d->container && d->container->isVisible()) {
|
||||
|
||||
if (!d->container || !d->container->isVisible())
|
||||
return;
|
||||
|
||||
#if QT_CONFIG(effects)
|
||||
QSignalBlocker modelBlocker(d->model);
|
||||
QSignalBlocker viewBlocker(d->container->itemView());
|
||||
QSignalBlocker containerBlocker(d->container);
|
||||
// Flash selected/triggered item (if any).
|
||||
if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)) {
|
||||
QItemSelectionModel *selectionModel = view() ? view()->selectionModel() : nullptr;
|
||||
if (selectionModel && selectionModel->hasSelection()) {
|
||||
QEventLoop eventLoop;
|
||||
const QItemSelection selection = selectionModel->selection();
|
||||
// Flash selected/triggered item (if any).
|
||||
if (style()->styleHint(QStyle::SH_Menu_FlashTriggeredItem)) {
|
||||
QItemSelectionModel *selectionModel = d->container->itemView()
|
||||
? d->container->itemView()->selectionModel() : nullptr;
|
||||
if (selectionModel && selectionModel->hasSelection()) {
|
||||
const QItemSelection selection = selectionModel->selection();
|
||||
|
||||
QTimer::singleShot(0, d->container, [d, selection, selectionModel]{
|
||||
QSignalBlocker modelBlocker(d->model);
|
||||
QSignalBlocker viewBlocker(d->container->itemView());
|
||||
QSignalBlocker containerBlocker(d->container);
|
||||
|
||||
// Deselect item and wait 60 ms.
|
||||
selectionModel->select(selection, QItemSelectionModel::Toggle);
|
||||
QTimer::singleShot(60, &eventLoop, SLOT(quit()));
|
||||
eventLoop.exec();
|
||||
|
||||
// Select item and wait 20 ms.
|
||||
selectionModel->select(selection, QItemSelectionModel::Toggle);
|
||||
QTimer::singleShot(20, &eventLoop, SLOT(quit()));
|
||||
eventLoop.exec();
|
||||
}
|
||||
QTimer::singleShot(60, d->container, [d, selection, selectionModel]{
|
||||
QSignalBlocker modelBlocker(d->model);
|
||||
QSignalBlocker viewBlocker(d->container->itemView());
|
||||
QSignalBlocker containerBlocker(d->container);
|
||||
selectionModel->select(selection, QItemSelectionModel::Toggle);
|
||||
QTimer::singleShot(20, d->container, [d] {
|
||||
d->doHidePopup();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
containerBlocker.unblock();
|
||||
viewBlocker.unblock();
|
||||
modelBlocker.unblock();
|
||||
} else
|
||||
#endif // QT_CONFIG(effects)
|
||||
d->container->hide();
|
||||
{
|
||||
d->doHidePopup();
|
||||
}
|
||||
}
|
||||
|
||||
void QComboBoxPrivate::doHidePopup()
|
||||
{
|
||||
if (container && container->isVisible())
|
||||
container->hide();
|
||||
|
||||
#ifdef QT_KEYPAD_NAVIGATION
|
||||
if (QApplicationPrivate::keypadNavigationEnabled() && isEditable() && hasFocus())
|
||||
setEditFocus(true);
|
||||
#endif
|
||||
d->_q_resetButton();
|
||||
|
||||
_q_resetButton();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -352,6 +352,7 @@ public:
|
||||
void updateViewContainerPaletteAndOpacity();
|
||||
void updateFocusPolicy();
|
||||
void showPopupFromMouseEvent(QMouseEvent *e);
|
||||
void doHidePopup();
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
void cleanupNativePopup();
|
||||
|
Loading…
Reference in New Issue
Block a user