summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qcombobox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/widgets/qcombobox.cpp')
-rw-r--r--src/widgets/widgets/qcombobox.cpp131
1 files changed, 78 insertions, 53 deletions
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index ab4c7bfff6..7a8fcc2c76 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -93,12 +93,22 @@ QComboBoxPrivate::QComboBoxPrivate()
hoverControl(QStyle::SC_None),
autoCompletionCaseSensitivity(Qt::CaseInsensitive),
indexBeforeChange(-1)
+#ifdef Q_OS_MAC
+ , m_platformMenu(0)
+#endif
#ifndef QT_NO_COMPLETER
, completer(0)
#endif
{
}
+QComboBoxPrivate::~QComboBoxPrivate()
+{
+#ifdef Q_OS_MAC
+ cleanupNativePopup();
+#endif
+}
+
QStyleOptionMenuItem QComboMenuDelegate::getStyleOption(const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
@@ -2398,7 +2408,7 @@ QSize QComboBox::sizeHint() const
return d->recomputeSizeHint(d->sizeHint);
}
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MAC
namespace {
struct IndexSetter {
@@ -2409,6 +2419,19 @@ struct IndexSetter {
};
}
+void QComboBoxPrivate::cleanupNativePopup()
+{
+ if (!m_platformMenu)
+ return;
+
+ int count = int(m_platformMenu->tag());
+ for (int i = 0; i < count; ++i)
+ m_platformMenu->menuItemAt(i)->deleteLater();
+
+ delete m_platformMenu;
+ m_platformMenu = 0;
+}
+
/*!
* \internal
*
@@ -2419,60 +2442,62 @@ bool QComboBoxPrivate::showNativePopup()
{
Q_Q(QComboBox);
- QPlatformTheme *theme = QGuiApplicationPrivate::instance()->platformTheme();
- if (QPlatformMenu *menu = theme->createPlatformMenu()) {
- int itemsCount = q->count();
-
- QList<QPlatformMenuItem *> items;
- items.reserve(itemsCount);
- QPlatformMenuItem *currentItem = 0;
- int currentIndex = q->currentIndex();
-
- for (int i = 0; i < itemsCount; ++i) {
- QPlatformMenuItem *item = theme->createPlatformMenuItem();
- QModelIndex rowIndex = model->index(i, modelColumn, root);
- QVariant textVariant = model->data(rowIndex, Qt::EditRole);
- item->setText(textVariant.toString());
- QVariant iconVariant = model->data(rowIndex, Qt::DecorationRole);
- if (iconVariant.canConvert<QIcon>())
- item->setIcon(iconVariant.value<QIcon>());
- item->setCheckable(true);
- item->setChecked(i == currentIndex);
- if (!currentItem || i == currentIndex)
- currentItem = item;
-
- IndexSetter setter = { i, q };
- QObject::connect(item, &QPlatformMenuItem::activated, setter);
-
- menu->insertMenuItem(item, 0);
- menu->syncMenuItem(item);
- }
+ cleanupNativePopup();
- QWindow *tlw = q->window()->windowHandle();
- menu->setFont(q->font());
- menu->setMinimumWidth(q->rect().width());
- QPoint offset = QPoint(0, 7);
- if (q->testAttribute(Qt::WA_MacSmallSize))
- offset = QPoint(-1, 7);
- else if (q->testAttribute(Qt::WA_MacMiniSize))
- offset = QPoint(-2, 6);
- menu->showPopup(tlw, QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize()), currentItem);
- menu->deleteLater();
- Q_FOREACH (QPlatformMenuItem *item, items)
- item->deleteLater();
-
- // The Cocoa popup will swallow any mouse release event.
- // We need to fake one here to un-press the button.
- QMouseEvent mouseReleased(QEvent::MouseButtonRelease, q->pos(), Qt::LeftButton,
- Qt::MouseButtons(Qt::LeftButton), Qt::KeyboardModifiers());
- qApp->sendEvent(q, &mouseReleased);
+ QPlatformTheme *theme = QGuiApplicationPrivate::instance()->platformTheme();
+ m_platformMenu = theme->createPlatformMenu();
+ if (!m_platformMenu)
+ return false;
+
+ int itemsCount = q->count();
+ m_platformMenu->setTag(quintptr(itemsCount));
+
+ QPlatformMenuItem *currentItem = 0;
+ int currentIndex = q->currentIndex();
+
+ for (int i = 0; i < itemsCount; ++i) {
+ QPlatformMenuItem *item = theme->createPlatformMenuItem();
+ QModelIndex rowIndex = model->index(i, modelColumn, root);
+ QVariant textVariant = model->data(rowIndex, Qt::EditRole);
+ item->setText(textVariant.toString());
+ QVariant iconVariant = model->data(rowIndex, Qt::DecorationRole);
+ if (iconVariant.canConvert<QIcon>())
+ item->setIcon(iconVariant.value<QIcon>());
+ item->setCheckable(true);
+ item->setChecked(i == currentIndex);
+ if (!currentItem || i == currentIndex)
+ currentItem = item;
+
+ IndexSetter setter = { i, q };
+ QObject::connect(item, &QPlatformMenuItem::activated, setter);
+
+ m_platformMenu->insertMenuItem(item, 0);
+ m_platformMenu->syncMenuItem(item);
+ }
+
+ QWindow *tlw = q->window()->windowHandle();
+ m_platformMenu->setFont(q->font());
+ m_platformMenu->setMinimumWidth(q->rect().width());
+ QPoint offset = QPoint(0, 7);
+ if (q->testAttribute(Qt::WA_MacSmallSize))
+ offset = QPoint(-1, 7);
+ else if (q->testAttribute(Qt::WA_MacMiniSize))
+ offset = QPoint(-2, 6);
+
+ m_platformMenu->showPopup(tlw, QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize()), currentItem);
- return true;
- }
+#ifdef Q_OS_OSX
+ // The Cocoa popup will swallow any mouse release event.
+ // We need to fake one here to un-press the button.
+ QMouseEvent mouseReleased(QEvent::MouseButtonRelease, q->pos(), Qt::LeftButton,
+ Qt::MouseButtons(Qt::LeftButton), Qt::KeyboardModifiers());
+ qApp->sendEvent(q, &mouseReleased);
+#endif
- return false;
+ return true;
}
-#endif // Q_OS_OSX
+
+#endif // Q_OS_MAC
/*!
Displays the list of items in the combobox. If the list is empty
@@ -2494,7 +2519,7 @@ void QComboBox::showPopup()
initStyleOption(&opt);
const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this);
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MAC
if (usePopup
&& (!d->container
|| (view()->metaObject()->className() == QByteArray("QComboBoxListView")
@@ -2502,7 +2527,7 @@ void QComboBox::showPopup()
&& style->styleHint(QStyle::SH_ComboBox_UseNativePopup, &opt, this)
&& d->showNativePopup())
return;
-#endif // Q_OS_OSX
+#endif // Q_OS_MAC
#ifdef QT_KEYPAD_NAVIGATION
#ifndef QT_NO_COMPLETER