QCocoaMenu: Attach late items to their submenu

Because the QMenu::aboutToShow() signal is emitted
way after -[QCocoaMenuDelegate menu:updateItem:
atIndex:shouldCancel:], we miss the opportunity to
attach the submenu to the menu item.

The solution is to track the "open" state of the
NSMenu. Then, if any submenu item gets added while
the NSMenu is open, then we immediately attach the
native item to the menu.

Change-Id: I1f3a84ed3832520344da07e06cb3483ad6bd4ffd
Task-number: QTBUG-54633
Reviewed-by: Jake Petroules <jake.petroules@qt.io>
This commit is contained in:
Gabriel de Dietrich 2016-07-07 14:33:30 -07:00
parent 6bafb9da71
commit 38b09d3421
2 changed files with 21 additions and 2 deletions

View File

@ -87,6 +87,9 @@ public:
void setAttachedItem(NSMenuItem *item);
NSMenuItem *attachedItem() const;
bool isOpen() const;
void setIsOpen(bool isOpen);
private:
QCocoaMenuItem *itemOrNull(int index) const;
void insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem);
@ -94,9 +97,10 @@ private:
QList<QCocoaMenuItem *> m_menuItems;
NSMenu *m_nativeMenu;
NSMenuItem *m_attachedItem;
quintptr m_tag;
bool m_enabled;
bool m_visible;
quintptr m_tag;
bool m_isOpen;
};
QT_END_NAMESPACE

View File

@ -131,12 +131,14 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
- (void) menuWillOpen:(NSMenu*)m
{
Q_UNUSED(m);
m_menu->setIsOpen(true);
emit m_menu->aboutToShow();
}
- (void) menuDidClose:(NSMenu*)m
{
Q_UNUSED(m);
m_menu->setIsOpen(false);
// wrong, but it's the best we can do
emit m_menu->aboutToHide();
}
@ -251,9 +253,10 @@ QT_BEGIN_NAMESPACE
QCocoaMenu::QCocoaMenu() :
m_attachedItem(0),
m_tag(0),
m_enabled(true),
m_visible(true),
m_tag(0)
m_isOpen(false)
{
QMacAutoReleasePool pool;
@ -324,6 +327,8 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
item->nsItem().target = m_nativeMenu.delegate;
if (!item->menu())
[item->nsItem() setAction:@selector(itemFired:)];
else if (isOpen() && item->nsItem()) // Someone's adding new items after aboutToShow() was emitted
item->menu()->setAttachedItem(item->nsItem());
if (item->isMerged())
return;
@ -347,6 +352,16 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
item->setMenuParent(this);
}
bool QCocoaMenu::isOpen() const
{
return m_isOpen;
}
void QCocoaMenu::setIsOpen(bool isOpen)
{
m_isOpen = isOpen;
}
void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
{
QMacAutoReleasePool pool;