Remove QMacNativeWidget and QMacCocoaViewContainer
The functionality should be available via QWidget::winId(), and QWidget::createWindowContainer() + QWindow::fromWinId(). Any bugs in this area should be fixed by improving the general wrapping APIs. Fixes: QTBUG-83254 Change-Id: I86584a4a8138d17d65a50da39efd58039f10da91 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
7fe7bd326f
commit
92a32e050f
@ -870,8 +870,6 @@ QT_CLASS_LIB(QKeySequenceEdit, QtWidgets, qkeysequenceedit.h)
|
||||
QT_CLASS_LIB(QLabel, QtWidgets, qlabel.h)
|
||||
QT_CLASS_LIB(QLCDNumber, QtWidgets, qlcdnumber.h)
|
||||
QT_CLASS_LIB(QLineEdit, QtWidgets, qlineedit.h)
|
||||
QT_CLASS_LIB(QMacCocoaViewContainer, QtWidgets, qmaccocoaviewcontainer_mac.h)
|
||||
QT_CLASS_LIB(QMacNativeWidget, QtWidgets, qmacnativewidget_mac.h)
|
||||
QT_CLASS_LIB(QMainWindow, QtWidgets, qmainwindow.h)
|
||||
QT_CLASS_LIB(QMdiArea, QtWidgets, qmdiarea.h)
|
||||
QT_CLASS_LIB(QMdiSubWindow, QtWidgets, qmdisubwindow.h)
|
||||
|
@ -302,8 +302,6 @@ qt_extend_target(Widgets CONDITION MSVC AND (TEST_architecture_arch STREQUAL "i3
|
||||
qt_extend_target(Widgets CONDITION MACOS
|
||||
SOURCES
|
||||
kernel/qmacgesturerecognizer.cpp kernel/qmacgesturerecognizer_p.h
|
||||
widgets/qmaccocoaviewcontainer_mac.h widgets/qmaccocoaviewcontainer_mac.mm
|
||||
widgets/qmacnativewidget_mac.h widgets/qmacnativewidget_mac.mm
|
||||
LIBRARIES
|
||||
${FWAppKit}
|
||||
z
|
||||
|
@ -1,94 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** 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.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGui/QtGui>
|
||||
#include <QtGui/qmacnativewidget_mac.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
//![0]
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
NSWindow *window = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, app.desktop()->height() - 200, 239, 200)
|
||||
styleMask:NSTitledWindowMask | NSClosableWindowMask
|
||||
| NSMiniaturizableWindowMask | NSResizableWindowMask
|
||||
backing:NSBackingStoreBuffered defer:NO];
|
||||
|
||||
QMacNativeWidget *nativeWidget = new QMacNativeWidget();
|
||||
nativeWidget->move(0, 0);
|
||||
nativeWidget->setPalette(QPalette(Qt::red));
|
||||
nativeWidget->setAutoFillBackground(true);
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
QPushButton *pushButton = new QPushButton("An Embedded Qt Button!", nativeWidget);
|
||||
pushButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // Don't use the layout rect calculated from QMacStyle.
|
||||
layout->addWidget(pushButton);
|
||||
nativeWidget->setLayout(layout);
|
||||
|
||||
// Adjust Cocoa layouts
|
||||
NSView *nativeWidgetView = reinterpret_cast<NSView *>(nativeWidget->winId());
|
||||
NSView *contentView = [window contentView];
|
||||
[contentView setAutoresizesSubviews:YES];
|
||||
[nativeWidgetView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
|
||||
[nativeWidgetView setAutoresizesSubviews:YES];
|
||||
NSView *pushButtonView = reinterpret_cast<NSView *>(pushButton->winId());
|
||||
[pushButtonView setAutoresizingMask:NSViewWidthSizable];
|
||||
|
||||
// Add the nativeWidget to the window.
|
||||
[contentView addSubview:nativeWidgetView positioned:NSWindowAbove relativeTo:nil];
|
||||
nativeWidget->show();
|
||||
pushButton->show();
|
||||
|
||||
// Show the window.
|
||||
[window makeKeyAndOrderFront:window];
|
||||
[pool release];
|
||||
//![0]
|
||||
return app.exec(); // gives us the same behavior in both
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QCOCOAVIEWCONTAINER_H
|
||||
#define QCOCOAVIEWCONTAINER_H
|
||||
|
||||
#include <QtWidgets/qtwidgetsglobal.h>
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(NSView);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
class QMacCocoaViewContainerPrivate;
|
||||
class QT_DEPRECATED_X("Use QWindow::fromWinId and QWidget::createWindowContainer instead")
|
||||
Q_WIDGETS_EXPORT QMacCocoaViewContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent = nullptr);
|
||||
virtual ~QMacCocoaViewContainer();
|
||||
|
||||
void setCocoaView(NSView *view);
|
||||
NSView *cocoaView() const;
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QMacCocoaViewContainer)
|
||||
};
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QCOCOAVIEWCONTAINER_H
|
@ -1,199 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#include "qmaccocoaviewcontainer_mac.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtGui/QWindow>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
#include <private/qwidget_p.h>
|
||||
#include <private/qwindow_p.h>
|
||||
|
||||
/*!
|
||||
\class QMacCocoaViewContainer
|
||||
\since 4.5
|
||||
|
||||
\brief The QMacCocoaViewContainer class provides a widget for \macos that can be used to wrap arbitrary
|
||||
Cocoa views (i.e., NSView subclasses) and insert them into Qt hierarchies.
|
||||
|
||||
\ingroup advanced
|
||||
\inmodule QtWidgets
|
||||
|
||||
While Qt offers a lot of classes for writing your application, Apple's
|
||||
Cocoa frameworks offer functionality that is not currently available (or
|
||||
may never end up) in Qt. Using QMacCocoaViewContainer, it is possible to take an
|
||||
arbitrary NSView-derived class from Cocoa and put it in a Qt widgets hierarchy.
|
||||
Depending on the level of integration you need, you can use QMacCocoaViewContainer
|
||||
directly or subclass it to wrap more functionality of the underlying NSView.
|
||||
|
||||
It should be also noted that, at the Cocoa level, there is a difference
|
||||
between top-level windows and views (widgets that are inside a window).
|
||||
For this reason, make sure that the NSView that you are wrapping doesn't
|
||||
end up as a top-level window. The best way to ensure this is to make sure
|
||||
QMacCocoaViewContainer's parent widget is not null.
|
||||
|
||||
If you are using QMacCocoaViewContainer as a subclass and are accessing Cocoa API,
|
||||
it is probably simpler to have your file end with \tt{.mm} instead of \tt{.cpp}.
|
||||
Most Apple tools will correctly identify the source as Objective-C++.
|
||||
|
||||
QMacCocoaViewContainer requires knowledge of how Cocoa works, especially in
|
||||
regard to its reference counting (retain/release) nature. It is noted in
|
||||
the functions below if there is any change in the reference count. Cocoa
|
||||
views often generate temporary objects that are released by an autorelease
|
||||
pool. If this is done outside of a running event loop, it is up to the
|
||||
developer to provide the autorelease pool.
|
||||
|
||||
The following is a snippet showing how to subclass QMacCocoaViewContainer
|
||||
to wrap an NSSearchField.
|
||||
|
||||
\code
|
||||
SearchWidget::SearchWidget(QWidget *parent)
|
||||
: QMacCocoaViewContainer(0, parent)
|
||||
{
|
||||
// Many Cocoa objects create temporary autorelease objects,
|
||||
// so create a pool to catch them.
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Create the NSSearchField, set it on the QCocoaViewContainer.
|
||||
NSSearchField *search = [[NSSearchField alloc] init];
|
||||
setCocoaView(search);
|
||||
|
||||
// Use a Qt menu for the search field menu.
|
||||
QMenu *qtMenu = createMenu(this);
|
||||
NSMenu *nsMenu = qtMenu->macMenu(0);
|
||||
[[search cell] setSearchMenuTemplate:nsMenu];
|
||||
|
||||
// Release our reference, since our super class takes ownership and we
|
||||
// don't need it anymore.
|
||||
[search release];
|
||||
|
||||
// Clean up our pool as we no longer need it.
|
||||
[pool release];
|
||||
}
|
||||
\endcode
|
||||
*/
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QMacCocoaViewContainerPrivate : public QWidgetPrivate
|
||||
{
|
||||
QT_IGNORE_DEPRECATIONS(Q_DECLARE_PUBLIC(QMacCocoaViewContainer))
|
||||
public:
|
||||
NSView *nsview;
|
||||
QMacCocoaViewContainerPrivate();
|
||||
~QMacCocoaViewContainerPrivate();
|
||||
};
|
||||
|
||||
QMacCocoaViewContainerPrivate::QMacCocoaViewContainerPrivate()
|
||||
: nsview(0)
|
||||
{
|
||||
}
|
||||
|
||||
QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate()
|
||||
{
|
||||
[nsview release];
|
||||
}
|
||||
|
||||
/*!
|
||||
Create a new QMacCocoaViewContainer using the NSView pointer in
|
||||
the \a view with parent, \a parent. QMacCocoaViewContainer will
|
||||
retain the \a view.
|
||||
|
||||
*/
|
||||
QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *view, QWidget *parent)
|
||||
: QWidget(*new QMacCocoaViewContainerPrivate, parent, {})
|
||||
{
|
||||
// Ensures that we have a QWindow, even if we're not a top level widget
|
||||
setAttribute(Qt::WA_NativeWindow);
|
||||
|
||||
setCocoaView(view);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroy the QMacCocoaViewContainer and release the wrapped view.
|
||||
*/
|
||||
QMacCocoaViewContainer::~QMacCocoaViewContainer()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the NSView that has been set on this container.
|
||||
*/
|
||||
NSView *QMacCocoaViewContainer::cocoaView() const
|
||||
{
|
||||
Q_D(const QMacCocoaViewContainer);
|
||||
return d->nsview;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets \a view as the NSView to contain and retains it. If this
|
||||
container already had a view set, it will release the previously set view.
|
||||
*/
|
||||
void QMacCocoaViewContainer::setCocoaView(NSView *view)
|
||||
{
|
||||
Q_D(QMacCocoaViewContainer);
|
||||
NSView *oldView = d->nsview;
|
||||
[view retain];
|
||||
d->nsview = view;
|
||||
|
||||
// Get rid of QWindow completely, and re-create a new vanilla one, which
|
||||
// we will then re-configure to be a foreign window.
|
||||
destroy();
|
||||
create();
|
||||
|
||||
// Can't use QWindow::fromWinId() here due to QWidget controlling its
|
||||
// QWindow, and can't use QWidget::createWindowContainer() due to the
|
||||
// QMacCocoaViewContainer class being public API instead of a factory
|
||||
// function.
|
||||
QWindow *window = windowHandle();
|
||||
window->destroy();
|
||||
qt_window_private(window)->create(false, WId(view));
|
||||
Q_ASSERT(window->handle());
|
||||
|
||||
[oldView release];
|
||||
|
||||
// The QWindow::destroy()) call above will explicitly hide this widget.
|
||||
// Clear the hidden state here so it can be implicitly shown again.
|
||||
setAttribute(Qt::WA_WState_Hidden, false);
|
||||
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -1,69 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QMACNATIVEWIDGET_H
|
||||
#define QMACNATIVEWIDGET_H
|
||||
|
||||
#include <QtWidgets/qtwidgetsglobal.h>
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(NSView);
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 15)
|
||||
class QT_DEPRECATED_X("Use QWidget::winId instead")
|
||||
Q_WIDGETS_EXPORT QMacNativeWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QMacNativeWidget(NSView *parentView = nullptr);
|
||||
~QMacNativeWidget();
|
||||
|
||||
QSize sizeHint() const override;
|
||||
NSView *nativeView() const;
|
||||
|
||||
protected:
|
||||
bool event(QEvent *ev) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QMACNATIVEWIDGET_H
|
@ -1,166 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
#include "qmacnativewidget_mac.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtGui/qwindow.h>
|
||||
#include <QtGui/qguiapplication.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
/*!
|
||||
\class QMacNativeWidget
|
||||
\since 4.5
|
||||
\brief The QMacNativeWidget class provides a widget for \macos that provides
|
||||
a way to put Qt widgets into Cocoa hierarchies.
|
||||
|
||||
\ingroup advanced
|
||||
\inmodule QtWidgets
|
||||
|
||||
On \macos, there is a difference between a window and view;
|
||||
normally expressed as widgets in Qt. Qt makes assumptions about its
|
||||
parent-child hierarchy that make it complex to put an arbitrary Qt widget
|
||||
into a hierarchy of "normal" views from Apple frameworks. QMacNativeWidget
|
||||
bridges the gap between views and windows and makes it possible to put a
|
||||
hierarchy of Qt widgets into a non-Qt window or view.
|
||||
|
||||
QMacNativeWidget pretends it is a window (i.e. isWindow() will return true),
|
||||
but it cannot be shown on its own. It needs to be put into a window
|
||||
when it is created or later through a native call.
|
||||
|
||||
Here is an example showing how to put a QPushButton into a NSWindow:
|
||||
|
||||
\snippet qmacnativewidget/main.mm 0
|
||||
|
||||
Note that QMacNativeWidget requires knowledge of Cocoa. All it
|
||||
does is get the Qt hierarchy into a window not owned by Qt. It is then up
|
||||
to the programmer to ensure it is placed correctly in the window and
|
||||
responds correctly to events.
|
||||
*/
|
||||
|
||||
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 (Q_UNLIKELY(!function))
|
||||
qWarning("Qt could not resolve function %s from "
|
||||
"QGuiApplication::platformNativeInterface()->nativeResourceFunctionForIntegration()",
|
||||
functionName.constData());
|
||||
return function;
|
||||
}
|
||||
} //namespsace
|
||||
|
||||
NSView *getEmbeddableView(QWindow *qtWindow)
|
||||
{
|
||||
// Make sure the platform window is created
|
||||
qtWindow->create();
|
||||
|
||||
// Inform the window that it's a subwindow of a non-Qt window. This must be
|
||||
// done after create() because we need to have a QPlatformWindow instance.
|
||||
// The corresponding NSWindow will not be shown and can be deleted later.
|
||||
typedef void (*SetEmbeddedInForeignViewFunction)(QPlatformWindow *window, bool embedded);
|
||||
reinterpret_cast<SetEmbeddedInForeignViewFunction>(resolvePlatformFunction("setEmbeddedInForeignView"))(qtWindow->handle(), true);
|
||||
|
||||
// Get the Qt content NSView for the QWindow from the Qt platform plugin
|
||||
QPlatformNativeInterface *platformNativeInterface = QGuiApplication::platformNativeInterface();
|
||||
NSView *qtView = (NSView *)platformNativeInterface->nativeResourceForWindow("nsview", qtWindow);
|
||||
return qtView; // qtView is ready for use.
|
||||
}
|
||||
|
||||
/*!
|
||||
Create a QMacNativeWidget with \a parentView as its "superview" (i.e.,
|
||||
parent). The \a parentView is a NSView pointer.
|
||||
*/
|
||||
QMacNativeWidget::QMacNativeWidget(NSView *parentView)
|
||||
: QWidget(0)
|
||||
{
|
||||
Q_UNUSED(parentView);
|
||||
|
||||
//d_func()->topData()->embedded = true;
|
||||
setPalette(QPalette(Qt::transparent));
|
||||
setAttribute(Qt::WA_SetPalette, false);
|
||||
setAttribute(Qt::WA_LayoutUsesWidgetRect);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setAttribute(Qt::WA_NoSystemBackground, false);
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroy the QMacNativeWidget.
|
||||
*/
|
||||
QMacNativeWidget::~QMacNativeWidget()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QSize QMacNativeWidget::sizeHint() const
|
||||
{
|
||||
// QMacNativeWidget really does not have any other choice
|
||||
// than to fill its designated area.
|
||||
if (windowHandle())
|
||||
return windowHandle()->size();
|
||||
return QWidget::sizeHint();
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the native view backing the QMacNativeWidget.
|
||||
|
||||
*/
|
||||
NSView *QMacNativeWidget::nativeView() const
|
||||
{
|
||||
winId();
|
||||
return getEmbeddableView(windowHandle());
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QMacNativeWidget::event(QEvent *ev)
|
||||
{
|
||||
return QWidget::event(ev);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
@ -50,9 +50,6 @@
|
||||
#include "qlayout.h"
|
||||
#include "qpainter.h"
|
||||
#include <qpa/qplatformtheme.h>
|
||||
#ifdef Q_OS_MACOS
|
||||
#include "qmacnativewidget_mac.h"
|
||||
#endif
|
||||
#include "qapplication.h"
|
||||
#ifndef QT_NO_ACCESSIBILITY
|
||||
# include "qaccessible.h"
|
||||
@ -3592,8 +3589,8 @@ void QMenu::actionEvent(QActionEvent *e)
|
||||
if (QWidget *widget = d->widgetItems.value(wa)) {
|
||||
#ifdef Q_OS_MACOS
|
||||
QWidget *p = widget->parentWidget();
|
||||
if (p != this && QT_IGNORE_DEPRECATIONS(qobject_cast<QMacNativeWidget *>(p))) {
|
||||
// This widget was reparented into a native Mac view
|
||||
if (p != this) {
|
||||
// This widget was reparented into a container widget
|
||||
// (see QMenuPrivate::moveWidgetToPlatformItem).
|
||||
// Reset the parent and delete the native widget.
|
||||
widget->setParent(this);
|
||||
|
@ -49,7 +49,6 @@ QT_USE_NAMESPACE
|
||||
#include "qmenubar.h"
|
||||
#include "qmenubar_p.h"
|
||||
#endif
|
||||
#include "qmacnativewidget_mac.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtGui/QGuiApplication>
|
||||
@ -125,13 +124,14 @@ void QMenu::setAsDockMenu()
|
||||
|
||||
void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* item)
|
||||
{
|
||||
auto *container = new QT_IGNORE_DEPRECATIONS(QMacNativeWidget);
|
||||
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 = container->nativeView();
|
||||
NSView *containerView = reinterpret_cast<NSView*>(container->winId());
|
||||
QWindow *containerWindow = container->windowHandle();
|
||||
Qt::WindowFlags wf = containerWindow->flags();
|
||||
containerWindow->setFlags(wf | Qt::SubWindow);
|
||||
|
@ -357,14 +357,6 @@ qtConfig(widgettextcontrol) {
|
||||
}
|
||||
|
||||
macx {
|
||||
HEADERS += \
|
||||
widgets/qmacnativewidget_mac.h \
|
||||
widgets/qmaccocoaviewcontainer_mac.h
|
||||
|
||||
OBJECTIVE_SOURCES += \
|
||||
widgets/qmacnativewidget_mac.mm \
|
||||
widgets/qmaccocoaviewcontainer_mac.mm
|
||||
|
||||
qtConfig(menu)|qtConfig(menubar) {
|
||||
SOURCES += widgets/qmenu_mac.mm
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
# Generated from qmaccocoaviewcontainer.pro.
|
||||
|
||||
#####################################################################
|
||||
## qmaccocoaviewcontainer Binary:
|
||||
#####################################################################
|
||||
|
||||
qt_add_manual_test(qmaccocoaviewcontainer
|
||||
GUI
|
||||
SOURCES
|
||||
TestMouseMovedNSView.h TestMouseMovedNSView.m
|
||||
main.mm
|
||||
INCLUDE_DIRECTORIES
|
||||
.
|
||||
PUBLIC_LIBRARIES
|
||||
${FWAppKit}
|
||||
Qt::Gui
|
||||
Qt::Widgets
|
||||
)
|
||||
|
||||
#### Keys ignored in scope 1:.:.:qmaccocoaviewcontainer.pro:<TRUE>:
|
||||
# TEMPLATE = "app"
|
@ -1,32 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** 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 General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** 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-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
@interface TestMouseMovedNSView : NSView
|
||||
@end
|
@ -1,112 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** 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 General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** 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-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#import "TestMouseMovedNSView.h"
|
||||
|
||||
@implementation TestMouseMovedNSView {
|
||||
NSPoint mouseMovedPoint_;
|
||||
BOOL wasAcceptingMouseEvents_;
|
||||
NSTrackingRectTag trackingRect_;
|
||||
NSTrackingArea* trackingArea_;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self)
|
||||
mouseMovedPoint_ = NSMakePoint(50, 50);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
trackingArea_ = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
|
||||
[self addTrackingArea:trackingArea_];
|
||||
}
|
||||
|
||||
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
|
||||
{
|
||||
if (self.window && trackingArea_)
|
||||
[self removeTrackingArea:trackingArea_];
|
||||
}
|
||||
|
||||
- (void)updateTrackingAreas
|
||||
{
|
||||
[super updateTrackingAreas];
|
||||
[self removeTrackingArea: trackingArea_];
|
||||
trackingArea_ = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil];
|
||||
[self addTrackingArea:trackingArea_];
|
||||
}
|
||||
|
||||
- (BOOL)acceptsFirstResponder { return YES; }
|
||||
- (BOOL)becomeFirstResponder { return YES; }
|
||||
|
||||
- (void)mouseEntered:(NSEvent *)theEvent
|
||||
{
|
||||
wasAcceptingMouseEvents_ = [[self window] acceptsMouseMovedEvents];
|
||||
[self.window setAcceptsMouseMovedEvents:YES];
|
||||
[self.window makeFirstResponder:self];
|
||||
}
|
||||
|
||||
- (void)mouseExited:(NSEvent *)theEvent
|
||||
{
|
||||
[self.window setAcceptsMouseMovedEvents:wasAcceptingMouseEvents_];
|
||||
[self setNeedsDisplay:YES];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
|
||||
-(void)mouseMoved:(NSEvent *)pTheEvent
|
||||
{
|
||||
mouseMovedPoint_ = [self convertPoint:pTheEvent.locationInWindow fromView:nil];
|
||||
[self setNeedsDisplay:YES];
|
||||
[self displayIfNeeded];
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
[[NSColor whiteColor] set];
|
||||
NSRectFill(dirtyRect);
|
||||
|
||||
NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext];
|
||||
CGContextRef cgContextRef = nsGraphicsContext.CGContext;
|
||||
|
||||
CGContextSetRGBStrokeColor(cgContextRef, 0, 0, 0, .5);
|
||||
CGContextSetLineWidth(cgContextRef, 1.0);
|
||||
|
||||
CGContextBeginPath(cgContextRef);
|
||||
|
||||
CGContextMoveToPoint(cgContextRef, mouseMovedPoint_.x, 0);
|
||||
CGContextAddLineToPoint(cgContextRef, mouseMovedPoint_.x, 1000);
|
||||
|
||||
CGContextMoveToPoint(cgContextRef, 0, mouseMovedPoint_.y);
|
||||
CGContextAddLineToPoint(cgContextRef, 1000, mouseMovedPoint_.y);
|
||||
|
||||
CGContextDrawPath(cgContextRef, kCGPathStroke);
|
||||
}
|
||||
|
||||
@end
|
@ -1,96 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** 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 General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** 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-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#import "TestMouseMovedNSView.h"
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
#include <QMacCocoaViewContainer>
|
||||
|
||||
class MyWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyWidget(QMacCocoaViewContainer *c, QWidget *parent = 0) : QWidget(parent), container(c), currentlyVisible(true)
|
||||
{
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
QLabel *label = new QLabel("1: Check that the cross hairs move when the mouse is moved over the widget\n"
|
||||
"2: Check that clicking on change visibility causes the NSView to hide/show as appropriate\n"
|
||||
"3: Check that clicking on resize makes the view be 200x200");
|
||||
vbox->addWidget(label);
|
||||
QPushButton *button = new QPushButton("Change visibility");
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(changeVisibility()));
|
||||
vbox->addWidget(button);
|
||||
button = new QPushButton("Change size");
|
||||
connect(button, SIGNAL(clicked()), this, SLOT(changeSize()));
|
||||
vbox->addWidget(button);
|
||||
setLayout(vbox);
|
||||
}
|
||||
public slots:
|
||||
void changeVisibility()
|
||||
{
|
||||
currentlyVisible = !currentlyVisible;
|
||||
if (!currentlyVisible)
|
||||
container->hide();
|
||||
else
|
||||
container->show();
|
||||
bool b = !([(NSView *)container->cocoaView() isHidden]);
|
||||
QMessageBox::information(this, "Is visible", QString("NSView visibility: %1").arg(b));
|
||||
}
|
||||
void changeSize()
|
||||
{
|
||||
NSRect r = NSMakeRect(0, 0, 200, 200);
|
||||
[(NSView *)container->cocoaView() setFrame:r];
|
||||
}
|
||||
private:
|
||||
QMacCocoaViewContainer *container;
|
||||
bool currentlyVisible;
|
||||
};
|
||||
|
||||
#include "main.moc"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
QPoint pos(100,100);
|
||||
QWidget w;
|
||||
w.move(pos);
|
||||
w.resize(300, 300);
|
||||
w.setWindowTitle("QMacCocoaViewContainer");
|
||||
NSRect r = NSMakeRect(0, 0, 100, 100);
|
||||
NSView *view = [[TestMouseMovedNSView alloc] initWithFrame:r];
|
||||
QMacCocoaViewContainer *nativeChild = new QMacCocoaViewContainer(view, &w);
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(nativeChild);
|
||||
w.setLayout(vbox);
|
||||
w.show();
|
||||
MyWidget w2(nativeChild);
|
||||
w2.show();
|
||||
return a.exec();
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
TEMPLATE = app
|
||||
TARGET = qmaccocoaviewcontainer
|
||||
INCLUDEPATH += .
|
||||
QT += widgets
|
||||
LIBS += -framework AppKit
|
||||
# Input
|
||||
OBJECTIVE_SOURCES += main.mm TestMouseMovedNSView.m
|
||||
HEADERS += TestMouseMovedNSView.h
|
Loading…
Reference in New Issue
Block a user