Implement QMacCocoaViewContainer in terms of foreign window
This leaves a clearer separation between the foreign-window and non-foreign window use-cases, where a single QCococaWindow can only be in one mode, which is determined in the constructor and doesn't change after that. There are no source or binary compatibility guarantees for the QPA classes, meaning the helper function in QPlatformNativeInterface can be removed. Change-Id: I3232aedca1d98c49a8f54e16750832187f9dc69a Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
parent
087b11e881
commit
89842b97d7
@ -120,9 +120,6 @@ private:
|
||||
static CGImageRef qImageToCGImage(const QImage &image);
|
||||
static QImage cgImageToQImage(CGImageRef image);
|
||||
|
||||
// Embedding NSViews as child QWindows
|
||||
static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView);
|
||||
|
||||
// Set a QWindow as a "guest" (subwindow) of a non-QWindow
|
||||
static void setEmbeddedInForeignView(QPlatformWindow *window, bool embedded);
|
||||
|
||||
|
@ -125,8 +125,6 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
|
||||
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::qImageToCGImage);
|
||||
if (resource.toLower() == "cgimagetoqimage")
|
||||
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::cgImageToQImage);
|
||||
if (resource.toLower() == "setwindowcontentview")
|
||||
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView);
|
||||
if (resource.toLower() == "registertouchwindow")
|
||||
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow);
|
||||
if (resource.toLower() == "setembeddedinforeignview")
|
||||
@ -278,12 +276,6 @@ QImage QCocoaNativeInterface::cgImageToQImage(CGImageRef image)
|
||||
return qt_mac_toQImage(image);
|
||||
}
|
||||
|
||||
void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void *contentView)
|
||||
{
|
||||
QCocoaWindow *cocoaPlatformWindow = static_cast<QCocoaWindow *>(window);
|
||||
cocoaPlatformWindow->setView(reinterpret_cast<NSView *>(contentView));
|
||||
}
|
||||
|
||||
void QCocoaNativeInterface::setEmbeddedInForeignView(QPlatformWindow *window, bool embedded)
|
||||
{
|
||||
QCocoaWindow *cocoaPlatformWindow = static_cast<QCocoaWindow *>(window);
|
||||
|
@ -183,7 +183,6 @@ public:
|
||||
void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE;
|
||||
|
||||
NSView *view() const;
|
||||
void setView(NSView *view);
|
||||
QNSView *qtView() const;
|
||||
NSWindow *nativeWindow() const;
|
||||
|
||||
|
@ -391,8 +391,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
|
||||
QMacAutoReleasePool pool;
|
||||
|
||||
if (tlw->type() == Qt::ForeignWindow) {
|
||||
NSView *foreignView = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>());
|
||||
setView(foreignView);
|
||||
m_view = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>());
|
||||
} else {
|
||||
m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this];
|
||||
m_view = m_qtView;
|
||||
@ -1183,24 +1182,6 @@ NSView *QCocoaWindow::view() const
|
||||
return m_view;
|
||||
}
|
||||
|
||||
// FIXME: Remove and replace with create() and destroy() on a QWindow level
|
||||
void QCocoaWindow::setView(NSView *view)
|
||||
{
|
||||
// Remove and release the previous view
|
||||
if (m_nsWindow)
|
||||
[m_nsWindow setContentView:nil];
|
||||
else
|
||||
[m_view removeFromSuperview];
|
||||
|
||||
[m_view release];
|
||||
|
||||
// Insert and retain the new view
|
||||
[view retain];
|
||||
m_view = view;
|
||||
m_qtView = 0; // The new view is not a QNSView.
|
||||
recreateWindow(QPlatformWindow::parent()); // Adds the view to parent NSView
|
||||
}
|
||||
|
||||
QNSView *QCocoaWindow::qtView() const
|
||||
{
|
||||
return m_qtView;
|
||||
@ -1400,7 +1381,7 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
|
||||
rect.setSize(QSize(1, 1));
|
||||
NSRect frame = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
|
||||
[m_view setFrame:frame];
|
||||
[m_view setHidden:YES];
|
||||
[m_view setHidden:!window()->isVisible()];
|
||||
}
|
||||
|
||||
m_nsWindow.ignoresMouseEvents =
|
||||
|
@ -92,21 +92,6 @@
|
||||
|
||||
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
|
||||
|
||||
class QMacCocoaViewContainerPrivate : public QWidgetPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QMacCocoaViewContainer)
|
||||
@ -137,12 +122,8 @@ QMacCocoaViewContainerPrivate::~QMacCocoaViewContainerPrivate()
|
||||
QMacCocoaViewContainer::QMacCocoaViewContainer(NSView *view, QWidget *parent)
|
||||
: QWidget(*new QMacCocoaViewContainerPrivate, parent, 0)
|
||||
{
|
||||
|
||||
if (view)
|
||||
setCocoaView(view);
|
||||
|
||||
// QMacCocoaViewContainer requires a native window handle.
|
||||
setAttribute(Qt::WA_NativeWindow);
|
||||
setCocoaView(view);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -173,13 +154,23 @@ void QMacCocoaViewContainer::setCocoaView(NSView *view)
|
||||
[view retain];
|
||||
d->nsview = view;
|
||||
|
||||
// Create window and platformwindow
|
||||
winId();
|
||||
QPlatformWindow *platformWindow = this->windowHandle()->handle();
|
||||
QWindow *window = windowHandle();
|
||||
|
||||
// Set the new view as the content view for the window.
|
||||
typedef void (*SetWindowContentViewFunction)(QPlatformWindow *window, NSView *nsview);
|
||||
reinterpret_cast<SetWindowContentViewFunction>(resolvePlatformFunction("setwindowcontentview"))(platformWindow, view);
|
||||
// Note that we only set the flag on the QWindow, and not the QWidget.
|
||||
// These two are not in sync, so from a QWidget standpoint the widget
|
||||
// is not a Window, and hence will be shown when the parent widget is
|
||||
// shown, like all QWidget children.
|
||||
window->setFlags(Qt::ForeignWindow);
|
||||
window->setProperty("_q_foreignWinId", view ? WId(view) : QVariant());
|
||||
|
||||
// Destroying the platform window implies hiding the window, and we
|
||||
// also lose the geometry information that the platform window kept,
|
||||
// and fall back to the stale QWindow geometry, so we update the two
|
||||
// based on the widget visibility and geometry, which is up to date.
|
||||
window->destroy();
|
||||
window->setVisible(isVisible());
|
||||
window->setGeometry(geometry());
|
||||
window->create();
|
||||
|
||||
[oldView release];
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ int main(int argc, char **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];
|
||||
|
Loading…
Reference in New Issue
Block a user