summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Sorvig <morten.sorvig@nokia.com>2011-08-11 11:08:30 +0200
committerRichard Moe Gustavsen <richard.gustavsen@nokia.com>2011-08-11 13:22:36 +0200
commitcbce0088bbb41b14d8ec41874d94e75283876e72 (patch)
treec2b32c37b87ead1b4991a7cbb526fb7cd14b4c72
parent9ff59c4ef435b41721a37dd9236473df51dc2e83 (diff)
Cocoa: Set child window geometry correctly.
Qt child window geometry is in the parent window coordinate space, convert from/to OS X screen coordinates when needed. Change-Id: I50d35dd35e51af8fc161ec363c0e996a0e8aa9f3 Reviewed-on: http://codereview.qt.nokia.com/2859 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@nokia.com>
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm69
2 files changed, 58 insertions, 15 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index dc7907d5ab..e301c48e59 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -45,6 +45,7 @@
#include <Cocoa/Cocoa.h>
#include <QPlatformWindow>
+#include <QRect>
#include "qcocoaglcontext.h"
#include "qnsview.h"
@@ -76,6 +77,9 @@ public:
protected:
void determineWindowClass();
NSWindow *createWindow();
+ NSRect globalGeometry(const QRect localWindowGeometry) const;
+ QRect windowGeometry() const;
+ QCocoaWindow *parentCocoaWindow() const;
private:
friend class QCocoaBackingStore;
NSWindow *m_nsWindow;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 492a43aec4..08a45cba6b 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -46,6 +46,7 @@
#include <QtCore/private/qcore_mac_p.h>
#include <qwindow.h>
#include <QWindowSystemInterface>
+#include <QPlatformScreen>
#include <Cocoa/Cocoa.h>
#include <Carbon/Carbon.h>
@@ -68,8 +69,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
m_contentView = [[QNSView alloc] initWithQWindow:tlw];
if (tlw->surfaceType() == QWindow::OpenGLSurface) {
- const QRect geo = window()->geometry();
- NSRect glFrame = NSMakeRect(0, 0, geo.width(), geo.height());
+ NSRect glFrame = globalGeometry(window()->geometry());
m_windowSurfaceView = [[NSOpenGLView alloc] initWithFrame : glFrame pixelFormat : QCocoaGLContext::createNSOpenGLPixelFormat() ];
[m_contentView setAutoresizesSubviews : YES];
[m_windowSurfaceView setAutoresizingMask : (NSViewWidthSizable | NSViewHeightSizable)];
@@ -90,8 +90,9 @@ void QCocoaWindow::setGeometry(const QRect &rect)
{
QPlatformWindow::setGeometry(rect);
- NSRect bounds = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height());
+ NSRect bounds = globalGeometry(window()->geometry());
[[m_nsWindow contentView]setFrameSize:bounds.size];
+ [m_nsWindow setFrameOrigin : bounds.origin];
if (m_glContext)
m_glContext->update();
@@ -100,6 +101,11 @@ void QCocoaWindow::setGeometry(const QRect &rect)
void QCocoaWindow::setVisible(bool visible)
{
if (visible) {
+ // The parent window might have moved while this window was hidden,
+ // update the window geometry if there is a parent.
+ if (window()->transientParent())
+ setGeometry(window()->geometry());
+
[m_nsWindow makeKeyAndOrderFront:nil];
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
} else {
@@ -265,18 +271,7 @@ NSWindow * QCocoaWindow::createWindow()
wattr |= QtMacCustomizeWindow;
}
*/
- // If we haven't created the desktop widget, you have to pass the rectangle
- // in "cocoa coordinates" (i.e., top points to the lower left coordinate).
- // Otherwise, we do the conversion for you. Since we are the only ones that
- // create the desktop widget, this is OK (but confusing).
-/*
- NSRect geo = NSMakeRect(crect.left(),
- (qt_root_win != 0) ? flipYCoordinate(crect.bottom() + 1) : crect.top(),
- crect.width(), crect.height());
-*/
- QRect geo = window()->geometry();
- NSRect frame = NSMakeRect(geo.x(), geo.y(), geo.width(), geo.height());
-
+ NSRect frame = globalGeometry(window()->geometry());
QCocoaAutoReleasePool pool;
NSWindow *window;
@@ -328,4 +323,48 @@ NSWindow * QCocoaWindow::createWindow()
return window;
}
+// Calculate the global screen geometry for the given local geometry, which
+// might be in the parent window coordinate system.
+NSRect QCocoaWindow::globalGeometry(const QRect localGeometry) const
+{
+ QRect finalGeometry = localGeometry;
+
+ if (QCocoaWindow *parent = parentCocoaWindow()) {
+ QRect parentGeometry = parent->windowGeometry();
+ finalGeometry.adjust(parentGeometry.x(), parentGeometry.y(), parentGeometry.x(), parentGeometry.y());
+
+ // Qt child window geometry assumes that the origin is at the
+ // top-left of the content area of the parent window. The title
+ // bar is not a part of this contet area, but is still included
+ // in the NSWindow height. Move the child window down to acccount
+ // for this if the parent window has a title bar.
+ const int titlebarHeight = 22;
+ if (!(window()->windowFlags() & Qt::FramelessWindowHint))
+ finalGeometry.adjust(0, titlebarHeight, 0, titlebarHeight);
+ }
+
+ // The final "y invert" to get OS X global geometry:
+ QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window());
+ int flippedY = onScreen->geometry().height() - finalGeometry.y() - finalGeometry.height();
+ return NSMakeRect(finalGeometry.x(), flippedY, finalGeometry.width(), finalGeometry.height());
+}
+
+// Returns the current global screen geometry for the nswindow accociated with this window.
+QRect QCocoaWindow::windowGeometry() const
+{
+ NSRect rect = [m_nsWindow frame];
+ QPlatformScreen *onScreen = QPlatformScreen::platformScreenForWindow(window());
+ int flippedY = onScreen->geometry().height() - rect.origin.y - rect.size.height; // account for nswindow inverted y.
+ QRect qRect = QRect(rect.origin.x, flippedY, rect.size.width, rect.size.height);
+ return qRect;
+}
+
+// Returns a pointer to the parent QCocoaWindow for this window, or 0 if there is none.
+QCocoaWindow *QCocoaWindow::parentCocoaWindow() const
+{
+ if (window() && window()->transientParent()) {
+ return static_cast<QCocoaWindow*>(window()->transientParent()->handle());
+ }
+ return 0;
+}