diff options
-rw-r--r-- | src/widgets/widgets/qmenu.cpp | 9 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu_mac.mm | 6 | ||||
-rw-r--r-- | src/widgets/widgets/qmenu_p.h | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar.cpp | 4 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp | 21 |
5 files changed, 38 insertions, 3 deletions
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index d957dda162..a983dc6fde 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -153,12 +153,19 @@ void QMenuPrivate::init() scroll->scrollFlags = QMenuPrivate::QMenuScroller::ScrollNone; } - setPlatformMenu(QGuiApplicationPrivate::platformTheme()->createPlatformMenu()); sloppyState.initialize(q); delayState.initialize(q); mousePopupDelay = q->style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, q); } +QPlatformMenu *QMenuPrivate::createPlatformMenu() +{ + Q_Q(QMenu); + if (platformMenu.isNull()) + q->setPlatformMenu(QGuiApplicationPrivate::platformTheme()->createPlatformMenu()); + return platformMenu.data(); +} + void QMenuPrivate::setPlatformMenu(QPlatformMenu *menu) { Q_Q(QMenu); diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index fef1eb2cf4..f9f3ad08dc 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -80,11 +80,12 @@ inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePla */ NSMenu *QMenu::toNSMenu() { + Q_D(QMenu); // Call into the cocoa platform plugin: qMenuToNSMenu(platformMenu()) QPlatformNativeInterface::NativeResourceForIntegrationFunction function = resolvePlatformFunction("qmenutonsmenu"); if (function) { typedef void* (*QMenuToNSMenuFunction)(QPlatformMenu *platformMenu); - return reinterpret_cast<NSMenu *>(reinterpret_cast<QMenuToNSMenuFunction>(function)(platformMenu())); + return reinterpret_cast<NSMenu *>(reinterpret_cast<QMenuToNSMenuFunction>(function)(d->createPlatformMenu())); } return nil; } @@ -98,11 +99,12 @@ NSMenu *QMenu::toNSMenu() */ void QMenu::setAsDockMenu() { + Q_D(QMenu); // Call into the cocoa platform plugin: setDockMenu(platformMenu()) QPlatformNativeInterface::NativeResourceForIntegrationFunction function = resolvePlatformFunction("setdockmenu"); if (function) { typedef void (*SetDockMenuFunction)(QPlatformMenu *platformMenu); - reinterpret_cast<SetDockMenuFunction>(function)(platformMenu()); + reinterpret_cast<SetDockMenuFunction>(function)(d->createPlatformMenu()); } } diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index 2b0dc482da..3166e6f6cd 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -286,6 +286,7 @@ public: delete platformMenu.data(); } void init(); + QPlatformMenu *createPlatformMenu(); void setPlatformMenu(QPlatformMenu *menu); void syncPlatformMenu(); #ifdef Q_OS_OSX diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index a77c0f9753..63fe09f77e 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1192,6 +1192,10 @@ QPlatformMenu *QMenuBarPrivate::getPlatformMenu(QAction *action) QPlatformMenu *platformMenu = action->menu()->platformMenu(); if (!platformMenu && platformMenuBar) { platformMenu = platformMenuBar->createMenu(); + // QPlatformMenuBar::createMenu() was introduced in Qt 5.7. Not all third party + // platform themes are using it, so fallback to QPlatformTheme::createPlatformMenu(). + if (!platformMenu) + platformMenu = QGuiApplicationPrivate::platformTheme()->createPlatformMenu(); if (platformMenu) action->menu()->setPlatformMenu(platformMenu); } diff --git a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp index ca58dc1247..475ce2a317 100644 --- a/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp +++ b/tests/auto/widgets/widgets/qmenubar/tst_qmenubar.cpp @@ -131,6 +131,8 @@ private slots: void cornerWidgets(); void taskQTBUG53205_crashReparentNested(); + void platformMenu(); + protected slots: void onSimpleActivated( QAction*); void onComplexActionTriggered(); @@ -1487,6 +1489,25 @@ void tst_QMenuBar::taskQTBUG53205_crashReparentNested() testMenus.actions[0]->trigger(); } +// QTBUG-56526 +void tst_QMenuBar::platformMenu() +{ + QMenuBar menuBar; + QPlatformMenuBar *platformMenuBar = menuBar.platformMenuBar(); + if (!platformMenuBar) + QSKIP("No platform menubar implementation available on this platform."); + + // QMenu must not create a platform menu instance at creation time, because + // on Unity the type of the platform menu instance must be different (QGtk3Menu + // vs. QDbusPlatformMenu) depending on whether the menu is in the global menubar + // or a standalone context menu. + QMenu *menu = new QMenu(&menuBar); + QVERIFY(!menu->platformMenu()); + + menuBar.addMenu(menu); + QVERIFY(menu->platformMenu()); +} + void tst_QMenuBar::slotForTaskQTBUG53205() { QWidget *parent = taskQTBUG53205MenuBar->parentWidget(); |