diff options
Diffstat (limited to 'src/widgets/widgets/qmenu_mac.mm')
-rw-r--r-- | src/widgets/widgets/qmenu_mac.mm | 112 |
1 files changed, 37 insertions, 75 deletions
diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index 7bff4f3341..184386a731 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #import <Foundation/Foundation.h> #import <AppKit/AppKit.h> @@ -56,28 +20,12 @@ QT_USE_NAMESPACE #include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformmenu_p.h> -using namespace QPlatformInterface::Private; +using namespace QNativeInterface::Private; QT_BEGIN_NAMESPACE #if QT_CONFIG(menu) -namespace { -// TODO use QtMacExtras copy of this function when available. -inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePlatformFunction(const QByteArray &functionName) -{ - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - QPlatformNativeInterface::NativeResourceForIntegrationFunction function = - nativeInterface->nativeResourceFunctionForIntegration(functionName); - if (Q_UNLIKELY(!function)) - qWarning("Qt could not resolve function %s from " - "QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()", - functionName.constData()); - return function; -} -} //namespsace - - /*! \fn NSMenu *QMenu::toNSMenu() \since 5.2 @@ -113,26 +61,40 @@ void QMenu::setAsDockMenu() void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item) { - auto *container = new QWidget; - container->setAttribute(Qt::WA_TranslucentBackground); - QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater())); - container->resize(widget->sizeHint()); - widget->setParent(container); - widget->setVisible(true); - - NSView *containerView = reinterpret_cast<NSView*>(container->winId()); - QWindow *containerWindow = container->windowHandle(); - Qt::WindowFlags wf = containerWindow->flags(); - containerWindow->setFlags(wf | Qt::SubWindow); - [(NSView *)widget->winId() setAutoresizingMask:NSViewWidthSizable]; - - if (QPlatformNativeInterface::NativeResourceForIntegrationFunction function = resolvePlatformFunction("setEmbeddedInForeignView")) { - typedef void (*SetEmbeddedInForeignViewFunction)(QPlatformWindow *window, bool embedded); - reinterpret_cast<SetEmbeddedInForeignViewFunction>(function)(containerWindow->handle(), true); - } - - item->setNativeContents((WId)containerView); - container->show(); + // Hide the widget before we mess with it + widget->hide(); + + // Move out of QMenu, since this widget will live in the native menu item + widget->setParent(nullptr); + + // Make sure the widget doesn't prevent quitting the application, + // just because it's a parent-less (top level) window. + widget->setAttribute(Qt::WA_QuitOnClose, false); + + // And that it blends nicely with the native menu background + widget->setAttribute(Qt::WA_TranslucentBackground); + + // Trigger creation of the backing QWindow, the platform window, and its + // underlying NSView and NSWindow. At this point the widget is still hidden, + // so the corresponding NSWindow that is created is not shown. + widget->setAttribute(Qt::WA_NativeWindow); + QWindow *widgetWindow = widget->windowHandle(); + widgetWindow->create(); + + // Inform the window that it's actually a sub-window. This + // ensures that we dispose of the NSWindow when the widget is + // finally shown. We need to do this on a QWindow level, as + // QWidget will ignore the flag if there is no parentWidget(). + // And we need to do it after creating the platform window, as + // QWidget will overwrite the window flags during creation. + widgetWindow->setFlag(Qt::SubWindow); + + // Finally, we can associate the underlying NSView with the menu item, + // and show it. This will dispose of the created NSWindow, due to + // the Qt::SubWindow flag above. The widget will not actually be + // visible until it's re-parented into the NSMenu hierarchy. + item->setNativeContents(WId(widgetWindow->winId())); + widget->show(); } #endif // QT_CONFIG(menu) |