diff options
author | Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com> | 2016-02-17 16:33:22 -0800 |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com> | 2016-03-16 18:26:33 +0000 |
commit | 09acf326dbc6b7b67f21a360be8c91605ce47f1e (patch) | |
tree | fe45435e0d5cb97b60a1997a297cffd9367cb2b3 /src/plugins/platforms/cocoa/qcocoamenubar.h | |
parent | abe3217bac18fe8a99cbb2f494a5e4cf6c6d70ce (diff) |
QCocoaMenu: Decouple NSMenuItem from NSMenu
While Cocoa requires an NSMenu to be coupled to an NSMenuItem
(just as Qt requires a QMenu to be coupled to a QAction), making
that a hard coupling comes with some limitations. This is because
Cocoa won't allow the NSMenu object to be simultaneously coupled
to more than one NSMenuItem and, similarly, an NSMenuItem can
only be added to a single parent NSMenu. Therefore, it becomes
difficult to share one QMenu between two different QMenuBars in
different windows, or to use a QMenu as context menu while being
accessible from the menu bar.
Previous solutions to circumvent those limitations were less than
ideal (see 119882714f87ffeb6945fdb2d02997ae125ff50c for the
QMenuBar shared QMenu issue). Other workarounds that relied on
that hard coupling, like 996054f5e65bc676aaea0743c2eacec51918e4aa,
also added gratuitous complexity.
In this patch, we break that hard NSMenuItem-NSMenu coupling, and
we replace it with a temporary, looser coupling. As a consequence,
* QCocoaMenu only contains and manages a NSMenu instance,
removing the previously used NSMenuItem. It gets a temporarily
attached NSMenuItem instead.
* QCocoaMenuItem gains a safe pointer to its QCocoaMenu property
removing the necessity containingMenuItem() in QCocoaMenu.
* QCocoaMenuBar manages its own NSMenuItems.
With this setup, we bind the NSMenu to its parent NSMenuItem at the
last moment. In QCocoaMenuBar, when we call updateMenuBarImmediately().
In QCocoaMenu, we use the delegate's -[QCocoaMenuDelegate menu:
updateItem:atIndex:shouldCancel:] method which is called when Cocoa
is about to display the NSMenu.
Note: There's still one use case we don't support, which is sharing
a toplevel QMenuBar menu. This is because Cocoa's menu bar requires
each of its menu items to have a submenu assigned, and therefore we
can't rely on that last moment assignment.
Task-number: QTBUG-34160
Task-number: QTBUG-31342
Task-number: QTBUG-41587
Change-Id: I92bdb444c680789c78e43fe0b585dc6661770281
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@theqtcompany.com>
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoamenubar.h')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenubar.h | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h index d5f75abf34..e84da7aeb0 100644 --- a/src/plugins/platforms/cocoa/qcocoamenubar.h +++ b/src/plugins/platforms/cocoa/qcocoamenubar.h @@ -71,10 +71,10 @@ private: static QCocoaMenuBar *findGlobalMenubar(); bool shouldDisable(QCocoaWindow *active) const; - void insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu); - void removeNativeMenu(QCocoaMenu *menu); - QList<QCocoaMenu*> m_menus; + NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const; + + QList<QPointer<QCocoaMenu> > m_menus; NSMenu *m_nativeMenu; QCocoaWindow *m_window; }; |