diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 4b66d2b610..6d2ad6f719 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -42,6 +42,8 @@ QCocoaMenu::~QCocoaMenu() item->setMenuParent(nullptr); } + if (isOpen()) + dismiss(); [m_nativeMenu release]; } @@ -320,6 +322,8 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, { QMacAutoReleasePool pool; + QPointer guard = this; + QPoint pos = QPoint(targetRect.left(), targetRect.top() + targetRect.height()); QCocoaWindow *cocoaWindow = parentWindow ? static_cast(parentWindow->handle()) : nullptr; NSView *view = cocoaWindow ? cocoaWindow->view() : nil; @@ -404,6 +408,11 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, } } + if (!guard) { + menuParentGuard.dismiss(); + return; + } + // The calls above block, and also swallow any mouse release event, // so we need to clear any mouse button that triggered the menu popup. if (cocoaWindow && !cocoaWindow->isForeignWindow()) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 4d6ce39007..97e6153b08 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2469,12 +2469,13 @@ void QComboBoxPrivate::cleanupNativePopup() if (!m_platformMenu) return; + m_platformMenu->setVisible(false); int count = int(m_platformMenu->tag()); for (int i = 0; i < count; ++i) m_platformMenu->menuItemAt(i)->deleteLater(); delete m_platformMenu; - m_platformMenu = 0; + m_platformMenu = nullptr; } /*! @@ -2531,15 +2532,18 @@ bool QComboBoxPrivate::showNativePopup() else if (q->testAttribute(Qt::WA_MacMiniSize)) offset = QPoint(-2, 6); + [[maybe_unused]] QPointer guard(q); const QRect targetRect = QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize()); m_platformMenu->showPopup(tlw, QHighDpi::toNativePixels(targetRect, tlw), currentItem); #ifdef Q_OS_MACOS - // 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(), q->mapToGlobal(QPoint(0, 0)), - Qt::LeftButton, Qt::MouseButtons(Qt::LeftButton), {}); - QCoreApplication::sendEvent(q, &mouseReleased); + if (guard) { + // 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(), q->mapToGlobal(QPoint(0, 0)), + Qt::LeftButton, Qt::MouseButtons(Qt::LeftButton), {}); + QCoreApplication::sendEvent(q, &mouseReleased); + } #endif return true; @@ -3116,7 +3120,10 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) // viewContainer(), we avoid creating the QComboBoxPrivateContainer. viewContainer()->initialClickPosition = q->mapToGlobal(e->position().toPoint()); } + QPointer guard = q; q->showPopup(); + if (!guard) + return; // The code below ensures that regular mousepress and pick item still works // If it was not called the viewContainer would ignore event since it didn't have // a mousePressEvent first.