macOS: Remove QMenu indirection via QPlatformNativeInterface

Task-number: QTBUG-83252
Change-Id: I0c750d2b1912ced343d96ea0ca081c3319be2889
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Tor Arne Vestbø 2020-05-13 19:36:51 +02:00
parent 7ad5c5346f
commit d7fc2fb5c6
8 changed files with 54 additions and 58 deletions

View File

@ -166,6 +166,31 @@ public:
virtual QPlatformMenu *createMenu() const;
};
// ----------------- QPlatformInterface -----------------
QT_END_NAMESPACE
Q_FORWARD_DECLARE_OBJC_CLASS(NSMenu);
QT_BEGIN_NAMESPACE
namespace QPlatformInterface::Private {
#if defined(Q_OS_MACOS)
struct Q_GUI_EXPORT QCocoaMenu
{
QT_DECLARE_PLATFORM_INTERFACE(QCocoaMenu)
virtual NSMenu *nsMenu() const = 0;
virtual void setAsDockMenu() const = 0;
};
struct Q_GUI_EXPORT QCocoaMenuBar
{
QT_DECLARE_PLATFORM_INTERFACE(QCocoaMenuBar)
virtual NSMenu *nsMenu() const = 0;
};
#endif
} // QPlatformInterface::Private
QT_END_NAMESPACE
#endif

View File

