QCocoaMenu: Keep a reference to the containing menu item
This allows the menu to tell its containing item the menu got deleted. This removes the need to reset the COCOA_MENU_ANCESTOR property value, which would crash since QCocoaMenuItem::m_menu would be a dangling pointer. Task-number: QTBUG-41587 Change-Id: Ia3408ef85cf823bfddbc2c41d6534e43bf14ed29 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
parent
9dcc3a5728
commit
996054f5e6
@ -94,6 +94,10 @@ public:
|
||||
QList<QCocoaMenuItem *> merged() const;
|
||||
void setMenuBar(QCocoaMenuBar *menuBar);
|
||||
QCocoaMenuBar *menuBar() const;
|
||||
|
||||
void setContainingMenuItem(QCocoaMenuItem *menuItem);
|
||||
QCocoaMenuItem *containingMenuItem() const;
|
||||
|
||||
private:
|
||||
QCocoaMenuItem *itemOrNull(int index) const;
|
||||
void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem);
|
||||
@ -106,6 +110,7 @@ private:
|
||||
bool m_visible;
|
||||
quintptr m_tag;
|
||||
QCocoaMenuBar *m_menuBar;
|
||||
QCocoaMenuItem *m_containingMenuItem;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -222,7 +222,8 @@ QCocoaMenu::QCocoaMenu() :
|
||||
m_enabled(true),
|
||||
m_visible(true),
|
||||
m_tag(0),
|
||||
m_menuBar(0)
|
||||
m_menuBar(0),
|
||||
m_containingMenuItem(0)
|
||||
{
|
||||
m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
|
||||
m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
|
||||
@ -238,6 +239,10 @@ QCocoaMenu::~QCocoaMenu()
|
||||
if (COCOA_MENU_ANCESTOR(item) == this)
|
||||
SET_COCOA_MENU_ANCESTOR(item, 0);
|
||||
}
|
||||
|
||||
if (m_containingMenuItem)
|
||||
m_containingMenuItem->clearMenu(this);
|
||||
|
||||
QCocoaAutoReleasePool pool;
|
||||
[m_nativeItem setSubmenu:nil];
|
||||
[m_nativeMenu release];
|
||||
@ -567,4 +572,14 @@ QCocoaMenuBar *QCocoaMenu::menuBar() const
|
||||
return m_menuBar;
|
||||
}
|
||||
|
||||
void QCocoaMenu::setContainingMenuItem(QCocoaMenuItem *menuItem)
|
||||
{
|
||||
m_containingMenuItem = menuItem;
|
||||
}
|
||||
|
||||
QCocoaMenuItem *QCocoaMenu::containingMenuItem() const
|
||||
{
|
||||
return m_containingMenuItem;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -101,6 +101,7 @@ public:
|
||||
inline bool isSeparator() const { return m_isSeparator; }
|
||||
|
||||
QCocoaMenu *menu() const { return m_menu; }
|
||||
void clearMenu(QCocoaMenu *menu);
|
||||
MenuRole effectiveRole() const;
|
||||
|
||||
private:
|
||||
|
@ -131,13 +131,19 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
|
||||
{
|
||||
if (menu == m_menu)
|
||||
return;
|
||||
if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this)
|
||||
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
|
||||
|
||||
if (m_menu) {
|
||||
if (COCOA_MENU_ANCESTOR(m_menu) == this)
|
||||
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
|
||||
if (m_menu->containingMenuItem() == this)
|
||||
m_menu->setContainingMenuItem(0);
|
||||
}
|
||||
|
||||
QCocoaAutoReleasePool pool;
|
||||
m_menu = static_cast<QCocoaMenu *>(menu);
|
||||
if (m_menu) {
|
||||
SET_COCOA_MENU_ANCESTOR(m_menu, this);
|
||||
m_menu->setContainingMenuItem(this);
|
||||
} else {
|
||||
// we previously had a menu, but no longer
|
||||
// clear out our item so the nexy sync() call builds a new one
|
||||
@ -146,6 +152,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
|
||||
}
|
||||
}
|
||||
|
||||
void QCocoaMenuItem::clearMenu(QCocoaMenu *menu)
|
||||
{
|
||||
if (menu == m_menu)
|
||||
m_menu = 0;
|
||||
}
|
||||
|
||||
void QCocoaMenuItem::setVisible(bool isVisible)
|
||||
{
|
||||
m_isVisible = isVisible;
|
||||
|
Loading…
Reference in New Issue
Block a user