1/**************************************************************************** 2** 3** Copyright (C) 2016 The Qt Company Ltd. 4** Contact: https://www.qt.io/licensing/ 5** 6** This file is part of the QtWidgets module of the Qt Toolkit. 7** 8** $QT_BEGIN_LICENSE:LGPL$ 9** Commercial License Usage 10** Licensees holding valid commercial Qt licenses may use this file in 11** accordance with the commercial license agreement provided with the 12** Software or, alternatively, in accordance with the terms contained in 13** a written agreement between you and The Qt Company. For licensing terms 14** and conditions see https://www.qt.io/terms-conditions. For further 15** information use the contact form at https://www.qt.io/contact-us. 16** 17** GNU Lesser General Public License Usage 18** Alternatively, this file may be used under the terms of the GNU Lesser 19** General Public License version 3 as published by the Free Software 20** Foundation and appearing in the file LICENSE.LGPL3 included in the 21** packaging of this file. Please review the following information to 22** ensure the GNU Lesser General Public License version 3 requirements 23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24** 25** GNU General Public License Usage 26** Alternatively, this file may be used under the terms of the GNU 27** General Public License version 2.0 or (at your option) the GNU General 28** Public license version 3 or any later version approved by the KDE Free 29** Qt Foundation. The licenses are as published by the Free Software 30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31** included in the packaging of this file. Please review the following 32** information to ensure the GNU General Public License requirements will 33** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34** https://www.gnu.org/licenses/gpl-3.0.html. 35** 36** $QT_END_LICENSE$ 37** 38****************************************************************************/ 39 40#import <AppKit/AppKit.h> 41#include "qmacnativewidget_mac.h" 42 43#include <QtCore/qdebug.h> 44#include <QtGui/qwindow.h> 45#include <QtGui/qguiapplication.h> 46#include <qpa/qplatformnativeinterface.h> 47 48/*! 49 \class QMacNativeWidget 50 \since 4.5 51 \brief The QMacNativeWidget class provides a widget for \macos that provides 52 a way to put Qt widgets into Cocoa hierarchies. 53 54 \ingroup advanced 55 \inmodule QtWidgets 56 57 On \macos, there is a difference between a window and view; 58 normally expressed as widgets in Qt. Qt makes assumptions about its 59 parent-child hierarchy that make it complex to put an arbitrary Qt widget 60 into a hierarchy of "normal" views from Apple frameworks. QMacNativeWidget 61 bridges the gap between views and windows and makes it possible to put a 62 hierarchy of Qt widgets into a non-Qt window or view. 63 64 QMacNativeWidget pretends it is a window (i.e. isWindow() will return true), 65 but it cannot be shown on its own. It needs to be put into a window 66 when it is created or later through a native call. 67 68 Here is an example showing how to put a QPushButton into a NSWindow: 69 70 \snippet qmacnativewidget/main.mm 0 71 72 Note that QMacNativeWidget requires knowledge of Cocoa. All it 73 does is get the Qt hierarchy into a window not owned by Qt. It is then up 74 to the programmer to ensure it is placed correctly in the window and 75 responds correctly to events. 76*/ 77 78QT_BEGIN_NAMESPACE 79 80namespace { 81// TODO use QtMacExtras copy of this function when available. 82inline QPlatformNativeInterface::NativeResourceForIntegrationFunction resolvePlatformFunction(const QByteArray &functionName) 83{ 84 QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); 85 QPlatformNativeInterface::NativeResourceForIntegrationFunction function = 86 nativeInterface->nativeResourceFunctionForIntegration(functionName); 87 if (Q_UNLIKELY(!function)) 88 qWarning("Qt could not resolve function %s from " 89 "QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()", 90 functionName.constData()); 91 return function; 92} 93} //namespsace 94 95NSView *getEmbeddableView(QWindow *qtWindow) 96{ 97 // Make sure the platform window is created 98 qtWindow->create(); 99 100 // Inform the window that it's a subwindow of a non-Qt window. This must be 101 // done after create() because we need to have a QPlatformWindow instance. 102 // The corresponding NSWindow will not be shown and can be deleted later. 103 typedef void (*SetEmbeddedInForeignViewFunction)(QPlatformWindow *window, bool embedded); 104 reinterpret_cast<SetEmbeddedInForeignViewFunction>(resolvePlatformFunction("setEmbeddedInForeignView"))(qtWindow->handle(), true); 105 106 // Get the Qt content NSView for the QWindow from the Qt platform plugin 107 QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface(); 108 NSView *qtView = (NSView *)platformNativeInterface->nativeResourceForWindow("nsview", qtWindow); 109 return qtView; // qtView is ready for use. 110} 111 112/*! 113 Create a QMacNativeWidget with \a parentView as its "superview" (i.e., 114 parent). The \a parentView is a NSView pointer. 115*/ 116QMacNativeWidget::QMacNativeWidget(NSView *parentView) 117 : QWidget(0) 118{ 119 Q_UNUSED(parentView); 120 121 //d_func()->topData()->embedded = true; 122 setPalette(QPalette(Qt::transparent)); 123 setAttribute(Qt::WA_SetPalette, false); 124 setAttribute(Qt::WA_LayoutUsesWidgetRect); 125 setAttribute(Qt::WA_TranslucentBackground); 126 setAttribute(Qt::WA_NoSystemBackground, false); 127} 128 129/*! 130 Destroy the QMacNativeWidget. 131*/ 132QMacNativeWidget::~QMacNativeWidget() 133{ 134} 135 136/*! 137 \reimp 138*/ 139QSize QMacNativeWidget::sizeHint() const 140{ 141 // QMacNativeWidget really does not have any other choice 142 // than to fill its designated area. 143 if (windowHandle()) 144 return windowHandle()->size(); 145 return QWidget::sizeHint(); 146} 147 148/*! 149 Returns the native view backing the QMacNativeWidget. 150 151*/ 152NSView *QMacNativeWidget::nativeView() const 153{ 154 winId(); 155 return getEmbeddableView(windowHandle()); 156} 157 158/*! 159 \reimp 160*/ 161bool QMacNativeWidget::event(QEvent *ev) 162{ 163 return QWidget::event(ev); 164} 165 166QT_END_NAMESPACE 167