From 38b09d34210805766afa8bdd6a1ef413447a89ed Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 7 Jul 2016 14:33:30 -0700 Subject: 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 --- src/plugins/platforms/cocoa/qcocoamenu.h | 6 +++++- src/plugins/platforms/cocoa/qcocoamenu.mm | 17 ++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/cocoa/qcocoamenu.h b/src/plugins/platforms/cocoa/qcocoamenu.h index c975de166d..98b0eb9c54 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.h +++ b/src/plugins/platforms/cocoa/qcocoamenu.h @@ -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 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 diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 878c96d33a..155abcc7ea 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -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; -- cgit v1.2.3