@ -42,6 +42,7 @@
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformmenu.h>
#include <AppKit/AppKit.h>
@ -54,6 +55,8 @@ using namespace QPlatformInterface::Private;
QT_DEFINE_PLATFORM_INTERFACE(QCocoaGLContext, QOpenGLContext);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QCocoaGLIntegration);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QCocoaWindow);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QCocoaMenu);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QCocoaMenuBar);
QOpenGLContext *QPlatformInterface::QCocoaGLContext::fromNative(NSOpenGLContext *nativeContext, QOpenGLContext *shareContext)
{

View File

@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
class QCocoaMenuBar;
class QCocoaMenu : public QPlatformMenu, public QCocoaMenuObject
, public QPlatformInterface::Private::QCocoaMenu
{
public:
QCocoaMenu();
@ -76,7 +77,8 @@ public:
void setMinimumWidth(int width) override;
void setFont(const QFont &font) override;
NSMenu *nsMenu() const;
NSMenu *nsMenu() const override;
void setAsDockMenu() const override;
inline bool isVisible() const { return m_visible; }

View File

@ -52,6 +52,7 @@
#include "qcocoamenubar.h"
#include "qcocoawindow.h"
#include "qcocoascreen.h"
#include "qcocoaapplicationdelegate.h"
QT_BEGIN_NAMESPACE
@ -104,6 +105,12 @@ NSMenu *QCocoaMenu::nsMenu() const
return static_cast<NSMenu *>(m_nativeMenu);
}
void QCocoaMenu::setAsDockMenu() const
{
QMacAutoReleasePool pool;
QCocoaApplicationDelegate.sharedDelegate.dockMenu = m_nativeMenu;
}
void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before)
{
QMacAutoReleasePool pool;

View File

@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
class QCocoaWindow;
class QCocoaMenuBar : public QPlatformMenuBar
, public QPlatformInterface::Private::QCocoaMenuBar
{
Q_OBJECT
public:
@ -63,8 +64,7 @@ public:
QWindow *parentWindow() const override;
QPlatformMenu *menuForTag(quintptr tag) const override;
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
NSMenu *nsMenu() const override { return m_nativeMenu; }
static void updateMenuBarImmediately();

View File

@ -84,15 +84,6 @@ private:
static void removeFromMimeList(void *macPasteboardMime);
static void registerDraggedTypes(const QStringList &types);
// Dock menu support
static void setDockMenu(QPlatformMenu *platformMenu);
// Function to return NSMenu * from QPlatformMenu
static void *qMenuToNSMenu(QPlatformMenu *platformMenu);
// Function to return NSMenu * from QPlatformMenuBar
static void *qMenuBarToNSMenu(QPlatformMenuBar *platformMenuBar);
// Set a QWindow as a "guest" (subwindow) of a non-QWindow
static void setEmbeddedInForeignView(QPlatformWindow *window, bool embedded);

View File

@ -102,12 +102,6 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::removeFromMimeList);
if (resource.toLower() == "registerdraggedtypes")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerDraggedTypes);
if (resource.toLower() == "setdockmenu")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setDockMenu);
if (resource.toLower() == "qmenutonsmenu")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qMenuToNSMenu);
if (resource.toLower() == "qmenubartonsmenu")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qMenuBarToNSMenu);
if (resource.toLower() == "registertouchwindow")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow);
if (resource.toLower() == "setembeddedinforeignview")
@ -189,28 +183,6 @@ void QCocoaNativeInterface::registerDraggedTypes(const QStringList &types)
qt_mac_registerDraggedTypes(types);
}
void QCocoaNativeInterface::setDockMenu(QPlatformMenu *platformMenu)
{
QMacAutoReleasePool pool;
QCocoaMenu *cocoaPlatformMenu = static_cast<QCocoaMenu *>(platformMenu);
NSMenu *menu = cocoaPlatformMenu->nsMenu();
[QCocoaApplicationDelegate sharedDelegate].dockMenu = menu;
}
void *QCocoaNativeInterface::qMenuToNSMenu(QPlatformMenu *platformMenu)
{
QCocoaMenu *cocoaPlatformMenu = static_cast<QCocoaMenu *>(platformMenu);
NSMenu *menu = cocoaPlatformMenu->nsMenu();
return reinterpret_cast<void *>(menu);
}
void *QCocoaNativeInterface::qMenuBarToNSMenu(QPlatformMenuBar *platformMenuBar)
{
QCocoaMenuBar *cocoaPlatformMenuBar = static_cast<QCocoaMenuBar *>(platformMenuBar);
NSMenu *menu = cocoaPlatformMenuBar->nsMenu();
return reinterpret_cast<void *>(menu);
}
void QCocoaNativeInterface::setEmbeddedInForeignView(QPlatformWindow *window, bool embedded)
{
Q_UNUSED(embedded); // "embedded" state is now automatically detected

View File

@ -40,6 +40,10 @@
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#include <qtwidgetsglobal.h>
QT_USE_NAMESPACE
#include "qmenu.h"
#if QT_CONFIG(menubar)
#include "qmenubar.h"
@ -52,6 +56,8 @@
#include <QtGui/QWindow>
#include <qpa/qplatformnativeinterface.h>
using namespace QPlatformInterface::Private;
QT_BEGIN_NAMESPACE
#if QT_CONFIG(menu)
@ -84,12 +90,9 @@ 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)(d->createPlatformMenu()));
}
if (auto *cocoaPlatformMenu = dynamic_cast<QCocoaMenu *>(d->createPlatformMenu()))
return cocoaPlatformMenu->nsMenu();
return nil;
}
@ -104,12 +107,8 @@ 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)(d->createPlatformMenu());
}
if (auto *cocoaPlatformMenu = dynamic_cast<QCocoaMenu *>(d->createPlatformMenu()))
cocoaPlatformMenu->setAsDockMenu();
}
@ -161,12 +160,9 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem*
*/
NSMenu *QMenuBar::toNSMenu()
{
// Call into the cocoa platform plugin: qMenuBarToNSMenu(platformMenuBar())
QPlatformNativeInterface::NativeResourceForIntegrationFunction function = resolvePlatformFunction("qmenubartonsmenu");
if (function) {
typedef void* (*QMenuBarToNSMenuFunction)(QPlatformMenuBar *platformMenuBar);
return reinterpret_cast<NSMenu *>(reinterpret_cast<QMenuBarToNSMenuFunction>(function)(platformMenuBar()));
}
if (auto *cocoaMenuBar = dynamic_cast<QCocoaMenuBar *>(platformMenuBar()))
return cocoaMenuBar->nsMenu();
return nil;
}
#endif // QT_CONFIG(menubar)