From 68b42cd595954b3c1579e30907dc78c181f0701c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Mon, 2 Sep 2013 13:49:24 +0200 Subject: Port QMacCocoaViewContainer to Qt 5. Includes example. Change-Id: Ifdda5c535d0ec41694712405d921b2c32cb8dfc8 Reviewed-by: Gabriel de Dietrich --- examples/widgets/mac/mac.pro | 6 +- .../widgets/mac/qmaccocoaviewcontainer/main.mm | 67 ++++++++++++++++++++++ .../qmaccocoaviewcontainer.pro | 7 +++ src/widgets/widgets/qmaccocoaviewcontainer_mac.h | 10 ++-- src/widgets/widgets/qmaccocoaviewcontainer_mac.mm | 59 +++++++++++++------ src/widgets/widgets/widgets.pri | 12 ++-- 6 files changed, 130 insertions(+), 31 deletions(-) create mode 100644 examples/widgets/mac/qmaccocoaviewcontainer/main.mm create mode 100644 examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro diff --git a/examples/widgets/mac/mac.pro b/examples/widgets/mac/mac.pro index c5f8bf826f..1513c66ed8 100644 --- a/examples/widgets/mac/mac.pro +++ b/examples/widgets/mac/mac.pro @@ -1,5 +1,7 @@ TEMPLATE = subdirs + macx { SUBDIRS = \ - qmacnativewidget -} \ No newline at end of file + qmacnativewidget \ + qmacnativewidget +} diff --git a/examples/widgets/mac/qmaccocoaviewcontainer/main.mm b/examples/widgets/mac/qmaccocoaviewcontainer/main.mm new file mode 100644 index 0000000000..e8ebc23714 --- /dev/null +++ b/examples/widgets/mac/qmaccocoaviewcontainer/main.mm @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtMacExtras 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +class WindowWidget : public QWidget +{ +public: + WindowWidget() + { + QMacCocoaViewContainer *cocoaViewContainer = new QMacCocoaViewContainer(0, this); + cocoaViewContainer->move(100, 100); + cocoaViewContainer->resize(300, 300); + NSTextView *text = [[NSTextView alloc] initWithFrame : NSMakeRect(0, 0, 300, 300)]; + cocoaViewContainer->setCocoaView(text); + } +}; + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + WindowWidget widget; + widget.show(); + + return app.exec(); +} diff --git a/examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro b/examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro new file mode 100644 index 0000000000..c8c2195cb8 --- /dev/null +++ b/examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro @@ -0,0 +1,7 @@ +TEMPLATE = app + +OBJECTIVE_SOURCES += main.mm +LIBS += -framework Cocoa + +QT += widgets + diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.h b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h index b89b796819..31172cb6bb 100644 --- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.h +++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h @@ -44,20 +44,20 @@ #include -QT_BEGIN_NAMESPACE +Q_FORWARD_DECLARE_OBJC_CLASS(NSView); +QT_BEGIN_NAMESPACE class QMacCocoaViewContainerPrivate; - class Q_WIDGETS_EXPORT QMacCocoaViewContainer : public QWidget { Q_OBJECT public: - QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent = 0); + QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent = 0); virtual ~QMacCocoaViewContainer(); - void setCocoaView(void *cocoaViewToWrap); - void *cocoaView() const; + void setCocoaView(NSView *view); + NSView *cocoaView() const; private: Q_DECLARE_PRIVATE(QMacCocoaViewContainer) diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm index 2be11f34d5..a94273c574 100644 --- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm +++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.mm @@ -40,9 +40,12 @@ ****************************************************************************/ #import -#include #include "qmaccocoaviewcontainer_mac.h" -#include + +#include +#include +#include +#include /*! \class QMacCocoaViewContainer @@ -91,6 +94,20 @@ QT_BEGIN_NAMESPACE +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 (!function) + qWarning() << "Qt could not resolve function" << functionName + << "from QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()"; + return function; +} +} //namespsace + class QMacCocoaViewContainerPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QMacCocoaViewContainer) @@ -111,20 +128,22 @@ QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate() } /*! - \fn QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent) + \fn QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent) Create a new QMacCocoaViewContainer using the NSView pointer in \a cocoaViewToWrap with parent, \a parent. QMacCocoaViewContainer will retain \a cocoaViewToWrap. - \a cocoaViewToWrap is a void pointer that allows the header to be included - with C++ source. */ -QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *parent) +QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *view, QWidget *parent) : QWidget(*new QMacCocoaViewContainerPrivate, parent, 0) { - if (cocoaViewToWrap) - setCocoaView(cocoaViewToWrap); + + if (view) + setCocoaView(view); + + // QMacCocoaViewContainer requires a native window handle. + setAttribute(Qt::WA_NativeWindow); } /*! @@ -132,33 +151,37 @@ QMacCocoaViewContainer::QMacCocoaViewContainer(void *cocoaViewToWrap, QWidget *p */ QMacCocoaViewContainer::~QMacCocoaViewContainer() { + } /*! - Returns the NSView that has been set on this container. The returned view - has been autoreleased, so you will need to retain it if you want to make - use of it. + Returns the NSView that has been set on this container. */ -void *QMacCocoaViewContainer::cocoaView() const +NSView *QMacCocoaViewContainer::cocoaView() const { Q_D(const QMacCocoaViewContainer); - return [[d->nsview retain] autorelease]; + return d->nsview; } /*! Sets the NSView to contain to be \a cocoaViewToWrap and retains it. If this container already had a view set, it will release the previously set view. */ -void QMacCocoaViewContainer::setCocoaView(void *cocoaViewToWrap) +void QMacCocoaViewContainer::setCocoaView(NSView *view) { Q_D(QMacCocoaViewContainer); - QMacCocoaAutoReleasePool pool; - NSView *view = static_cast(cocoaViewToWrap); NSView *oldView = d->nsview; - destroy(true, true); [view retain]; d->nsview = view; - create(WId(d->nsview), false, true); + + // Create window and platformwindow + winId(); + QPlatformWindow *platformWindow = this->windowHandle()->handle(); + + // Set the new view as the content view for the window. + typedef void (*SetWindowContentViewFunction)(QPlatformWindow *window, NSView *nsview); + reinterpret_cast(resolvePlatformFunction("setwindowcontentview"))(platformWindow, view); + [oldView release]; } diff --git a/src/widgets/widgets/widgets.pri b/src/widgets/widgets/widgets.pri index 027654078f..a35e6eb3a1 100644 --- a/src/widgets/widgets/widgets.pri +++ b/src/widgets/widgets/widgets.pri @@ -143,21 +143,21 @@ SOURCES += \ macx { HEADERS += \ - widgets/qmacnativewidget_mac.h + widgets/qmacnativewidget_mac.h \ + widgets/qmaccocoaviewcontainer_mac.h OBJECTIVE_SOURCES += \ widgets/qmenu_mac.mm \ - widgets/qmacnativewidget_mac.mm + widgets/qmacnativewidget_mac.mm \ + widgets/qmaccocoaviewcontainer_mac.mm } # TODO false:mac { - HEADERS += widgets/qmaccocoaviewcontainer_mac.h OBJECTIVE_HEADERS += widgets/qcocoatoolbardelegate_mac_p.h \ widgets/qcocoamenu_mac_p.h - OBJECTIVE_SOURCES += widgets/qmaccocoaviewcontainer_mac.mm \ - widgets/qcocoatoolbardelegate_mac.mm \ - widgets/qmainwindowlayout_mac.mm \ + OBJECTIVE_SOURCES += widgets/qcocoatoolbardelegate_mac.mm \ + widgets/qmainwindowlayout_mac.mm } -- cgit v1.2.3