Don't use the SubWindow flag for windows embedded in foreign windows

Instead, add QCocoaWindow::setEmbeddedInForeignView which can be called
via QPlatformNativeInterface::NativeResourceForIntegrationFunction

Task-number: QTBUG-30805
Change-Id: I05861e80ca664ddb430216388cf0fec573a4d32b
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
Shawn Rutledge 2013-04-24 10:59:45 +02:00 committed by The Qt Project
parent 2e69015d74
commit 9f1b64766b
5 changed files with 30 additions and 7 deletions

View File

@ -115,6 +115,9 @@ private:
// Embedding NSViews as child QWindows // Embedding NSViews as child QWindows
static void setWindowContentView(QPlatformWindow *window, void *nsViewContentView); 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);
// Register if a window should deliver touch events. Enabling // Register if a window should deliver touch events. Enabling
// touch events has implications for delivery of other events, // touch events has implications for delivery of other events,
// for example by causing scrolling event lag. // for example by causing scrolling event lag.

View File

@ -120,6 +120,8 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView); return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setWindowContentView);
if (resource.toLower() == "registertouchwindow") if (resource.toLower() == "registertouchwindow")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow); return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerTouchWindow);
if (resource.toLower() == "setembeddedinforeignview")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setEmbeddedInForeignView);
return 0; return 0;
} }
@ -229,6 +231,12 @@ void QCocoaNativeInterface::setWindowContentView(QPlatformWindow *window, void *
cocoaPlatformWindow->setContentView(reinterpret_cast<NSView *>(contentView)); cocoaPlatformWindow->setContentView(reinterpret_cast<NSView *>(contentView));
} }
void QCocoaNativeInterface::setEmbeddedInForeignView(QPlatformWindow *window, bool embedded)
{
QCocoaWindow *cocoaPlatformWindow = static_cast<QCocoaWindow *>(window);
cocoaPlatformWindow->setEmbeddedInForeignView(embedded);
}
void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable) void QCocoaNativeInterface::registerTouchWindow(QWindow *window, bool enable)
{ {
if (!window) if (!window)

View File

@ -127,6 +127,8 @@ public:
NSView *contentView() const; NSView *contentView() const;
void setContentView(NSView *contentView); void setContentView(NSView *contentView);
void setEmbeddedInForeignView(bool subwindow);
void windowWillMove(); void windowWillMove();
void windowDidMove(); void windowDidMove();
void windowDidResize(); void windowDidResize();
@ -175,7 +177,10 @@ public: // for QNSView
NSView *m_contentView; NSView *m_contentView;
QNSView *m_qtView; QNSView *m_qtView;
NSWindow *m_nsWindow; NSWindow *m_nsWindow;
bool m_contentViewIsEmbedded; // true if the m_contentView is embedded in a "foregin" NSView hiearchy
// TODO merge to one variable if possible
bool m_contentViewIsEmbedded; // true if the m_contentView is actually embedded in a "foreign" NSView hiearchy
bool m_contentViewIsToBeEmbedded; // true if the m_contentView is intended to be embedded in a "foreign" NSView hiearchy
QNSWindowDelegate *m_nsWindowDelegate; QNSWindowDelegate *m_nsWindowDelegate;
Qt::WindowFlags m_windowFlags; Qt::WindowFlags m_windowFlags;

View File

@ -194,6 +194,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw) : QPlatformWindow(tlw)
, m_nsWindow(0) , m_nsWindow(0)
, m_contentViewIsEmbedded(false) , m_contentViewIsEmbedded(false)
, m_contentViewIsToBeEmbedded(false)
, m_nsWindowDelegate(0) , m_nsWindowDelegate(0)
, m_synchedWindowState(Qt::WindowActive) , m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal) , m_windowModality(Qt::NonModal)
@ -654,6 +655,12 @@ void QCocoaWindow::setContentView(NSView *contentView)
recreateWindow(parent()); // Adds the content view to parent NSView recreateWindow(parent()); // Adds the content view to parent NSView
} }
void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
{
m_contentViewIsToBeEmbedded = embedded;
recreateWindow(0); // destroy what was already created
}
void QCocoaWindow::windowWillMove() void QCocoaWindow::windowWillMove()
{ {
// Close any open popups on window move // Close any open popups on window move
@ -715,8 +722,8 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
m_nsWindowDelegate = 0; m_nsWindowDelegate = 0;
} }
if (window()->type() == Qt::SubWindow) { if (m_contentViewIsToBeEmbedded) {
// Subwindows don't have a NSWindow. // An embedded window doesn't have its own NSWindow.
} else if (!parentWindow) { } else if (!parentWindow) {
// Create a new NSWindow if this is a top-level window. // Create a new NSWindow if this is a top-level window.
m_nsWindow = createNSWindow(); m_nsWindow = createNSWindow();

View File

@ -172,7 +172,7 @@ static QTouchDevice *touchDevice = 0;
- (void)viewDidMoveToSuperview - (void)viewDidMoveToSuperview
{ {
if (!(m_window->type() & Qt::SubWindow)) if (!(m_platformWindow->m_contentViewIsToBeEmbedded))
return; return;
if ([self superview]) { if ([self superview]) {
@ -208,7 +208,7 @@ static QTouchDevice *touchDevice = 0;
NSRect rect = [self frame]; NSRect rect = [self frame];
NSRect windowRect = [[self window] frame]; NSRect windowRect = [[self window] frame];
geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height); geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height);
} else if (m_window->type() & Qt::SubWindow) { } else if (m_platformWindow->m_contentViewIsToBeEmbedded) {
// embedded child window, use the frame rect ### merge with case below // embedded child window, use the frame rect ### merge with case below
geometry = qt_mac_toQRect([self bounds]); geometry = qt_mac_toQRect([self bounds]);
} else { } else {
@ -229,9 +229,9 @@ static QTouchDevice *touchDevice = 0;
m_platformWindow->QPlatformWindow::setGeometry(geometry); m_platformWindow->QPlatformWindow::setGeometry(geometry);
// Don't send the geometry change if the QWindow is designated to be // Don't send the geometry change if the QWindow is designated to be
// embedded in a foregin view hiearchy but has not actually been // embedded in a foreign view hiearchy but has not actually been
// embedded yet - it's too early. // embedded yet - it's too early.
if ((m_window->type() & Qt::SubWindow) && !m_platformWindow->m_contentViewIsEmbedded) if (m_platformWindow->m_contentViewIsToBeEmbedded && !m_platformWindow->m_contentViewIsEmbedded)
return; return;
// Send a geometry change event to Qt, if it's ready to handle events // Send a geometry change event to Qt, if it's ready to handle events