Cocoa: Reflect menu hierarchy in QCocoaMenu* objects
QCocoaMenu is child of either a QCocoaMenuBar, a QCocoaMenuItem as a submenu, or nothing as a standalone menu. QCocoaMenuItem is child of its containing QCocoaMenu. The parent is set during insertion and cleared during removal. QMenu needs to be updated to avoid double deletion and leaking its own platform menu. Change-Id: Iadf60d8062d7466fa616f84f3761fe322fc9aa2e Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
parent
7a1cdac052
commit
370e89f064
@ -154,6 +154,7 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
|
||||
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
|
||||
QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before);
|
||||
|
||||
menuItem->setParent(this);
|
||||
cocoaItem->sync();
|
||||
if (beforeItem) {
|
||||
int index = m_menuItems.indexOf(beforeItem);
|
||||
@ -209,6 +210,10 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
|
||||
qWarning() << Q_FUNC_INFO << "Menu does not contain the item to be removed";
|
||||
return;
|
||||
}
|
||||
|
||||
if (menuItem->parent() == this)
|
||||
menuItem->setParent(0);
|
||||
|
||||
m_menuItems.removeOne(cocoaItem);
|
||||
if (!cocoaItem->isMerged()) {
|
||||
if (m_nativeMenu != [cocoaItem->nsItem() menu]) {
|
||||
|
@ -109,6 +109,7 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
|
||||
[m_nativeMenu addItem: menu->nsMenuItem()];
|
||||
}
|
||||
|
||||
platformMenu->setParent(this);
|
||||
[m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()];
|
||||
}
|
||||
|
||||
@ -123,6 +124,8 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
|
||||
}
|
||||
m_menus.removeOne(menu);
|
||||
|
||||
if (platformMenu->parent() == this)
|
||||
platformMenu->setParent(0);
|
||||
NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()];
|
||||
[m_nativeMenu removeItemAtIndex: realIndex];
|
||||
}
|
||||
|
@ -124,10 +124,13 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
|
||||
{
|
||||
if (menu == m_menu)
|
||||
return;
|
||||
if (m_menu && m_menu->parent() == this)
|
||||
m_menu->setParent(0);
|
||||
|
||||
QCocoaAutoReleasePool pool;
|
||||
m_menu = static_cast<QCocoaMenu *>(menu);
|
||||
if (m_menu) {
|
||||
m_menu->setParent(this);
|
||||
} else {
|
||||
// we previously had a menu, but no longer
|
||||
// clear out our item so the nexy sync() call builds a new one
|
||||
|
@ -154,7 +154,7 @@ void QMenuPrivate::init()
|
||||
}
|
||||
|
||||
platformMenu = QGuiApplicationPrivate::platformTheme()->createPlatformMenu();
|
||||
if (platformMenu) {
|
||||
if (!platformMenu.isNull()) {
|
||||
QObject::connect(platformMenu, SIGNAL(aboutToShow()), q, SIGNAL(aboutToShow()));
|
||||
QObject::connect(platformMenu, SIGNAL(aboutToHide()), q, SIGNAL(aboutToHide()));
|
||||
}
|
||||
@ -2411,7 +2411,7 @@ void QMenu::changeEvent(QEvent *e)
|
||||
if (d->tornPopup) // torn-off menu
|
||||
d->tornPopup->setEnabled(isEnabled());
|
||||
d->menuAction->setEnabled(isEnabled());
|
||||
if (d->platformMenu)
|
||||
if (!d->platformMenu.isNull())
|
||||
d->platformMenu->setEnabled(isEnabled());
|
||||
}
|
||||
QWidget::changeEvent(e);
|
||||
@ -2992,7 +2992,7 @@ void QMenu::actionEvent(QActionEvent *e)
|
||||
d->widgetItems.remove(e->action());
|
||||
}
|
||||
|
||||
if (d->platformMenu) {
|
||||
if (!d->platformMenu.isNull()) {
|
||||
if (e->type() == QEvent::ActionAdded) {
|
||||
QPlatformMenuItem *menuItem =
|
||||
QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem();
|
||||
@ -3201,7 +3201,7 @@ void QMenu::setSeparatorsCollapsible(bool collapse)
|
||||
d->updateActionRects();
|
||||
update();
|
||||
}
|
||||
if (d->platformMenu)
|
||||
if (!d->platformMenu.isNull())
|
||||
d->platformMenu->syncSeparatorsCollapsible(collapse);
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,8 @@ public:
|
||||
~QMenuPrivate()
|
||||
{
|
||||
delete scroll;
|
||||
delete platformMenu;
|
||||
if (!platformMenu.isNull() && !platformMenu->parent())
|
||||
delete platformMenu.data();
|
||||
#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
|
||||
delete wce_menu;
|
||||
#endif
|
||||
@ -228,7 +229,7 @@ public:
|
||||
//menu fading/scrolling effects
|
||||
bool doChildEffects;
|
||||
|
||||
QPlatformMenu *platformMenu;
|
||||
QPointer<QPlatformMenu> platformMenu;
|
||||
|
||||
QPointer<QAction> actionAboutToTrigger;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user